MyBatis笔记(六)
1. 动态SQL
1.1 介绍
概念:**动态SQL指的是根据不同的查询条件 , 生成不同的Sql语句.*
官网描述:
MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句的痛苦。例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。
虽然在以前使用动态 SQL 并非一件易事,但正是 MyBatis 提供了可以被用在任意 SQL 映射语句中的强大的动态 SQL 语言得以改进这种情形。
动态 SQL 元素和 JSTL 或基于类似 XML 的文本处理器相似。在 MyBatis 之前的版本中,有很多元素需要花时间了解。MyBatis 3 大大精简了元素种类,现在只需学习原来一半的元素便可。MyBatis 采用功能强大的基于 OGNL 的表达式来淘汰其它大部分元素。
- if
- choose (when, otherwise)
- trim (where, set)
- foreach
-------------------------------
1.2 搭建环境
新建一个表:blog
CREATE TABLE `blog` (
`id` varchar(50) NOT NULL COMMENT '博客id',
`title` varchar(100) NOT NULL COMMENT '博客标题',
`author` varchar(30) NOT NULL COMMENT '博客作者',
`create_time` datetime NOT NULL COMMENT '创建时间',
`views` int(30) NOT NULL COMMENT '浏览量'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
插件IDUtil工具类
public class IDUtil {
public static String genId(){
return UUID.randomUUID().toString().replaceAll("-","");
}
}
编写实体类
public class Blog {
private String id;
private String title;
private String author;
private Date createTime;
private int views; // 无参构造
// 有参构造
// get、set、toString
}
编写Mapper接口及mapper配置文件
public interface BlogMapper {
int addBlog(Blog blog);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="top.linzeliang.mapper.BlogMapper">
<insert id="addBlog" parameterType="blog">
insert into blog (id, title, author, create_time, views)
values (#{id},#{title},#{author},#{createTime},#{views});
</insert>
</mapper>
在MyBatis配置文件中设置下驼峰线自动转换
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!--注册Mapper.xml-->
<mappers>
<mapper resource="top/linzeliang/mapper/BlogMapper.xml"/>
</mappers>
初始化博客方法
@Test
public void addInitBlog(){
SqlSession session = MybatisUtils.getSession();
BlogMapper mapper = session.getMapper(BlogMapper.class); Blog blog = new Blog();
blog.setId(IDUtil.genId());
blog.setTitle("Mybatis如此简单");
blog.setAuthor("妙啊");
blog.setCreateTime(new Date());
blog.setViews(9999); mapper.addBlog(blog); blog.setId(IDUtil.genId());
blog.setTitle("Java如此简单");
mapper.addBlog(blog); blog.setId(IDUtil.genId());
blog.setTitle("Spring如此简单");
mapper.addBlog(blog); blog.setId(IDUtil.genId());
blog.setTitle("微服务如此简单");
mapper.addBlog(blog); session.close();
}
2. IF和WHERE语句
if
语句就是判断是否满足某个条件,满足的话就添加标签内容到sql语句中where
语句:如果包含的标签中含有返回值得话,他就会自动插入一个where,如果返回值的内容的第一个开头是and
或者or
,则会自动剔除
需求:根据作者名字和博客名字来查询博,如果作者名字为空,那么只根据博客名字查询,反之,则根据作者名来查询
编写接口类
List<Blog> queryBlogIf(Map map);
编写对应的mapper配置文件
- 传入的参数是map,那么在if标签中直接写的是map中的key,不用加
#{}
<select id="queryBlogIf" resultType="blog" parameterType="map">
select *
from blog
<where>
<if test="title != null">
and title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</where>
</select>
- 传入的参数是map,那么在if标签中直接写的是map中的key,不用加
3. SET语句
- 如果在进行更新操作的时候,含有 set 关键词,则使用set标签,效果和
where
也是一样的
编写接口方法
int updateBlog(Map map);
编写对应的mapper配置文件
<update id="updateBlog" parameterType="map">
update blog
<set>
<if test="title != null">
title = #{title},
</if>
<if test="author != null">
author = #{author}
</if>
</set>
where id = #{id}
</update>
4. CHOOSE语句
- 有时候,我们不想用到所有的查询条件,只想选择其中的一个,查询条件有一个满足即可,使用 choose 标签可以解决此类问题,类似于 Java 的 switch 语句
编写接口方法
List<Blog> queryBlogChoose(Map map);
编写对应的mapper配置文件
<select id="selectBlogChoose" resultType="blog" parameterType="map">
select *
from blog
<where>
<choose>
<when test="title != null">
title = #{title}
</when>
<when test="author != null">
and author = #{author}
</when>
<otherwise>
adn views = #{views}
</otherwise>
</choose>
</where>
</select>
5. SQL片段
有时候可能某个 sql 语句我们用的特别多,为了增加代码的重用性,简化代码,我们需要将这些代码抽取出来,然后使用时直接调用
提取SQL片段:
<sql id="if-title-author">
<if test="title != null">
title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</sql>
引用SQL片段:
<select id="queryBlogIf" parameterType="map" resultType="blog">
select * from blog
<where>
<!-- 引用 sql 片段,如果refid 指定的不在本文件中,那么需要在前面加上 namespace -->
<include refid="if-title-author"></include>
<!-- 在这里还可以引用其他的 sql 片段 -->
</where>
</select>
最好基于 单表来定义 sql 片段,提高片段的可重用性
在 sql 片段中不要包括
where
6. ForEach
需求:我们需要查询 blog 表中 id 分别为1,2,3的博客信息
编写接口
List<Blog> queryBlogForeach(Map map);
编写对应的mapper配置文件
<select id="queryBlogForeach" parameterType="map" resultType="blog">
select * from blog
<where>
<!--
collection:指定输入对象中的集合属性
item:每次遍历生成的对象
open:开始遍历时的拼接字符串
close:结束时拼接的字符串
separator:遍历对象之间需要拼接的字符串
select * from blog where 1=1 and (id=1 or id=2 or id=3)
-->
<foreach collection="ids" item="id" open="and (" close=")" separator="or">
id = #{id}
</foreach>
</where>
</select>
总结:其实动态
sql
语句的编写往往就是一个拼接的问题,为了保证拼接准确,我们最好首先要写原生的sql
语句出来,然后在通过mybatis
动态sql
对照着改,防止出错
最新文章
- Mysql 中的事件//定时任务
- lua协程一则报错解决“attempt to yield across metamethod/C-call boundary”
- 使用Mulesoft建立webservice, simple方式,POJO
- poj1416 Shredding Company
- mac OS X下PhpStorm+MAMP PRO+Xdebug+FireFox集成开发和断点调试环境配置
- 【转】Android Listener侦听的N种写法
- 为什么选择我--ReactJS
- MS SQL 批量给存储过程/函数授权
- toString 方法在数组中的使用
- 前端技术之_CSS详解第六天--完结
- sed的替换元字符的语法
- spark配置参数
- Visual Studio 2010 VS IDE 编辑界面出现绿色的点 去掉绿色的空格点
- 定位crash的问题
- Java并发编程总结2——慎用CAS
- Vim中的寄存器
- Java实现WordCount
- sqli-labs学习笔记 DAY6
- XorPay 个人支付平台增加 个人支付宝支付接口
- *Amazon problem: 234. Palindrome Linked List (reverse the linked list with n time)
热门文章
- rem &; 16px &; 62.5%
- ES6 Arrow Function return Object
- 「NGK每日快讯」2021.1.26日NGK公链第84期官方快讯!
- 人物传记:Mila Fletcher:如何勤于思考抓住关键?
- JavaScript中判断对象是否属于Array类型的4种方法及其背后的原理与局限性
- int和Integer的比较详解
- 力扣1438. 绝对差不超过限制的最长连续子数组-C语言实现-中等难度
- 【JAVA并发第四篇】线程安全
- POJ-3281(最大流+EK算法)
- Docker系列——InfluxDB+Grafana+Jmeter性能监控平台搭建(一)