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. 腾讯QQ的开发分客户端软件和服务器端软件

    Windows客户端主要是C++ COM/ATL Q+Web 后端C++ CGI ,前端javascript和flash 望采纳 腾讯QQ使用何种开发平台? 腾讯QQ的开发分客户端软件和服务器端软件两 ...

  2. js错误:对象不支持此属性或方法

    对象不支持此属性或方法 错误原因: 可能是js的文件名和另外一个文件重复. 也有可能是js里的function和另外一个function名字重复. 也有可能是js里的function和页面的某一元素重 ...

  3. 不用Invoke就等用 Control.CheckForIllegalCrossThreadCalls = false;

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  4. 你真的了解try{ return }finally{}中的return?

    你真的了解try{ return }finally{}中的return?   今天去逛论坛 时发现了一个很有趣的问题: 谁能给我我解释一下这段程序的结果为什么是:2.而不是:3 代码如下: class ...

  5. 68. Text Justification

    题目: Given an array of words and a length L, format the text such that each line has exactly L charac ...

  6. js 字符串日期 转成 Date

    只支持 2015/09/23 反斜杠这样类型 2015-09-23 单横的这种无法识别 var dateStr='${endDate}'; dateStr=dateStr.replace(/-/g,' ...

  7. 前端自动化神器gulp使用记录

    1.安装压缩图片插件的时候,由于网络原因,死活安装不成功.由于imagemin本身就包含很多插件,安装的时候卡住了,很是郁闷.如果要压缩png图片,那就单独安装imagemin-pngquant压缩插 ...

  8. makefile使用

    linux make手册:http://www.gnu.org/software/make/manual/make.html 一篇文章: 假设我们有一个程序由5个文件组成,源代码如下:/*main.c ...

  9. 使用 powershell 的 grep 过滤文本

    使用 powershell 的 grep 过滤文本 有个log文件,大小在4M左右,要求找出里面耗时超过100s 的记录.首先想到了强大的 grep ,那么就搞起. 先在网上找一下资料,这篇文章,有几 ...

  10. 浅谈PHP自动化代码审计技术

    原文出处: exploit   欢迎分享原创到伯乐头条 0×00 由于博客实在没什么可以更新的了,我就把目前做的事情总结一下,当做一篇博客,主要是谈一谈项目中所运用的一些技术.目前市面上有不少PHP的 ...