目录
动态 SQL
动态SQL语句标签包括以下标签:
1、If标签
2、trim标签:
3、foreach标签
4、choose标签
5、set
6、where
mybatis传参
1、八大基础类型
2、String类型参数
3、传递对象或者集合
4、传递多个参数
模糊查询
查询返回结果集
分页查询
范围查询,转义字符处理
动态 SQL
通常写在mapper包下面的地址映射配置文件(.xml)中。根据条件的不同, SQL 语句也会随之动态的改变. MyBatis 中,提供了一组标签用于实现动态 SQL
动态SQL语句标签包括以下标签:
1、If标签
条件判断标签,通过判断参数取值来决定是否使用某个查询条件,基本用法如下:
select from t_book where 1=1 and book_type=#{bookType}
这里上面的sql语句后面必须添加 where 1=1 或者 使用where标签
if在这里是判断,判断书本类型是否为空 不为空就根据书本类型查询
id为mMapper的接口方法名,resultType为结果集类型
test 属性用于指定判断条件.
book_id, book_name, book_name_pinyin, book_price, book_type
2、trim标签:
trim标签用于控制sql语句的前缀及后缀,其具体属性如下:
| 属性 | 描述 |
|---|---|
| prefix | 指定sql语句拼接的前缀 |
| subfix | 指定sql语句拼接的后缀 |
| prefixOverrides | 指定sql语句前面要去除的关键字或字符,如and 逗号 括号等 |
| suffixOverrides | 指定sql语句后面要去除的关键字或字符 |
insert into t_book book_id, book_name, book_name_pinyin, book_price, book_type, #{bookId,jdbcType=INTEGER}, #{bookName,jdbcType=VARCHAR}, #{bookNamePinyin,jdbcType=VARCHAR}, #{bookPrice,jdbcType=REAL}, #{bookType,jdbcType=VARCHAR},
动态的新增方法,判断实体类的属性是否为空,为空则不给予添加此对应的字段
3、foreach标签
动态sql的一个常用操作时要求对一个集合进行遍历,比如说使用in操作符就会用到
| 属性 | 描述 |
|---|---|
| collection | 表示迭代集合的名称,一般可为list、set、array、map,该参数为必选参数 |
| item | 本次迭代获取的元素,如collection为list、set、array则item为其中元素,若为map,则item为key-value中的alue,必填参数 |
| open | 表示该语句以什么开始,最常见的是左括号“(” , 可选参数 |
| close | 表示该语句以什么结束,最常见的是右括号“)” , 可选参数 |
| separator | 分隔符,mybatis会在每次迭代后给item后添加一个分隔符,一般为逗号,可选参数 |
| index | 在list set 数组中,index表示当前迭代元素的下标,在map中index表示key-value中的key,可选参数 |
4、choose标签
有时候,我们并不想应用所有的条件,而只是想从多个选项中选一个,而if标签是只要条件为真就会执行sql拼装.这时就需要使用choose标签,choose与java的switch功能类似;
mybatis会依次顺序判断各choose中的条件,当when某个条件满足时,就会跳出choose,即只选择第一个满足条件的when,如果choose中的条件都不满足,则执行otherwise中的语句;
总结:choose otherwise 类似于java的 switch…in case…default
select from t_book where 1=1 and book_name like concat('%',#{bookName},'%') and book_type like concat('%',#{bookType},'%') and bookId =#{bookId}
在此,判断书本名称是否为空,不为空就根据书本名称模糊查询,书本类型是否为空,不为空就根据书本类型模糊查询,假如都为空就根据书本id查询
5、set
set用于更新的sql语句中
在update时,多条件更新,每个属性后面要加逗号“,”,这个时候可能会出现多一个“,”的情况,此时我们就可以使用set去掉后边的“,”,除此之外我们使用前面说的trim也可实现当前的操作
update t_book where book_id = #{bookId,jdbcType=INTEGER} book_name = #{bookName,jdbcType=VARCHAR}, book_name_pinyin = #{bookNamePinyin,jdbcType=VARCHAR}, book_price = #{bookPrice,jdbcType=REAL}, book_type = #{bookType,jdbcType=VARCHAR},
修改方法,假如实体类属性为空就不修改此属性所对于的字段
6、where
用于管理 where 子句. 有如下功能:
1) 如果没有条件, 不会生成 where 关键字
2) 如果有条件, 会自动添加 where 关键字
3) 如果第一个条件中有 and, 自动去除之
mybatis传参
1、八大基础类型
Mapper接口
//传递Integer类型的参数,等同于传递八大基础类型
List queryBookId(Integer bookId);
实现对应Mapper接口的xml
select from t_book where 1=1
and book_id=#{value}
这里的if标签的test条件使用的value 不能写参数名称
但是if标签里面取值可以直接写参数名取值
2、String类型参数
Mapper接口
必须使用@Param方式,并且指明参数名
List queryBookType(@Param("bType") String bookType);
实现对应Mapper接口的xml
这里使用的是注解里面设置的参数名称,不能写参数里面的参数名称,也不能写value
3、传递对象或者集合
Mapper接口
List queryBookObject(Book book);
实现对应Mapper接口的xml
对象
select from t_book where 1=1
and book_type=#{bookType}
集合
Mapper接口 //传递Integer类型的参数,等同于传递八大基础类型 ListqueryBookId(Integer bookId); 实现对应Mapper接口的xml
select
from t_book where 1=1
and book_id=#{value}
这里的if标签的test条件使用的value 不能写参数名称
但是if标签里面取值可以直接写参数名取值
2、String类型参数
Mapper接口
必须使用@Param方式,并且指明参数名
List queryBookType(@Param("bType") String bookType);
实现对应Mapper接口的xml
这里使用的是注解里面设置的参数名称,不能写参数里面的参数名称,也不能写value
3、传递对象或者集合
Mapper接口
List queryBookObject(Book book);
实现对应Mapper接口的xml
对象
select from t_book where 1=1
and book_type=#{bookType}
集合
Mapper接口 必须使用@Param方式,并且指明参数名 ListqueryBookType(@Param("bType") String bookType);
实现对应Mapper接口的xml
这里使用的是注解里面设置的参数名称,不能写参数里面的参数名称,也不能写value
Mapper接口 ListqueryBookObject(Book book); 实现对应Mapper接口的xml
对象
select
from t_book where 1=1
and book_type=#{bookType}
集合
4、传递多个参数
Mapper接口
List queryBookByParams(@Param("bookType") String bookType,@Param("bookId") Integer bookId);
实现对应Mapper接口的xml
这里标签里面用的是@Param定义的参数名称,不是方法的参数名称
模糊查询
Mapper接口 ListqueryBookByParams(@Param("bookType") String bookType,@Param("bookId") Integer bookId);
实现对应Mapper接口的xml
这里标签里面用的是@Param定义的参数名称,不是方法的参数名称
三种方式:
#{}:相当于占位符,参数传递时需要手动拼接%%
${}:使用$传递时,只传递参数本身, 例如: "zs"--> ${} --> zs
参数类型为字符串,#会在前后加单引号['],$则直接插入值
问题使用${...}代替#{...}(不建议使用该方式,有Sql注入风险)
concat():为数据库的拼接方法
查询返回结果集
resultMap:适合使用返回值是自定义实体类的情况
resultType:适合使用返回值的数据类型是非自定义的,即JDK的提供类型
Mapper接口
List queryMap();
Book queryBookByID(Integer bookId);
//Map和List
分页查询
为什么要重写mybatis的分页?
Mybatis的分页功能很弱,它是基于内存的分页(查出所有记录再按偏移量offset和边界limit取结果),在大数据量的情况下这样的分页基本上是没有用的
在pom.xml文件导入分页插件
com.github.pagehelper
pagehelper
5.1.2
将pagehelper插件配置到mybatis的核心配置文件中
Mapper接口
List
queryBookPager(Book book); 实现对应Mapper接口的xml
导入分页帮助PageBean.java工具类
分页测试
PageBean pageBean=new PageBean();
pageBean.setPage(2);
//判断是否分页
if (null != pageBean && pageBean.isPagination()) {
// 参数1:当前页码,参数2:每页条数
PageHelper.startPage(pageBean.getPage(), pageBean.getRows());
}
List bookList = bookService.queryBookPager(Book.builder().bookName("西游").build(), pageBean);
System.out.println(bookList.getClass());
if (null != pageBean && pageBean.isPagination()) {
PageInfo pageInfo = new PageInfo(bookList);
System.out.println("页码:" + pageInfo.getPageNum());
System.out.println("页大小:" + pageInfo.getPageSize());
System.out.println("总记录:" + pageInfo.getTotal());
List list = pageInfo.getList();
list.forEach(System.out::println);
}
范围查询,转义字符处理
>(>)
<(<)
&(&)
空格( )
Bookvo属性
private List
ids;
private Float min;private Float max;
Mapper接口 示例七:范围查询,转义字符处理 ListqueryBookRange(BookVo bookvo); 实现对应Mapper接口的xml
最后给一个方便使用对象赋值的一个插件
导入lombok插件
org.projectlombok lombok1.18.22 provided
之后在实体类上写入注解
加入@Builder之后
Book.builder().bookId(1).build();赋值在builder()和build();之间如
Book.builder().bookId(1).bookName("1").build();
代码地址 提取码:hm4j
至此,MyBatis动态sql和分页介绍完毕,由于作者水平有限难免有疏漏,欢迎留言纠错。



