8.1     什么是动态sql

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

8.2     需求

  用户信息综合查询列表和用户信息查询列表总数这两个statement的定义使用动态sql。

  对查询条件进行判断,如果输入参数不为空才进行查询条件拼接。

8.3     mapper.xml

  <!-- 动态sql -->
<select id="findUserListDynamic" parameterType="UserQueryVo" resultType="User">
SELECT * FROM USER
<!-- where 可以自动去掉第一个and -->
<where>
<if test="userCustom != null">
<if test="userCustom.sex != null and userCustom.sex != ''"></if>
and sex = #{userCustom.sex}
</if>
<if test="userCustom.username != null and userCustom.username != ''">
  and username LIKE '%${userCustom.username}%'
</if>
</where>
</select>
<!-- 动态sql -->
<select id="findUserCountDynamic" parameterType="UserQueryVo" resultType="int">
SELECT count(*) FROM USER
<!-- where 可以自动去掉第一个and -->
<where>
<if test="userCustom != null">
<if test="userCustom.sex != null and userCustom.sex != ''"></if>
and sex = #{userCustom.sex}
</if>
<if test="userCustom.username != null and userCustom.username != ''">
and username LIKE '%${userCustom.username}%'
</if>
</where>
</select>

8.4     测试代码

   //08 使用动态sql 如果sex为空,count应该为0,否则正常查询
@Test
public void testfindUserCountDynamic() throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); //创建UserMapper对象,mybatis自动生成mapper代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class); //创建包装对象,设置查询条件
UserQueryVo userQueryVo = new UserQueryVo();
User user = new User();
//user.setSex("1"); //如果注释,count应该为0
user.setUsername("张");
userQueryVo.setUserCustom(user); //调用userMapper的方法
int count = userMapper.findUserCountDynamic(userQueryVo);
System.out.println(count);
} // 08 动态sql 如果sex为空,list不应该有成员
@Test
public void testfindUserListDynamic(){ SqlSession sqlSession = sqlSessionFactory.openSession(); //创建UserMapper对象,mybatis自动生成mapper代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class); //创建包装对象,设置查询条件
UserQueryVo userQueryVo = new UserQueryVo(); User user = new User();
user.setId(24);
//user.setSex("1");
user.setUsername("张");
userQueryVo.setUserCustom(user); //调用userMapper的方法
List<User> list = userMapper.findUserListDynamic(userQueryVo);
System.out.println(list.size());
}

8.5     sql片段

8.5.1     需求

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

  方便程序员进行开发。

8.5.2     定义sql片段

    <!-- 定义sql片段
id:sql片段的唯 一标识
经验:是基于单表来定义sql片段,这样话这个sql片段可重用性才高
在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>

8.5.3     引用sql片段

 <!-- 引用sql片段 -->
<select id="findUserListPart" parameterType="UserQueryVo" resultType="User">
SELECT * FROM USER
<where>
<!-- 引用sql片段 的id,如果refid指定的id不在本mapper文件中,需要前边加namespace -->
<include refid="query_user_where"></include>
<!-- 在这里还要引用其它的sql片段 -->
</where>
  </select> <!-- 引用sql片段 -->
<select id="findUserCountPart" parameterType="UserQueryVo" resultType="int">
SELECT count(*) FROM USER
<where>
<!-- 引用sql片段 的id,如果refid指定的id不在本mapper文件中,需要前边加namespace -->
<include refid="query_user_where"></include>
<!-- 在这里还要引用其它的sql片段 -->
</where>
</select>

  测试:和动态sql测试结果一样

8.6     foreach

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

8.6.1     需求

  在用户查询列表和查询总数的statement中增加多个id输入查询。

  sql语句如下:

  两种方法:

  SELECT * FROM USER WHERE id=1 OR id=10 OR id=16

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

8.6.2     在输入参数类型中添加List<Integer> ids传入多个id

public class UserQueryVo {

   //传入多个id
private List<Integer> ids;

8.6.3     修改mapper.xml

  WHERE id=1 OR id=10 OR id=16

  在查询条件中,查询条件定义成一个sql片段,需要修改刚才的sql片段。

        <if test="ids!=null">
<!-- 使用 foreach遍历传入ids
collection:指定输入 对象中集合属性
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>
</if>

8.6.4     测试代码

   // 08 动态sql 测试foreach
@Test
public void testfindUserListPartForeach(){ SqlSession sqlSession = sqlSessionFactory.openSession(); //创建UserMapper对象,mybatis自动生成mapper代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class); //创建包装对象,设置查询条件
UserQueryVo userQueryVo = new UserQueryVo();
User userCustom = new User();
//由于这里使用动态sql,如果不设置某个值,条件不会拼接在sql中
     //userCustom.setSex("1");
userCustom.setUsername("小明"); //传入多个id
List<Integer> ids = new ArrayList<Integer>();
ids.add(1);
ids.add(10);
ids.add(16); //将ids通过userQueryVo传入statement中
userQueryVo.setIds(ids);
userQueryVo.setUserCustom(userCustom); //调用userMapper的方法
List<User> list = userMapper.findUserListPart(userQueryVo); System.out.println(list.size());
}

8.6.5     另外一个实现

