08.MyBatis动态sql
- 应用场景
当我们要根据不同的条件,来执行不同的sql语句的时候,需要用到动态sql。
1. 动态 SQL 之 if
-
需求
根据id和username查询,但是不确定两个都有值。 -
UserMapper接口
public List<User> findByIdAndUsernameIf(User user);
-
UserMapper.xml映射
<!-- 动态sql之if : 多条件查询-->
<select id="findByIdAndUsernameIf" parameterType="user" resultType="com.lagou.domain.User">
select * from user
<!-- test里面写的就是表达式
<where>: 相当于where 1= 1,但是如果没有条件的话,不会拼接上where关键字
-->
<where>
<if test="id != null">
and id = #{id}
</if>
<if test="username !=null">
and username = #{username}
</if>
</where>
</select>
2.动态 SQL 之set
需求:动态更新user表数据,如果该属性有值就更新,没有值不做处理。
-
UserMapper接口
void updateIf(User user);
-
UserMapper.xml映射
set: 在更新的时候,会自动添加set关键字,还会去掉最后一个条件的逗号 。
<!--动态sql之set : 动态更新-->
<update id="updateIf" parameterType="user">
update user
<!--<set> : 在更新的时候,会自动添加set关键字,还会去掉最后一个条件的逗号 -->
<set>
<if test="username != null">
username = #{username},
</if>
<if test="birthday != null">
birthday = #{birthday},
</if>
<if test="sex != null">
sex = #{sex},
</if>
<if test="address != null">
address = #{address},
</if>
</set>
where id = #{id}
</update>
3.动态 SQL 之foreach
-
foreach主要是用来做数据的循环遍历
例如: select * from user where id in (1,2,3) 在这样的语句中,传入的参数部分必须依靠
foreach遍历才能实现。 -
foreach标签用于遍历集合,它的属性:
- collection:代表要遍历的集合元素
- open:代表语句的开始部分
- close:代表结束部分
- item:代表遍历集合的每个元素,生成的变量
- sperator:代表分隔符
(1)集合:
UserMapper接口:
List<User> findByList(List<Integer> ids);
UserMaper.xml映射:
<!-- 如果查询条件为普通类型 List集合,collection属性值为:collection 或者 list-->
<select id="findByList" parameterType="list" resultType="user">
select * from `user`
<where>
<foreach collection="collection" open="id in(" close=")" item="id" separator=",">
#{id}
</foreach>
</where>
</select>
测试代码:
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
List<User> byList = userMapper.findByList(list);
for(User user4: byList){
System.out.println(user4);
}
sqlSession.close();
(2)数组
UserMapper接口:
List<User> findByArray(int[] array);
UserMaper.xml映射
<!--
如果查询条件为普通类型 Array数组,collection属性值为:array
-->
<select id="findByArray" parameterType="int" resultType="user">
SELECT * FROM `user`
<where>
<foreach collection="array" open="id in(" close=")" item="id"
separator=",">
#{id}
</foreach>
</where>
</select>
-
测试代码
UserMapper userMapper = sqlSession.getMapper(UserMapper.class); int[] arr = new int[3]; arr[0] = 1; arr[1] = 2; arr[2] = 9; List<User> byArray = userMapper.findByArray(arr); for(User user4: byArray){ System.out.println(user4); } sqlSession.close();
4.SQL片段
应用场景:映射文件中可将重复的sql提取出来,使用时用include引用即可,最终达到sql重用的目的。
//抽取的sql片段
<sql id="selectUser" >
select * from `user`
</sql>
<select id="findByArray" parameterType="list" resultType="user">
<include refid="selectUser"></include>
<where>
<foreach collection="array" open="id in(" close=")" item="id" separator=",">
#{id}
</foreach>
</where>
</select>
5.知识小结
- MyBatis映射文件配置
<select>:查询
<insert>:插入
<update>:修改
<delete>:删除
<selectKey>:返回主键
<where>:where条件
<if>:if判断
<foreach>:for循环
<set>:set设置
<sql>:sql片段抽取