MyBatis实现动态SQL的实现方法

 更新时间:2019年12月20日 08:32:51   作者:Norvyn.  
这篇文章主要介绍了MyBatis实现动态SQL的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

MyBatis 最强大的特性之一就是它的动态语句功能。如果您以前有使用JDBC或者类似框架的 经历,您就会明白把SQL语句条件连接在一起是多么的痛苦,要确保不能忘记空格或者不要在 columns列后面省略一个逗号等。动态语句能够完全解决掉这些痛苦。

​尽管与动态SQL一起工作不是在开一个party,但是MyBatis确实能通过在任何映射SQL语句中 使用强大的动态SQL来改进这些状况。

if 元素

if元素条件判断,动态 SQL 最常做的事就是有条件地包括 where 子句。例如:

<select id=”findActiveBlogWithTitleLike” parameterType=”Blog” resultType=”Blog”>
 SELECT * FROM BLOG WHERE state = ‘ACTIVE'
 <if test=”title != null”>
 AND title like #{title}
 </if>
</select>

where元素

where元素知道插入“where”如果它包含的标签中有内容返回的话。此外,如果返回的内容 以“AND” 或者 “OR”开头,它会把“AND” 或者 “OR”去掉。

<select id="findStudentList" parameterType="hashmap" resultMap="studentInfo">
 select * from t_student
 <where>
 <if test="name!=null">
  and name=#{name}
 </if>
 <if test="age!=null">
  and age=#{age}
 </if>
 </where>
</select>

choose元素

有时候我们不想应用所有的条件,而是想从多个选项中选择一个。与 java 中的 switch 语句 相似,MyBatis 提供了一个 choose 元素。

when元素

当when里面的条件成立时,执行when标签内的语句

<select id="findStudentList" parameterType="hashmap" resultMap="studentInfo">
 select * from t_student
 <where>
 <choose>
  <when test="name!=null">
  and name=#{name}
  </when>
  <when test="age!=null">
  and age=#{age}
  </when>
 </choose>
 </where>
</select>

otherwise元素

当所有when都不成立了,执行otherwise

<select id="findStudentList" parameterType="hashmap" resultMap="studentInfo">
 select * from t_student
 <where>
 <choose>
  <when test="name!=null">
  and name=#{name}
  </when>
  <when test="age!=null">
  and age=#{age}
  </when>
  <otherwise>
  and name='jim'
  </otherwise>
 </choose>
 </where>
</select>

trim元素

如果 where 元素的行为并没有完全按您想象的那样,您还可以使用 trim 元素来自定义。

​ trim内的if有成立的就添加一个前缀用prefix=""定义,没有就不添加。

​ trim元素也可以去掉where后面指定的关键字and或者or等等,用prefixOverrides=""定义

<select id="findStudentList" parameterType="hashmap" resultMap="studentInfo">
 select * from t_student
 <trim prefix="where" prefixOverrides="and">
 <if test="name!=null">
  and name=#{name}
 </if>
 <if test="age!=null">
  and age=#{age}
 </if>
 </trim>
</select>

set元素

在动态update语句里相似的解决方式叫做set,这个set元素能够动态地更新列。

set 元素将动态的配置set关键字,也用来剔除追加到条件末尾的任何不相关的逗号。

<update id="updateStudent" parameterType="Student">
 update t_student
 <set>
 <if test="name!=null">
  name=#{name},
 </if>
 <if test="age!=null">
  age=#{age},
 </if>
 </set>
 where id=#{id}
</update>

当然了,聪明的你肯定想知道等同的 trim 元素该怎么写吧,它就像这样 :

<update id="updateStudent" parameterType="Student">
 update t_student
 <trim prefix="set" prefixOverrides=",">
 <if test="name!=null">
  name=#{name},
 </if>
 <if test="age!=null">
  age=#{age},
 </if>
 </trim>
 where id=#{id}
</update>

注意这种情况,我们剔除了一个后缀, 同时追加了一个前缀 。

Foreach 元素

另一个动态 SQL 经常使用到的功能是集合迭代,通常用在 in条件句

foreach 元素非常强大,允许您指定一个集合,申明能够用在元素体内的项和索引变量。也 允许您指定开始和结束的字符,也可以加入一个分隔符到迭代器之间。这个元素的聪明之处在于 它不会意外地追加额外的分隔符。

<select id="findStudentByAge" resultMap="studentInfo">
 select * from t_student where age in
 <foreach collection="list" item="item" open="(" separator="," close=")">
 #{item}
 </foreach>
</select>

测试方法如下:

public void findStudentByAge() {
 SqlSession sqlSession = null;
 try {
 sqlSession = MyBatisUtil.getsqlSession();
 StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
 List<Integer> list= new ArrayList<Integer>();
 list.add(21);
 list.add(23);
 List<Student> liststudent =studentDao.findStudentByAge(list);
 System.out.println(liststudent);
 } catch (Exception e) {
 e.printStackTrace();
 }
}
 

