当前位置:   article > 正文

05 MyBatis 动态SQL&&标签_mybatis &&

mybatis &&

目录

前言:

一、动态SQL_<if><where>

二、动态SQL_<set>

三、动态SQL_<choose><when><otherwise>

四、动态SQL_<foreach> 遍历Array数组进行批量删除

五、动态SQL_ <foreach>遍历Collection集合进行批量插入

六、动态SQL_ <foreach>遍历Collection集合进行批量插入


前言:

一个查询的方法的 Sql 语句不一定是固定的。比如电商网站的查询商品,用户使用不同条件查询,Sql 语句就会添加不同的查询条件。此时就需要在方法中使用动态Sql 语句。

一、动态SQL_<if><where>

介绍:

<if> 标签内的 Sql 片段在满足条件后才会添加,用法为: <if test="条件">
<where> 可以代替 sql 中的 where 1=1 和第一个 and ,更符合程序员的开发习惯

1.持久层接口查询方法

  1. //测试MyBatis动态sql语句标签如:<if>、where、set、when、choose、otherwise、foreach
  2. public interface UserMapper2 {
  3. // 1.查询满足条件的所有数据,测试动态SQL的<if>标签
  4. // 用途:测试<if><where>标签
  5. List<User> findByCondition(User user);
  6. }

2.映射文件

  1. <!--注意:这里的resultType、parameterType传入的是别名,在SqlMapConfig.xml中设置了-->
  2. <!--1.查询满足条件的所有数据,测试动态SQL的<if>标签-->
  3. <!--(1)where 1=1 条件是为了满足后面第一条if条件中的and,因为查询中第一个条件可能不符合,
  4. 但不能影响后面的条件,所以把where 1=1作为第一个条件 如:
  5. select * from user where 1=1 <if></if>.....-->
  6. <!-- (2)<where>标签可以代替where 1=1 并且可以省去第一个条件中的and-->
  7. <!--(3)注意:username那里的模糊查询不能用'%${value}%',因为${}是字符串替换,用在普通类型的,而这里的参数类型为POJO类型-->
  8. <select id="findByCondition" resultType="User" parameterType="string">
  9. select * from user
  10. <where>
  11. <if test="username != null and username.length() != 0">
  12. username like #{username}
  13. </if>
  14. <if test="sex != null and sex.length() != 0">
  15. and sex = #{sex}
  16. </if>
  17. <if test="address != null and address.length() != 0">
  18. and address = #{address}
  19. </if>
  20. </where>
  21. </select>

3.测试方法

  1. @Test
  2. public void testFindByCondition(){
  3. User user = new User();
  4. //第一次查询,user对象是一个null对象,所以传入到sql中没有条件,调用where 1=1 查询所有数据
  5. List<User> users1 = userMapper2.findByCondition(user);
  6. users1.forEach(System.out::println);
  7. user.setUsername("%尚学堂%");
  8. //第二次查询,user对象有了”username=尚学堂“的值,传入username的条件并查询满足username=尚学堂的条件
  9. List<User> users2 = userMapper2.findByCondition(user);
  10. users2.forEach(System.out::println);
  11. user.setAddress("北京");
  12. //第三次查询,user对象有了”username=尚学堂、address=北京“的值,传入username、address的条件并查询满足条件的数据
  13. List<User> users3 = userMapper2.findByCondition(user);
  14. users3.forEach(System.out::println);
  15. }

4.注意:

(1)if 中的条件不能使用 &&/|| ,而应该使用 and/or
2
(2)if 中的条件可以直接通过属性名获取参数 POJO 的属性值,并且该值可以调用方法。
3
(3)where 后为什么要加 1=1
         任意条件都可能拼接到Sql 中。如果有多个条件,从第二个条件开始前都需要加And 关键字。加上 1=1 这个永久成立的条件,就不需要考虑后面的条件哪个是第一个条件,后面的条件前都加And 关键字即可。

5.知识点整理:

(1)MyBatis的<if>标签使用“test”属性添加条件
(2)MyBatis的<if>中,多个条件同时满足需要用“and”连接,不能用&&
(3)MyBatis映射文件中,<where>的作用是“代替sql中where 1=1 和第一个and”

二、动态SQL_<set>

介绍:

<set> 标签用在update语句中。借助 <if> ,可以只对有具体值的字段进行更新。 <set> 会自动添加set关键字,并去掉最后一个if语句中多余的逗号。

1.持久层接口更新方法

  1. // 2.动态更新数据,按给定的id主键值进行动态修改数据,可以只更新一行数据中的其中一个字段值,测试动态SQL的<set>标签
  2. // 用途:测试<set>标签
  3. void updateUser(User user);

