文章目录

  • 一、if判断
    • mapper.xml
    • 测试结果
  • 二、sql片段(重点)
    • 2.1 定义sql片段
    • 2.2引用sql片段
  • 三、foreach标签
  • 四、 Choose(when , otherwise )

# 动态sql

标签: mybatis


Contents

  • if判断
  • sql片段(重点)
  • foreach标签

什么是动态sql?:

mybatis核心,对sql语句进行灵活操作,通过表达式对sql进行判断,对sql进行灵活拼接、组装。

一、if判断

mapper.xml

<!-- 用户信息综合查询#{userCustom.sex}:取出pojo包装对象中性别值${userCustom.username}:取出pojo包装对象中用户名称-->
<select id="findUserList" parameterType="com.iot.mybatis.po.UserQueryVo"resultType="com.iot.mybatis.po.UserCustom">SELECT * FROM user<where><!--  where 可以自动去掉条件中的第一个and --><if test="userCustom!=null"><!--类.属性不为空--><if test="userCustom.sex!=null and userCustom.sex != '' "><!--类.属性.属性不为空-->AND user.sex=#{userCustom.sex}</if><if test="userCustom.username!=null and userCustom.username != '' ">AND user.username LIKE '%${userCustom.username}%'</if></if></where>
</select><!-- 用户信息综合查询总数parameterType:指定输入类型和findUserList一样resultType:输出结果类型
-->
<select id="findUserCount" parameterType="com.iot.mybatis.po.UserQueryVo" resultType="int">SELECT count(*) FROM user<where><if test="userCustom!=null"><if test="userCustom.sex!=null and userCustom.sex != '' ">AND user.sex=#{userCustom.sex}</if><if test="userCustom.username!=null and userCustom.username != '' ">AND user.username LIKE '%${userCustom.username}%'</if></if></where>
</select>

测试结果

1.注释掉testFindUserList()方法中的userCustom.setUsername("张三");

public class UserMapperTest {  @Before  public void setup() throws Exception{  ...}@Testpublic void testFindUserList() throws Exception {SqlSession sqlSession = sqlSessionFactory.openSession();//创建UserMapper对象,mybatis自动生成mapper代理对象UserMapper userMapper  sqlSession.getMapper(UserMapper.class);//创建包装对象,设置查询条件UserQueryVo userQueryVo = new UserQueryVo();UserCustom userCustom = new UserCustom();//由于这里使用动态sql,如果不设置某个值,条件不会拼接在sql中userCustom.setSex("1");//userCustom.setUsername("张三");userQueryVo.setUserCustom(userCustom);List<UserCustom> list = userMapper.findUserList(userQueryVo);System.out.println(list);}
}

输出

DEBUG [main] - Checking to see if class com.iot.mybatis.mapper.UserMapper matches criteria [is assignable to Object]
DEBUG [main] - Checking to see if class com.iot.mybatis.mapper.UserMapperTest matches criteria [is assignable to Object]
DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Created connection 352359770.
DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@1500955a]
DEBUG [main] - ==>  Preparing: SELECT * FROM user WHERE user.sex=?
DEBUG [main] - ==> Parameters: 1(String)
DEBUG [main] - <==      Total: 6
[User [id=10, username=张三, sex=1, birthday=Thu Jul 10 00:00:00 CST 2014, address=北京市], User [id=16, username=张小明, sex=1, birthday=null, address=河南郑州], User [id=22, username=陈小明, sex=1, birthday=null, address=河南郑州], User [id=24, username=张三丰, sex=1, birthday=null, address=河南郑州], User [id=25, username=陈小明, sex=1, birthday=null, address=河南郑州], User [id=28, username=王小军, sex=1, birthday=Tue Feb 23 00:00:00 CST 2016, address=河南郑州]]

可以看到sql语句为reparing: SELECT * FROM user WHERE user.sex=?,没有username的部分

2.userQueryVo设为null,则userCustom为null

//List<UserCustom> list = userMapper.findUserList(userQueryVo);
List<UserCustom> list = userMapper.findUserList(null);

输出

DEBUG [main] - ==>  Preparing: SELECT * FROM user
DEBUG [main] - ==> Parameters:
DEBUG [main] - <==      Total: 9
[User [id=1, username=王五, sex=2, birthday=null, address=null], User [id=10, username=张三, sex=1, birthday=Thu Jul 10 00:00:00 CST 2014, address=北京市], User [id=16, username=张小明, sex=1, birthday=null, address=河南郑州], User [id=22, username=陈小明, sex=1, birthday=null, address=河南郑州], User [id=24, username=张三丰, sex=1, birthday=null, address=河南郑州], User [id=25, username=陈小明, sex=1, birthday=null, address=河南郑州], User [id=26, username=王五, sex=null, birthday=null, address=null], User [id=27, username=王大军, sex=2, birthday=Tue Feb 23 00:00:00 CST 2016, address=河南郑州], User [id=28, username=王小军, sex=1, birthday=Tue Feb 23 00:00:00 CST 2016, address=河南郑州]]

