1.mybatis动态sql
1.1 if:if判断
<select id="queryBookByIf" resultType="com.zking.mybatis01.model.book">
select
<include refid="Base_Column_List"/>
from t_book where 1=1 <if test="null!=bookType and ''!=bookType"></if> and
book_type=#{bookType}
</select>
1.2 trim mybatis中trim是动态拼接;java中表示去除前后空格
prefix:前缀
suffix:后缀
suffixOverride:去除后缀指定的字符
prefixOverrides:去除前缀指定的字符
<insert id="insertSelective" parameterType="com.zking.mybatis01.model.book" >
insert into t_book
<trim prefix="(" suffix=")" suffixOverrides="," >
<if test="bookId != null" >
book_id,
</if>
<if test="bookName != null" >
book_name,
</if>
<if test="bookNamePinyin != null" >
book_name_pinyin,
</if>
<if test="bookPrice != null" >
book_price,
</if>
<if test="bookType != null" >
book_type,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides="," >
<if test="bookId != null" >
#{bookId,jdbcType=INTEGER},
</if>
<if test="bookName != null" >
#{bookName,jdbcType=VARCHAR},
</if>
<if test="bookNamePinyin != null" >
#{bookNamePinyin,jdbcType=VARCHAR},
</if>
<if test="bookPrice != null" >
#{bookPrice,jdbcType=REAL},
</if>
<if test="bookType != null" >
#{bookType,jdbcType=VARCHAR},
</if>
</trim>
</insert>
1.3 foreach:循环(三种方式)
第一种:
<select id="queryBookForEach" resultType="com.zking.mybatis01.model.book">
select <include refid="Base_Column_List"/> from t_book where 1=1
<foreach collection="ids" item="id" separator="," open=" and book_id in(" close=")">
#{id}
</foreach>
</select>
第二种:
第三种:
1.4 其他
choose:
choose(判断参数) - 按顺序将实体类 User 第一个不为空的属性作为:where条件,choose标签在mybatis的xml文件中, 一般与when标签结合使用, 主要用于条件查询,根据不同的情况来进行页面查询,choose的执行原理如下: 如果有一个when满足,那么choose结束, choose会按照when标签的顺序来执行,如果when执行的结果都会false,那么会执行otherwise标签里的语句
<select id="queryChooseTest" resultType="com.zking.mybatis01.model.book">
select <include refid="Base_Column_List"/> from t_book where 1=1
<choose>
<when test="value!=null and ''!=value">
and book_id = #{value}
</when>
<otherwise>
and book_id=1
</otherwise>
</choose>
</select>
set:
set用于更新的sql语句中
在update时,多条件更新,每个属性后面要加逗号“,”,这个时候可能会出现多一个“,”的情况,此时我们就可以使用set去掉后边的“,”,除此之外我们使用前面说的trim也可实现当前的操作,修改方法,假如实体类属性为空就不修改此属性所对于的字段
<update id="updateByPrimaryKeySelective" parameterType="mybatis01.model.Book" >
update t_book
<set >
<if test="bookName != null" >
book_name = #{bookName,jdbcType=VARCHAR},
</if>
<if test="bookNamePinyin != null" >
book_name_pinyin = #{bookNamePinyin,jdbcType=VARCHAR},
</if>
<if test="bookPrice != null" >
book_price = #{bookPrice,jdbcType=REAL},
</if>
<if test="bookType != null" >
book_type = #{bookType,jdbcType=VARCHAR},
</if>
</set>
where book_id = #{bookId,jdbcType=INTEGER}
</update>
where
用于管理 where 子句. 有如下功能:
1) 如果没有条件, 不会生成 where 关键字
2) 如果有条件, 会自动添加 where 关键字
3) 如果第一个条件中有 and, 自动去除之
<select id="queryBookWhere" resultType="mybatis01.model.Book">
select <include refid="Base_Column_List"/> from t_book
<where>
<if test="bookType!=null and bookType!=''">
and book_Type=#{bookType}
</if>
<if test="bookName!=null and bookName!=''">
and book_name=#{bookName}
</if>
</where>
</select>
2.模糊查询(3种方式)
<select id="queryBooklike" resultType="mybatis01.model.Book">
select <include refid="Base_Column_List"/> from t_book where 1=1
<if test="null!=bookType and ''!=bookType">
and book_type like #{bookType}
</if>
<if test="null!=bookName and ''!=bookName">
and book_name like '%${bookName}%'
</if>
<if test="null!=bookId and ''!=bookId">
and book_Id like concat('%',#{bookId},'%')
</if>
</select>
2.1 参数中直接加入%%
2.2 使用${...}代替#{...}(不建议使用该方式,有SQL注入风险)
参数类型为字符串,#会在前后加单引号['],$则直接插入值
注:
1) mybatis中使用OGNL表达式传递参数
2) 优先使用#{...}
3) ${...}方式存在SQL注入风险
MyBatis中#和$的区别
1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。
如:order by #user_id#,如果传入的值是111,那么解析成sql时的值为order by '111',
如果传入的值是id,则解析成的sql为order by "id".
2. $将传入的数据直接显示生成在sql中。
如:order by $user_id$,如果传入的值是111,那么解析成sql时的值为order by user_id,
如果传入的值是id,则解析成的sql为order by id.
3. #方式能够很大程度防止sql注入。
4. $方式无法防止Sql注入。
5. $方式一般用于传入数据库对象,例如传入表名.
6. 一般能用#的就别用$.
2.3 SQL字符串拼接CONCAT
3.查询返回结果集
resultMap:适合使用返回值是自定义实体类的情况
resultType:适合使用返回值的数据类型是非自定义的,即jdk的提供的类型
3.1 使用resultMap返回自定义类型集合
3.2 使用resultType返回List<T>
3.3 使用resultType返回单个对象
3.4 使用resultType返回List<Map>,适用于多表查询返回结果集
3.5 使用resultType返回Map<String,Object>,适用于多表查询返回单个结果集
Mapper接口
List<Book> queryMap();
Book queryBookByID(Integer bookId);
//Map和List<Map>集合适用于多表联查返回综合数据结果
Map<String,Object> querySingBookByMap(Integer bookId);
List<Map<String,Object>> querySingBookByMaps();
实现对应Mapper接口的xml
<select id="queryMap" resultMap="BaseResultMap">
select <include refid="Base_Column_List"/> from t_book
</select>
<select id="queryBookByID" resultType="mybatis01.model.Book">
select <include refid="Base_Column_List"/> from t_book where 1=1 and book_id=#{value}
</select>
<select id="querySingBookByMap" resultType="java.util.Map">
select <include refid="Base_Column_List"/> from t_book where 1=1 and book_id=#{bookId}
</select>
<select id="querySingBookByMaps" resultType="java.util.Map">
select <include refid="Base_Column_List"/> from t_book
</select>
4.分页查询
为什么要重写mybatis的分页?
Mybatis的分页功能很弱,它是基于内存的分页(查出所有记录再按偏移量offset和边界limit取结果),在大数据量的情况下这样的分页基本上是没有用的
4.1 导入分页插件
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.2</version>
</dependency>
4.2 将pagehelper插件配置到mybatis中
<!-- 配置分页插件PageHelper, 4.0.0以后的版本支持自动识别使用的数据库 -->
<plugin interceptor="com.github.pagehelper.PageInterceptor">
</plugin>
4.3 在你需要进行分页的Mybatis方法前调用PageHelper.startPage静态方法即可,紧跟在这个方法后的第一个Mybatis查询方法会被进行分页
//设置分页处理
if (null != pageBean && pageBean.isPaginate()) {
PageHelper.startPage(pageBean.getCurPage(), pageBean.getPageRecord());
}
4.4 获取分页信息(二种方式)
4.4.1 使用插件后,查询实际返回的是Page<E>,而非List<E>,Page继承了ArrayList,同时还包含分页相关的信息
Page<Book> page = (Page<Book>)list;
System.out.println("页码:" + page.getPageNum());
System.out.println("页大小:" + page.getPageSize());
System.out.println("总记录:" + page.getTotal());
4.4.2 使用PageInfo
PageInfo pageInfo = new PageInfo(list);
System.out.println("页码:" + pageInfo.getPageNum());
System.out.println("页大小:" + pageInfo.getPageSize());
System.out.println("总记录:" + pageInfo.getTotal());
分页测试
PageBean pageBean=new PageBean();
pageBean.setPage(2);
//判断是否分页
if (null != pageBean && pageBean.isPagination()) {
// 参数1:当前页码,参数2:每页条数
PageHelper.startPage(pageBean.getPage(), pageBean.getRows());
}
List<Book> 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);
}
5.特殊字符处理(xml文件中的sql语句中使用)
> (>)
< (<)
& (&)
空格( )
Mapper接口
示例七:范围查询,转义字符处理
List<Book> queryBookRange(BookVo bookvo);
实现对应Mapper接口的xml
<select id="queryBookRange" resultType="mybatis01.model.Book">
select <include refid="Base_Column_List"/> from t_book where 1=1
<if test="null!=min and ''!=min">
and book_price > #{min}
</if>
<if test="null!=max and ''!=max">
and book_price < #{max}
</if>
</select>
最后给一个方便使用对象赋值的一个插件
导入lombok插件
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
<scope>provided</scope>
</dependency>