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. QTP之delphi试用感想一(自动化测试)

    这两天一直在琢磨自动化测试,自动化测试,其实与单元测试有一些相同之处,单元测试的目的也是可以一次写,多次运行,对于测试驱动及后期维护真是有非常多的好处,用自动化测试工具也是如何,主要目的是为了回归测试 ...

  2. WCF入门(二)-----实战开发

    在这个实战中我们将使用DataContract,ServiceContract来构建WCF服务,并使用VS2008内置的“WCFSVCHost”运行我们创建的WCF服务,并使用“WCF测试客户端”来测 ...

  3. linux jdk bin安装

    1.jdk-1_5_0_06-linux-i586.bin下载到/usr/soft,赋予可执行权限:chmod 755jdk-1_5_0_06-linux-i586.bin 2.执行:./jdk-1_ ...

  4. Java API —— 多线程

    1.多线程概述     1)进程:         正在运行的程序,是系统进行资源分配和调用的独立单位.         每一个进程都有它自己的内存空间和系统资源.     2)线程:         ...

  5. NYOJ-253 凸包

    LK的旅行 时间限制:2000 ms  |  内存限制:65535 KB 难度:5   描述 LK最近要去某几个地方旅行,她从地图上计划了几个点,并且用笔点了出来,准备在五一假期去这几个城市旅行.现在 ...

  6. [Codeforces677B]Vanya and Food Processor(模拟,数学)

    题目链接:http://codeforces.com/contest/677/problem/B 题意:n个土豆,每个土豆高ai.现在有个加工机,最高能放h,每次能加工k.问需要多少次才能把土豆全加工 ...

  7. Mybatis的if test字符串比较问题

    1. Mybatis判断字符串是否为空的变态写法 <if test="bussSceneIsNull =='0'.toString() "> <![CDATA[ ...

  8. poj 3273 Monthly Expense(贪心+二分)

    题目:http://poj.org/problem?id=3273 题意:把n个数分成m份,使每份的和尽量小,输出最大的那一个的和. 思路:二分枚举最大的和,时间复杂度为O(nlog(sum-max) ...

  9. poj 3368 Frequent values(RMQ)

    题目:http://poj.org/problem?id=3368 题意:给定n个数,顺序为非下降,询问某个区间内的数出现最多的数的 出现次数.. 大白书上的 例题..算是RMQ变形了, 对 原数组重 ...

  10. VB获取浏览器版本

    String userAgent; userAgent = Request.UserAgent; ) { // The browser is Microsoft Internet Explorer V ...