可以看到sql语句变为了SELECT * FROM user

二、sql片段(重点)

解决代码重复的问题。

将上边实现的动态sql判断代码块抽取出来,组成一个sql片段。其它的statement中就可以引用sql片段。

2.1 定义sql片段

<!-- 定义sql片段id:sql片段的唯 一标识经验:1.是基于单表来定义sql片段,这样话这个sql片段可重用性才高2.在sql片段中不要包括 where-->
<sql id="query_user_where"><if test="userCustom!=null"><if test="userCustom.sex!=null and userCustom.sex!=''">AND user.sex = #{userCustom.sex}</if><if test="userCustom.username!=null and userCustom.username!=''">AND user.username LIKE '%${userCustom.username}%'</if></if>
</sql>

2.2引用sql片段

<!-- 用户信息综合查询#{userCustom.sex}:取出pojo包装对象中性别值${userCustom.username}:取出pojo包装对象中用户名称-->
<select id="findUserList" parameterType="com.iot.mybatis.po.UserQueryVo"resultType="com.iot.mybatis.po.UserCustom">SELECT * FROM user<!--  where 可以自动去掉条件中的第一个and --><where><!-- 引用sql片段 的id,如果refid指定的id不在本mapper文件中,需要前边加namespace --><include refid="query_user_where"></include><!-- 在这里还要引用其它的sql片段  --></where>
</select>

三、foreach标签

向sql传递数组或List,mybatis使用foreach解析

在用户查询列表和查询总数的statement中增加多个id输入查询。两种方法,sql语句如下:

  • SELECT * FROM USER WHERE id=1 OR id=10 OR id=16
  • SELECT * FROM USER WHERE id IN(1,10,16)

一个使用OR,一个使用IN

  • 在输入参数类型中添加List<Integer> ids传入多个id
public class UserQueryVo {//传入多个idprivate List<Integer> ids;getter、setter方法。。。
}
  • 修改mapper.xml
<if test="ids!=null"><!-- 使用 foreach遍历传入idscollection:指定输入 对象中集合属性item:每个遍历生成对象中open:开始遍历时拼接的串close:结束遍历时拼接的串separator:遍历的两个对象中需要拼接的串--><!-- 使用实现下边的sql拼接:AND (id=1 OR id=10 OR id=16)--><foreach collection="ids" item="user_id" open="AND (" close=")" separator="or"><!-- 每个遍历需要拼接的串 -->id=#{user_id}</foreach><!-- 实现  “ and id IN(1,10,16)”拼接 --><!-- <foreach collection="ids" item="user_id" open="and id IN(" close=")" separator=",">每个遍历需要拼接的串#{user_id}</foreach> --></if>
--------最终结果如下--------
<sql id="query_user_where"><if test="userCustom!=null"><if test="userCustom.sex!=null and userCustom.sex!=''">AND user.sex = #{userCustom.sex}</if><if test="userCustom.username!=null and userCustom.username!=''">AND user.username LIKE '%${userCustom.username}%'</if><if test="ids!=null"><foreach collection="ids" item="user_id" open="AND (" close=")" separator="or"><!-- 每个遍历需要拼接的串 -->id=#{user_id}</foreach></if></if>
</sql>
  • 测试代码

testFindUserList中加入

//传入多个id
List<Integer> ids = new ArrayList<Integer>();
ids.add(1);
ids.add(10);
ids.add(16);
//将ids通过userQueryVo传入statement中
userQueryVo.setIds(ids);

四、 Choose(when , otherwise )

Choose(when , otherwise )相当swtich

when元素执行SQL代码