2.映射文件

  1. <!--2.动态更新数据,可以只更新一行数据中的其中一个字段值,测试动态SQL的<set>标签-->
  2. <!--<set>标签可以代替set(update user (set)<set>...)和最后一个条件后的逗号,
  3. 如果没有<set>标签的话,最后一个if条件中要写上逗号(即address = #{address},)-->
  4. <update id="updateUser" parameterType="User">
  5. update user
  6. <set>
  7. <if test="username != null and username.length() !=0">
  8. username = #{username},
  9. </if>
  10. <if test="sex != null and sex.length() !=0">
  11. sex = #{sex},
  12. </if>
  13. <if test="address != null and address.length() !=0">
  14. address = #{address}
  15. </if>
  16. </set>
  17. <where>
  18. id = #{id}
  19. </where>
  20. </update>

3.测试方法

  1. @Test
  2. public void testUpdateUser(){
  3. User user = new User();
  4. user.setId(2);
  5. user.setUsername("我是程序员");
  6. userMapper2.updateUser(user);
  7. // 增删改操作记得要手动提交事务
  8. session.commit();
  9. }

4.知识点整理:

(1)MyBatis映射文件中,<set>的作用是“代替set关键字,并去掉最后一个if语句中多余的逗号”

三、动态SQL_<choose><when><otherwise>

介绍:

这些标签表示多条件分支,类似 JAVA 中的 switch...case <choose> 类似
switch <when> 类似 case <otherwise> 类似 default ,用法如下:

1.持久层接口查询方法

  1. // 3.查询满足条件的所有数据,测试动态SQL的<choose><when><otherwise>标签
  2. // 按给定的内容进行模糊查询(内容小于5)或精确查询(内容小于10),否则返回id=1的数据(内容大于10)
  3. // 用途:测试<choose><when><otherwise>标签,一般三个连着使用,相当于java中的Switch-case-default
  4. List<User> findByUsername(String username);

2.映射文件

  1. <!--3.查询满足条件的所有数据,测试动态SQL的<choose><when><otherwise>标签-->
  2. <!--<choose><when><otherwise>相当于java的选择条件句,
  3. <choose>相当于Switch
  4. <when> 相当于case
  5. <otherwise> 相当于default-->
  6. <select id="findByUsername" parameterType="string" resultType="User">
  7. select * from user
  8. <where>
  9. <choose>
  10. <when test="username.length() &lt; 5">
  11. <bind name="username" value="'%'+username+'%'"/>
  12. username like #{username}
  13. </when>
  14. <when test="username.length() &lt; 10">
  15. username = #{username}
  16. </when>
  17. <otherwise>
  18. id = 1
  19. </otherwise>
  20. </choose>
  21. </where>
  22. </select>
这段代码的含义为:用户名 <5 时使用模糊查询,用户名 >=5 并且<10时使用精确查询,否则查询 id 1 的用户

3.测试方法

  1. @Test
  2. public void testFindByUsername(){
  3. // 精确查询username属性中含有北京的数据
  4. List<User> user = userMapper2.findByUsername("北京");
  5. user.forEach(System.out::println);
  6. }

4.知识点整理:

1.MyBatis 映射文件中, <choose> 的作用为“表示多条件分支”
2. MyBatis 映射文件中 , <when> 需要被嵌套“ <choose>

四、动态SQL_<foreach> 遍历Array数组进行批量删除

介绍:

<foreach> 类似JAVA中的for循环,可以遍历集合或数组。 <foreach> 有如下属性:

collection :遍历的对象类型
open :表示该语句以什么开始,常用 “(”;
close : 表示以什么结束,常用 “)”。
separator :表示在每次进行迭代之间以什么符号作为分隔符,常用 “,”;
item :表示集合中每一个元素进行迭代时的别名,随便起的变量名,遍历 map 时表示键值对的值。
index :遍历 List 、数组时表示遍历的索引位置,遍历 map 时表示键值对的键。
遍历数组:
我们使用 <foreach> 遍历数组进行批量删除。

1.持久层接口删除方法

  1. // 4.批量删除指定id的一些数据,测试动态SQL的<foreach>标签,遍历Array
  2. // 按给定的id值进行批量删除数据,传入一个数组,数组中包含要删掉的id值
  3. // 系统的删除语句:delete from user where id in(12,13,14,16,17,18)
  4. // 用途:测试<foreach>标签,遍历Array数组
  5. void deleteBatch(int[] ids);

2.映射文件

  1. <!--4.批量删除指定id的一些数据,测试动态SQL的<foreach>标签,遍历Array-->
  2. <!-- collection:遍历的对象类型
  3. open:开始的sql语句
  4. close:结束的sql语句
  5. separator:遍历每项间的分隔符(自定义分隔符形式形式,如逗号、、、)
  6. item(名字自定义):表示本次遍历获取的元素,遍历List、Set、Array时表示每项元素,遍历Map时表示键值对的值
  7. index:遍历List、Array时表示遍历的索引,遍历Map时表示键值对的键-->
  8. <delete id="deleteBatch" parameterType="int">
  9. delete from user
  10. <where>
  11. <foreach collection="array" open="id IN(" close= ")" separator="," item="id">
  12. #{id}
  13. </foreach>
  14. </where>
  15. </delete>

3.测试方法

  1. @Test
  2. public void testDeleteBatch(){
  3. int[] ids = {12,13,14,16,17,18};
  4. userMapper2.deleteBatch(ids);
  5. session.commit();
  6. }

4.知识点整理:

1. MyBatis <foreach> 中,使用属性表示遍历的数据类型" item "
2. MyBatis 映射文件中,遍历数组时需要将 collection 的值设为"array"

五、动态SQL_<foreach> 遍历Collection集合进行批量插入

介绍:

<foreach> 遍历 List Set 的方法是一样的,这里使用 <foreach> 遍历 List集合
行批量添加

1.持久层接口插入方法

  1. // 5.批量插入数据,测试动态SQL的<foreach>标签,遍历Collection
  2. // 系统插入语句:insert into user(username,sex,address) values(),(),()
  3. // 批量新增方法,测试<foreach>标签,遍历Collection集合
  4. void insertBatch(List<User> user);

2.映射文件

  1. <!--5.批量插入数据,测试动态SQL的<foreach>标签,遍历Collection-->
  2. <!--Collection:遍历的对象类型 item:遍历获取的元素(名字自定义,可以调用字段名进行传参) separator:分隔符-->
  3. <insert id="insertBatch" parameterType="User">
  4. insert into user(username,sex,address) values
  5. <foreach collection="list" item="user" separator=",">
  6. (#{user.username},#{user.sex},#{user.adddress})
  7. </foreach>
  8. </insert>

3.测试方法

  1. @Test
  2. public void testInsertBatch(){
  3. User user1 = new User("程序员1","男","深圳");
  4. User user2 = new User("程序员2","女","上海");
  5. List<User> users = new ArrayList();
  6. users.add(user1);
  7. users.add(user2);
  8. // 批量插入
  9. userMapper2.insertBatch(users);
  10. session.commit();
  11. }

4.知识点整理:

(1)在MyBatis中映射文件中,遍历List时<foreach>的item属性表示“遍历的每项元素”

(2)在MyBatis的<foreach>标签中,使用属性遍历每项间的分隔符“separator”

六、动态SQL_<foreach> 遍历Collection集合进行批量插入

介绍:

使用 <foreach>标签 遍历Map进行多条件查询。

1.持久层接口查询方法

  1. // 6.多条件查询:批量查询方法,测试<foreach>标签,遍历Map集合
  2. /**
  3. * 多条件查询:批量查询方法,测试<foreach>标签,遍历Map集合
  4. * @param map 查询的条件键值对 键:属性名 值:出入要查询的属性名
  5. * 系统的查询语句:select * from user where username = ? and sex = ?
  6. * @return
  7. * @Param:为参数起别名
  8. */
  9. List<User> findUser(@Param("queryMap") Map<String,Object> map);

2.映射文件

  1. <!--6.多条件查询:批量查询方法,测试<foreach>标签,遍历Map集合-->
  2. <!--注意:1.collection:传入的不是遍历的对象类型,List、Set、Array传入的类型分别是list、set、array,
  3. 但Map集合传入的不是map,而是持久层接口中定义的参数名 如:@Param("queryMap")
  4. 2.separator:传入的是and不是逗号,因为查询给定的条件是and连接,修改是逗号连接
  5. 3.index:Map类型的键,起名为key item:Map类型的值,起名为value
  6. 4.特别注意:sql语句key=value(键=值),键只能用${},作为字符串拼接到sql语句中,因为键是属性名
  7. 值可以用#{},作为占位符-->
  8. <select id="findUser" parameterType="map" resultType="User">
  9. select * from user
  10. <where>
  11. <foreach collection="queryMap" separator="and" index="key" item="value">
  12. ${key} = #{value}
  13. </foreach>
  14. </where>
  15. </select>

3.测试方法

  1. @Test
  2. public void testFindUser(){
  3. Map<String,Object> queryMap = new HashMap();
  4. queryMap.put("sex","男");
  5. queryMap.put("address","北京");
  6. List<User> users = userMapper2.findUser(queryMap);
  7. users.forEach(System.out::println);
  8. }

4.知识点整理:

(1)MyBatis <foreach> 中,遍历 Map index 属性表示“键值对的键”
(2) MyBatis <foreach> 中,遍历 Map item 属性表示“键值对的值”

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/858261
推荐阅读
相关标签
  

闽ICP备14008679号