Mybatis 学习笔记总结
Posted IT_Holmes
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mybatis 学习笔记总结相关的知识,希望对你有一定的参考价值。
文章目录
- 1. 动态SQL
- 2. 什么是缓存(Cache)? 缓存在架构中的作用?
- 3. Mybatis缓存
- 4. Mybatis 一级缓存
- 5. Mybatis 二级缓存
- 6. Mybatis 缓存原理
- 7. 自定义缓存
1. 动态SQL
1.1 什么是动态SQL?
什么是动态SQL?
- 动态SQL就是指根据不同的条件生成不同的SQL语句。
平时我们操作一些不同的sql语句,都是直接在代码上更改,很麻烦。通过Mybatis的动态SQL就很方便。
利用动态SQL这一特性可以彻底摆脱这种痛苦。
如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。
要学习的内容也就下面4个标签:
if
choose (when, otherwise)
trim (where, set)
foreach
1.2 准备工作
Blog实体类:
package com.itholmes.pojo;
import lombok.Data;
import java.util.Date;
@Data
public class Blog
private String id;
private String title;
private String author;
/*
对于这种驼峰命名,对应数据库的内容,我们可以在mybatis的核心配置文件的setting配置,mapUnderscoreToCamelCase为true.
*/
private Date createTime;
private int views;
创建一个IDUtils类,来获取UUId的一个字符串。将这个字符串作为Blog的id属性。
package com.itholmes.utils;
import org.junit.jupiter.api.Test;
import java.util.UUID;
public class IDUtils
public static String getUUId()
/*
UUID.randomUUID().toString()来生成一个uuid字符串。
注意:UUID是不会重复的!
*/
return UUID.randomUUID().toString().replaceAll("-","");
//测试uuid的效果。
@Test
public void test()
String uuId = IDUtils.getUUId();
String uuId2 = IDUtils.getUUId();
String uuId3 = IDUtils.getUUId();
System.out.println(uuId);
System.out.println(uuId2);
System.out.println(uuId3);
1.3 动态SQL之if语句
<select id="findActiveBlogWithTitleLike"
resultType="Blog">
SELECT * FROM BLOG
WHERE state = ‘ACTIVE’
<if test="title != null">
AND title like #title
</if>
</select>
结构就是:if标签加一个test属性,test属性中是字段名的一些限制语句啥的。
BlogMapper.xml文件:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itholmes.dao.BlogMapper">
<select id="queryBlogIF" parameterType="map" resultType="com.itholmes.pojo.Blog">
select * from mybatis.blog where 1=1
<if test="title != null">
and title = #title
</if>
<if test="author != null">
and author = #author
</if>
</select>
</mapper>
BlogMapper接口类:
package com.itholmes.dao;
import com.itholmes.pojo.Blog;
import java.util.List;
import java.util.Map;
public interface BlogMapper
//查询博客
List<Blog> queryBlogIF(Map map);
测试类:
import com.itholmes.dao.BlogMapper;
import com.itholmes.pojo.Blog;
import com.itholmes.utils.IDUtils;
import com.itholmes.utils.MybatisSqlSession;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
public class test
@Test
public void test2()
SqlSession sqlSession = MybatisSqlSession.getMybatisSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
HashMap map = new HashMap();
map.put("title","数据结构");
map.put("author","张三");
List<Blog> list = mapper.queryBlogIF(map);
for (Blog blog : list)
System.out.println(blog);
sqlSession.close();
1.4 动态SQL的trim(where , set)
where作用很关键,我们在执行一些动态SQL的语句时,可能会出现sql语句拼接的错误。如下:
作用:where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。
set的作用:set元素会动态前置SET关键字(update set语句的set关键字) ,同时会删除无关的逗号。
语句类似下面的效果:
<update id="updateBlog" parameterType="map">
update mybatis.blog
<set>
<if test="title != null">
title = #title,
</if>
<if test="author != null">
author = #author
</if>
</set>
where id = #id
</update>
trim元素有四个属性:
- prefix属性:给语句开头添加prefix的值。
- prefixOverrides属性:语句开头如果匹配到prefixOverrides属性值,就移除。
- suffix属性:给语句末尾添加suffix的值。
- suffixOverrides属性:语句末尾如果匹配到suffixOverrides属性值,就移除。
如下:
<update id="updateBlog" parameterType="map">
update mybatis.blog
<trim prefix="set" suffixOverrides="," suffix="where id = #id">
<if test="title != null">
title = #title,
</if>
<if test="author != null">
author = #author,
</if>
</trim>
</update>
1.5 动态SQL之 choose(when ,otherwise) 语句
<select id="findActiveBlogLike"
resultType="Blog">
SELECT * FROM BLOG WHERE state = ‘ACTIVE’
<choose>
<when test="title != null">
AND title like #title
</when>
<when test="author != null and author.name != null">
AND author_name like #author.name
</when>
<otherwise>
AND featured = 1
</otherwise>
</choose>
</select>
choose,when,otherwise。就类似Java代码中的switch,case,default。
BlogMapper.xml文件:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itholmes.dao.BlogMapper">
<select id="queryBlogChoose" parameterType="map" resultType="com.itholmes.pojo.Blog">
select * from mybatis.blog
<where>
<choose>
<when test="title != null">
-- 这里不需要and,因为第一个元素前面是where。
title = #title;
</when>
<when test="author != null">
and author = #author
</when>
<otherwise>
and views = #views
</otherwise>
</choose>
</where>
</select>
</mapper>
BlogMapper接口类:
package com.itholmes.dao;
import com.itholmes.pojo.Blog;
import java.util.List;
import java.util.Map;
public interface BlogMapper
//choose测试
List<Blog> queryBlogChoose(Map map);
测试类:
public void test3()
SqlSession sqlSession = MybatisSqlSession.getMybatisSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
HashMap map = new HashMap();
// map.put("title","数据结构");
// map.put("author","张三");
map.put("views",999);
List<Blog> list = mapper.queryBlogChoose(map);
for (Blog blog : list)
System.out.println(blog);
sqlSession.close();
1.6 动态SQL之 sql片段
有的时候,我们可能会将一些公共的部分抽取出来,方便复用。
第一步:使用sql标签定义公共部分。
<sql id="if-title-author">
<if test="title != null">
and title = #title
</if>
<if test="author != null">
and author = #author
</if>
</sql>
第二步:在需要使用的地方使用include标签引用即可。
<select id="queryBlogIF" parameterType="map" resultType="com.itholmes.pojo.Blog">
select * from mybatis.blog
<where>
<include refid="if-title-author"></include>
</where>
</select>
sql片段的注意事项:
- 最好基于单表来定义SQL片段。
- sql标签中,不要存在where标签。
1.7 动态SQL之 foreach 语句
foreach元素的作用:对集合进行遍历(尤其是在构建 IN 条件语句的时候)。
foreach很简单,对应他们的属性名就能理解如下:
<!--
使用foreach进行查询。
演示下面的语句:
select * from mybatis.blog where 1=1 and (id = 1 or id = 2 or id = 3);
这里接受的一个map,这个map中可以存一个集合。
-->
<select id="queryBlogForeach" parameterType="map" resultType="com.itholmes.pojo.Blog">
select * from mybatis.blog
<where>
<foreach collection="ids" item="id" open="and (" close=")" separator="or">
id = #id
</foreach>
</where>
</select>
2. 什么是缓存(Cache)? 缓存在架构中的作用?
我们查询数据时,首先需要连接数据库,拿到数据传到后台。这样我们每一次的查询结果,可以将它暂存到一个可以直接获取到的地方!那就是内存。而这种临时数据就是缓存了。
什么是缓存(Cache)?
- 存在内存中的临时数据。
- 将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,直接从缓存中查询,从而提高查询效率,解决
高并发系统的性能问题
。
对于架构方面的了解:
3. Mybatis缓存
4. Mybatis 一级缓存
4.1 准备工作 和 一级缓存的案例
User实体类:
package com.itholmes.pojo;
import lombok.Data;
@Data
@AllArgsConstructor
public class User
private int id;
private String name;
private String pwd;
UserMapper接口类:
package com.itholmes.dao;
import com.itholmes.pojo.User;
import org.apache.ibatis.annotations.Param;
public interface UserMapper
//查询指定id的用户给
User queryUsers(@Param("id") int a);
UserMapper.xml文件:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itholmes.dao.UserMapper">
<select id="queryUsers" parameterType="int" resultType="User">
select * from user where id = #id;
</select>
</mapper>
测试类:
import com.itholmes.dao.UserMapper;
import com.itholmes.pojo.User;
import com.itholmes.utils.MybatisSqlSession;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;
public class test
@Test
public void test()
SqlSession sqlSession = MybatisSqlSession.getMybatisSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user1 = mapper.queryUsers(1);
System.out.println(user1);
System.out.println("===================");
User user2 = mapper.queryUsers(1);
System.out.println(user2);
System.out.println("user1 和 user2 是否相等:" + (user1==user2));
sqlSession.close();
我们从执行结果得出,两次相同的查询,仅仅调用了一次sql,并且得到的对象相同(对象地址相同),这第二次查询就用到了缓存的效果。这里mybatis默认是开启一级缓存的。
4.2 一级缓存 失效(清理)的情况
缓存必须要有失效的情况(失效了,就要清理缓存),如果数据库的数据发生了变化,而缓存没有,这样拿到的数据就有大问题了!!
缓存失效的情况:
- 1.插叙不同的数据。
- 2.增删改操作,可能会改变原来的数据,所以必定会刷新缓存!!例如:
import com.itholmes.dao.Mybatis 学习笔记总结