<select id="findCustomerByNameOrJobs" parameterType="Customer" resultType="Customer">select *from customer where 1=1<choose><when test="username!=null and username!=''">and username like concat('%',#{username},'%')</when><when test="jobs !=null and jobs!=''">and jobs=#{jobs}</when><otherwise>and phone is not null</otherwise></choose></select>

当第一个when元素中的执行条件为真,则只动态组装第一个when元素的SQL,否则就继续判断第二个when元素中的条件是否为真。

when元素测试类

     @Testpublic void findCustomerBy() {Customer customer =new Customer();/* customer.setUsername("jack");*/customer.setJobs("teacher");List<Customer> customers =sqlSession.selectList("com.itheima.mapper"+".CustomerMapper.findCustomerByNameOrJobs",customer);for(Customer customer2:customers) {System.out.println(customer2);}
}

mybatis笔记-8、动态sql相关推荐

  1. MyBatis:学习笔记(4)——动态SQL

    MyBatis:学习笔记(4)--动态SQL 转载于:https://www.cnblogs.com/MrSaver/p/7453949.html

  2. JavaWeb学习笔记(动态SQL)

    JavaWeb学习笔记(动态SQL) 动态SQL中的元素 < if>元素 < choose>.< when>.< otherwise>元素 < w ...

  3. Mybatis 注解开发 + 动态SQL

    Hello 大家好我是橙子同学,今天分享注解Mybatis注解开发+动态sql 目录 每文一铺垫(今天有小插曲哦) 注解开发 添加 @Insert 删除 @Delete 查询 @Select 修改 @ ...

  4. Mybatis入门之动态sql

    Mybatis入门之动态sql 通过mybatis提供的各种标签方法实现动态拼接sql. 1.if.where.sql.include标签(条件.sql片段) <sql id="sel ...

  5. Mybatis映射文件动态SQL语句-01

    因为在很多业务逻辑复杂的项目中,往往不是简单的sql语句就能查询出来自己想要的数据,所有mybatis引入了动态sql语句, UserMapper.xml <?xml version=" ...

  6. Java - MyBatis中的动态SQL是什么意思?

    分享一个大牛的人工智能教程.零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请点击http://www.captainbed.net 对于一些复杂的查询,我们可能会指定多个查询条件,但是 ...

  7. mybatis注解开发动态sql

    mybatis注解开发动态sql 本篇来讲一下如何使用mybatis注解模式中的动态sql 先来讲一下什么是动态sql 在我们实际开发的时候可能会出现很多方法需要一条很相似的sql语句来进行增删改查, ...

  8. Mybatis学习笔记之---动态sql中标签的使用

    动态Sql语句中标签的使用 (一)常用标签 1.<if> if标签通常用于WHERE语句中,通过判断参数值来决定是否使用某个查询条件, 他也经常用于UPDATE语句中判断是否更新某一个字段 ...

  9. 6.Mybatis中的动态Sql和Sql片段(Mybatis的一个核心)

    视频地址:http://edu.51cto.com/sd/be679 动态Sql是Mybatis的核心,就是对我们的sql语句进行灵活的操作,他可以通过表达式,对sql语句进行判断,然后对其进行灵活的 ...

  10. mybatis学习(39):动态sql片段

    目录结构 com.geyao.mybatis.mapper BlogMapper类 package com.geyao.mybatis.mapper;import java.util.List; im ...

最新文章

  1. web自动化测试从入门到持续集成(selenium webdriver)
  2. linux安装硬盘命令,硬盘安装linux的两条命令
  3. Gson:我爸是 Google
  4. 在线作图|微生物多样性分析——丰度等级曲线
  5. 第一章 内核模块 elf文件
  6. 第三部分 Calendar函数接口
  7. 【转】wireshark过滤规则
  8. Dubbox服务的消费方配置
  9. 文本分类pytorch Bert fine tune
  10. 小孔子内容管理系统V2.0测试
  11. e生保等待期什么意思_平安e生保等待期是90天 保险90天等待期是什么
  12. w7网络计算机共享,网络共享设置 win7局域网共享设置最简单教程
  13. 修改input提示文字样式
  14. php 大转盘抽奖概率 角度,在线抽奖大转盘和概率计算
  15. 职场的技术人如何做好一个公众号?
  16. 用C语言实现求水仙花数
  17. PhotoSwipe 图片浏览插件使用方法 - 简单
  18. 准备工作(正则表达式学习)
  19. matlab中poly2sym什么意思,[转载]sym2poly   poly2sym
  20. 全红婵水花消失术是怎样炼成的,郭晶晶都羡慕她怎么跳得那么好

热门文章

  1. 常用计算机杀毒软件名称,最常用的杀毒软件有哪些
  2. TDP158RSBR 6-Gbps 转接驱动器,兼容HDMI2.0
  3. mysql resource_MySQL - Resource temporarily unavailable问题处理
  4. [论文阅读笔记]DeepFool: a simple and accurate method to fool deep neural networks
  5. 【Python游戏】实现一个恶搞游戏,粉丝大战xxx小游戏(狗头保命) | 附带源码
  6. 国内如何申请到Twitter API
  7. ‘com.cloudera.server.cmf.TrialState‘:Cannot resolve reference to bean ‘entityManagerFactoryBean‘
  8. 衣带渐宽终不悔,为伊消得人憔悴--DbHelper增强版
  9. html鼠标悬停闪烁,鼠标悬停闪烁星星插件jQuery-canvas-sparkles
  10. 页面关闭时postback,导致IE假死的分析