输出的sql结果:select * from t_student where age in (item,item),显示age为21、23的学生信息。

Settings 元素

Setting 元素下是些非常重要的设置选项,用于设置和改变 MyBatis 运行中的行为。下面的 表格列出了 Setting 元素支持的属性、默认值及其功能。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vuQc9cUw-1576746278488)(E:\javaEE笔记\img\QQ浏览器截图20191218153217.png)]

完整配置例子:

<settings>
 <setting name="cacheEnabled" value="true"/>
 <setting name="lazyLoadingEnabled" value="true"/>
 <setting name="multipleResultSetsEnabled" value="true"/>
 <setting name="useColumnLabel" value="true"/>
 <setting name="useGeneratedKeys" value="false"/>
 <setting name="enhancementEnabled" value="false"/>
 <setting name="defaultExecutorType" value="SIMPLE"/>
 <setting name="defaultStatementTimeout" value="25000"/>
</settings>

XML 中的特殊字符

如果 MyBatis 使用 XML 配置,那不可避免地会遇到一些对 XML 来说是特殊的字符。如小于号 “<”,因为 XML 解析器会认为是一个新元素的开始,因此要进行转义。这里有两个方法: 

1 使用转义实体

下面是五个在 XML 文档中预定义好的转义实体 :

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

<select id="findStudentList" parameterType="hashmap" resultMap="studentInfo">
 select * from t_student where age $lt; 23
</select>

2 使用 CDATA 部件

 一个 CDATA 部件以"“标记结束。在”"之间 的特殊字符的意义都不起作用,而转变为普通字符串内容。

一般地,在 MyBatis 的 XML 映射语句配置文件中,如果 SQL 语句有特殊字符,那么使用 CDTA 部件括起来,如: 

<select id="findStudentList" parameterType="hashmap" resultMap="studentInfo">
 <![CDATA[
 select * from t_student where age = 23
 ]]> 
</select>

 而在动态 SQL 各元素的测试语句中,在元素的属性中不能再嵌套其它元素或包含 CDATA 部 件,因此只能使用转义实体, 如:

<select id="selectAuthor_use_where" parameterType="Blog" resultType="Author">
 select * from author
 <where>
 <if test="authorId != null
  and authorId &gt;= 1
  and authorId &lt;= 5">
 id = #{authorId}
 </if>
 </where>
</select> 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • Java实现天天酷跑小游戏完整代码(附源码)

    Java实现天天酷跑小游戏完整代码(附源码)

    这篇文章主要介绍了使用Java实现天天酷跑(附源码),本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12
  • java面试try-with-resources问题解答

    java面试try-with-resources问题解答

    这篇文章主要介绍了java面试try-with-resources问题解答, 这个语句的作用是,确保该语句执行之后,关闭每一个资源,也就是说它确保了每个资源都在生命周期结束之后被关闭
    2022-07-07
  • Spring Boot文件上传原理与实现详解

    Spring Boot文件上传原理与实现详解

    这篇文章主要介绍了Spring Boot 文件上传原理与实现详解,前端文件上传是面向多用户的,多用户之间可能存在上传同一个名称、类型的文件;为了避免文件冲突导致的覆盖问题这些应该在后台进行解决,需要的朋友可以参考下
    2024-01-01
  • 深入了解Java核心类库--Math类

    深入了解Java核心类库--Math类

    本文是小编最新给大家整理的关于Java中Math类常用方法的知识,通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧,
    2021-07-07
  • Java System类两个常用方法代码实例

    Java System类两个常用方法代码实例

    这篇文章主要介绍了Java System类两个常用方法代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • java面试常见模式问题---代理模式

    java面试常见模式问题---代理模式

    代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息
    2021-06-06
  • Java获取Process子进程进程ID方法详解

    Java获取Process子进程进程ID方法详解

    这篇文章主要介绍了Java获取Process子进程进程ID方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-12-12
  • Java利用完全二叉树创建大根堆和小根堆

    Java利用完全二叉树创建大根堆和小根堆

    大根堆是每个结点的值不大于他的父亲结点的值;小根堆是每个结点的值不小于他的父亲结点的值。本文将利用完全二叉树创建大根堆和小根堆,感兴趣的可以了解一下
    2022-08-08
  • SpringBoot与Postman实现REST模拟请求的操作

    SpringBoot与Postman实现REST模拟请求的操作

    这篇文章主要介绍了SpringBoot与Postman实现REST模拟请求的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • java 查询oracle数据库所有表DatabaseMetaData的用法(详解)

    java 查询oracle数据库所有表DatabaseMetaData的用法(详解)

    下面小编就为大家带来一篇java 查询oracle数据库所有表DatabaseMetaData的用法(详解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-11-11

最新评论