        <!-- 实现  “ and id IN(1,10,16)”拼接 -->
<foreach collection="ids" item="user_id" open="and id IN(" close=")" separator=",">
<!--每个遍历需要拼接的串 -->
#{user_id}
</foreach>

mybatis系列-08-动态sql的更多相关文章

  1. 【mybatis深度历险系列】mybatis中的动态sql

    最近一直做项目,博文很长时间没有更新了,今天抽空,学习了一下mybatis,并且总结一下.在前面的博文中,小编主要简单的介绍了mybatis中的输入和输出映射,并且通过demo简单的介绍了输入映射和输 ...

  2. Mybatis入门之动态sql

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

  3. mybatis 详解------动态SQL

    mybatis 详解------动态SQL   目录 1.动态SQL:if 语句 2.动态SQL:if+where 语句 3.动态SQL:if+set 语句 4.动态SQL:choose(when,o ...

  4. mybatis中的动态SQL

    在实际开发中,数据库的查询很难一蹴而就,我们往往要根据各种不同的场景拼接出不同的SQL语句,这无疑是一项复杂的工作,我们在使用mybatis时,mybatis给我们提供了动态SQL,可以让我们根据具体 ...

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

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

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

    动态Sql是Mybatis的核心,就是对我们的sql语句进行灵活的操作,他可以通过表达式,对sql语句进行判断,然后对其进行灵活的拼接和组装.可以简单的说成Mybatis中可以动态去的判断需不需要某些 ...

  7. MyBatis注解配置动态SQL

    MySQL创建表 DROP TABLE IF EXISTS `tb_employee`; CREATE TABLE `tb_employee` ( `id` int(11) NOT NULL AUTO ...

  8. mybatis框架(5)---动态sql

    那么,问题来了: 什么是动态SQL? 动态SQL有什么作用? 传统的使用JDBC的方法,相信大家在组合复杂的的SQL语句的时候,需要去拼接,稍不注意哪怕少了个空格,都会导致错误.Mybatis的动态S ...

  9. MyBatis进阶使用——动态SQL

    MyBatis的强大特性之一就是它的动态SQL.如果你有使用JDBC或者其他类似框架的经验,你一定会体会到根据不同条件拼接SQL语句的痛苦.然而利用动态SQL这一特性可以彻底摆脱这一痛苦 MyBati ...

随机推荐

  1. 电容值E系列标称方法

    本节首先介绍常用的E系列标称方法,然后介绍电阻.电容器.电感器.二极管的分类.性能和识别方法,以及简单的实用电路. 一.E系列标称方法 厂家生产的电阻器,并不是包含任何阻值,就像人民币,只有1.2.5 ...

  2. AsyncTask 与 Thread+Handler

    AsyncTask是封装好的线程池,比起Thread+Handler的方式,AsyncTask在操作UI线程上更方便,因为onPreExecute().onPostExecute()及更新UI方法on ...

  3. CentOS7 升级python同时解决yum损坏问题

    CentOS7中的python版本为python2.7.5,升级到最新版的python时需要注意两个问题 新版的python安装好后要修改python的系统默认指向问题 升级到最新版python后yu ...

  4. 传感器(3)传感器的X,Y,Z轴

    设备正面水平向上. X轴 : 左右方向,向右是正值. Y轴 : 远近方向,远离你是负. Z轴 : 上下方向,向上是正值.

  5. git stash 暂存当前修改

    当我们在开发项目的时候,突然来一个变更需要修改,我们除了将当前项目提交(commit)后切换(checkout) 到其他分支外,我们还可以先将当前的修改暂存(stash)起来,然后再切换(checko ...

  6. Linux 下查看文件字符编码和转换编码

    Linux 下查看文件字符编码和转换编码 如果你需要在Linux中操作windows下的文件,那么你可能会经常遇到文件编码转换的问题.Windows中默认的文件格式是GBK(gb2312),而Linu ...

  7. CSS在不同浏览器兼容问题,margin偏移/offset溢出等

    margin在垂直取值时取最大值 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "h ...

  8. 函数fil_node_create

    /*******************************************************************//** Appends a new file to the c ...

  9. BZOJ_1028_[JSOI2007]_麻将_(模拟+贪心)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1028 同一种花色的牌,序数为\(1,2,...,n\).定义"和了"为手上 ...

  10. POJ 3352 Road Construction(边双连通分量,桥,tarjan)

    题解转自http://blog.csdn.net/lyy289065406/article/details/6762370   文中部分思路或定义模糊,重写的红色部分为修改过的. 大致题意: 某个企业 ...