MyBatis进阶:动态SQL、多表查询、分页查询
UserMapper接口上篇提到简单的进行增删改查操作,指路↓
MyBatis 核心入门:从概念到实战,一篇掌握简单增删改查https://blog.csdn.net/weixin_75180926/article/details/150069128?spm=1001.2014.3001.5501
目录
一、动态SQL的核心技术与应用
1.if标签的使用场景
2.choose/when/otherwise标签
3.where标签的智能处理
4.set标签的更新优化
5.foreach标签的批量操作
6.trim标签的灵活控制
二、多表查询的映射策略
1.一对一关联的两种实现
2.一对多关联的集合处理
3.多对多关系的查询
三、分页查询
一、动态SQL的核心技术与应用
1.if标签的使用场景
条件判断动态拼接SQL,适用于非必传参数的查询场景,用于查询多种场景。
<!--if标签--><select id="selectStudentOne">select * from student<if test="stuName!=null">where stu_name=#{stuName}</if></select>
2.choose/when/otherwise标签
多条件分支选择,类似Java的switch-case结构。
<!--choose动态sql的使用语法:省略注意点:1.可以编写多个when与java中的switch相似2.但凡进入任意一个when其余将不再执行3.若所有when都未匹配到则执行otherwise--><select id="selectStudentTwo">select * from student <where><choose><when test="stuName!=null">and stu_name=#{stuName}</when><when test="nickName!=null">and nick_name=#{nickName}</when><otherwise>and stu_sex=#{stuSex}</otherwise></choose></where></select>
3.where标签的智能处理
自动去除多余的AND/OR,避免语法错误。对比原生SQL拼接的缺陷。
<!--where:替代sql语句中的where关键字特点:1.若有条件则生成where关键字2.若无条件则不生成where关键字3.where会自动屏蔽掉多余的and与or关键字--><select id="selectStudentThree" parameterType="com.use.pojo.Student">select * from student<where><if test="stuName!=null">and stu_name=#{stuName}</if><if test="nickName!=null">and nick_name=#{nickName}</if><if test="stuSex!=null">and stu_sex=#{stuSex}</if></where></select>
4.set标签的更新优化
动态生成UPDATE语句,忽略未变更字段。
<!--set标签--><!--set标签:替代sql语句中的set关键字特点:1.若有条件则生成set关键字2.若无条件则不生成set关键字3.set会自动屏蔽掉多余的and与or关键字--><update id="updateStudent" parameterType="com.use.pojo.Student">update student<set><if test="stuName!=null">stu_name=#{stuName}</if><if test="nickName!=null">,nick_name=#{nickName}</if><if test="stuSex!=null">,stu_sex=#{stuSex}</if></set>where stu_id=#{stuId}</update>
5.foreach标签的批量操作
遍历集合生成IN语句或批量插入。可用于List或数组
数组
<!--foreach动态sqlcollection:list array表示遍历集合或者数组item:创建变量用来保存每次遍历的数据open:开始时候拼接的元素,只执行一次close:结束的候拼接的元素,只执行一次separator:每个元素的分隔符号,每次循环完执行;index:下标--><!-- 遍历数组--><select id="selectStudentFive" parameterType="int[]" resultType="com.use.pojo.Student">select * from student where stu_age in<foreach collection="array" open="(" close=")" item="a" separator=",">#{a}</foreach></select>
List
<!-- 遍历list--><select id="selectStudentSix" parameterType="list" resultType="com.use.pojo.Student">select * from student where stu_age in<foreach collection="list" open="(" close=")" item="num" separator=",">#{num}</foreach></select>
6.trim标签的灵活控制
自定义前缀/后缀处理,解决复杂条件拼接问题。
替换where
<!--trim:可以完成where与set的功能语法:<trim prefix = “关键字” suffixOverrides = “后缀” prefixOverrides=“前缀”></trim>注意点:1.prefix,suffix会根据sql语句智能的添加前缀或后缀2.prefixOverrides,suffixOverrides会智能的帮出去除多余的“and or ,”--><select id="findStudentsTrimWhere" parameterType="com.use.pojo.Student" resultType="com.use.pojo.Student">select * from student<trim prefix="where" prefixOverrides="and"><if test="stuName!=null">and stu_name= #{stuName}</if><if test="nickName!=null">and nick_name= #{nickName}</if><if test="stuSex!=null">and stu_sex= #{stuSex}</if></trim></select>
替换set
<update id="updateTrimSet" parameterType="com.use.pojo.Student">update student<trim prefix="set" suffixOverrides=","><if test="stuName!=null">stu_name=#{stuName}</if><if test="nickName!=null">,nick_name=#{nickName}</if><if test="stuSex!=null">,stu_sex=#{stuSex}</if></trim>where stu_id=#{stuId}</update>
二、多表查询的映射策略
1.一对一关联的两种实现
单步查询(一步到位,只用一条sql语句)
AccoutMapper接口
public interface AccountMapper {public List<Account> selectAccountAll();}
AccountMapper.xml
<resultMap id="map2" type="com.my.pojo.Account"><id column="account_id" property="accountId"></id><result column="account_uid" property="accountUid"></result><result column="account_money" property="accountMoney"></result><!--一对一关联--><association property="user" javaType="com.my.pojo.User"><id column="user_id" property="userId"></id><result column="user_name" property="userName"></result><result column="user_sex" property="userSex"></result><result column="user_birthday" property="userBirthday"></result><result column="user_address" property="userAddress"></result></association></resultMap><!--一对一查询(单步查询)--><select id="selectAccountAll" resultMap="map2">select * from user left join account a on user.user_id = a.account_uid;</select>
分布查询(将上一个select语句查询的结果的某个字段值当做下一个select语句的查询条件)
AccoutMapper接口
public interface AccountMapper {public List<Account> selectAccountAll();public Account selectAccountById(int id);}
AccountMapper.xml
<resultMap id="map3" type="com.my.pojo.Account"><id column="account_id" property="accountId"></id><result column="account_uid" property="accountUid"></result><result column="account_money" property="accountMoney"></result><association property="user" javaType="com.my.pojo.User" column="account_uid" select="com.my.mapper.UserMapper.selectUserById"></association></resultMap><!--一对一(分步查询)--><select id="selectAccountById" parameterType="int" resultMap="map3">select * from account where account_id=#{id}</select>
UserMapper接口
public interface UserMapper {public User selectUserById(int id);
}
UserMapper.xml
<!--一对一分步查询--><select id="selectUserById" parameterType="int" resultType="com.my.pojo.User">select * from user where user_id=#{id}</select>
2.一对多关联的集合处理
单步查询
UserMapper接口
public interface UserMapper {public List<User> selectUserAll();
}
UserMapper.xml
<resultMap id="map1" type="com.my.pojo.User"><id column="user_id" property="userId"></id><result column="username" property="userName"></result><result column="user_birthday" property="userBirthday"></result><result column="user_sex" property="userSex"></result><result column="user_address" property="userAddress"></result><!--一对多关联--><collection property="accounts" ofType="com.my.pojo.Account"><id column="account_id" property="accountId"></id><result column="account_uid" property="accountUid"></result><result column="account_money" property="accountMoney"></result></collection></resultMap><!--一对多查询(单步查询)--><select id="selectUserAll" resultMap="map1">select * from user u,account a where u.user_id=a.account_uid;</select>
分步查询
UserMapper接口
public interface UserMapper {public User selectUserByName(String name);
}
UserMapper.xml
<resultMap id="map4" type="com.my.pojo.User"><id column="user_id" property="userId"></id><result column="user_name" property="userName"></result><result column="user_birthday" property="userBirthday"></result><result column="user_sex" property="userSex"></result><result column="user_address" property="userAddress"></result><collection property="accounts" ofType="com.my.pojo.Account" column="user_id" select="com.my.mapper.AccountMapper.selectAccountByUid"></collection></resultMap><!--一对多分布查询--><select id="selectUserByName" parameterType="java.lang.String" resultMap="map4">select * from user where user_name=#{name}</select>
AccountMapper.xml
<!--一对多分步查询--><select id="selectAccountByUid" parameterType="int" resultType="com.my.pojo.Account">select * from account where account_uid=#{uid}</select>
AccountMapper接口
public interface AccountMapper {public Account selectAccountByUid(int uid);
}
3.多对多关系的查询
多对多查询就是双向的一对多查询,这里就不列举了。
三、分页查询
分页查询是一种将大量数据分成多个小部分(页)进行查询的技术,用于避免一次性加载全部数据导致的性能问题和内存消耗过大。
<select id="findUsers" resultType="User">SELECT * FROM user LIMIT #{offset}, #{pageSize}
</select>
进行查询时传入参数offset和pageSize就行,其中offset是起始位置(计算公式:(页码 - 1)* 每页条数),pageSize是每页显示的记录数