Mybatis入门



img点击并拖拽以移动

1. 简介

1.1 什么是 MyBatis?

MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

img

点击并拖拽以移动

2. MyBatis工作机制

img

点击并拖拽以移动

下面就对图中的每一步流程进行详细讲解,具体如下。
(1)读取 MyBatis 配置文件mybatis-config.xml。mybatis-config.xml 作为MyBatis 的全局配置文件,配置了MyBatis的运行环境等信息,其中主要内容是获取数据库连接。

(2)加载映射文件Mapper.xml。Mapper.xml文件即SQL映射文件,该文件中配置了操作数据库的SQL语句,需要在mybatis-configxml中加载才能执行。mybatis-config.xml 可以加载多个配置文件,每个配置文件对应数据库中的一张表。

(3)构建会话工厂。通过MyBatis的环境等配置信息构建会话工厂SqlSessionFactory。

(4)创建 SqiSession 对象。由会话工厂创建SqlSession 对象,该对象中包含了执行 SQL的所有方法。

(5)MyBatis底层定义了一个Executor接口来操作数据库,它会根据SqlSession 传递的参数动态地生成需要执行的SQL语句,同时负责查询缓存的维护。

(6)在Executor 接口的执行方法中,包含一个MappedStatement类型的参数,该参数是对映射信息的封装,用于存储要映射的SQL语句的id、参数等。M Mapper.xml 文件中一个 SQL对应一个MappedStatement对象,SQL的id即是MappedStatem ent 的 id。

**(7)输入参数映射。在执行方法时,MappedStatement对象会对用户执行 SQL 语句的输入参数进行定义(可以定义为Map、List类型、基本类型和POJO类型),Executor执行器会通过MappedStatement对象在执行SQL前,将输入的Java对象映射到 SQL语句中。这里对输入参数的映射过程就类似于JDBC编程中对preparedStatement对象设置参数的过程。

(8)输出结果映射。在数据库中执行完SQL语句后,Mapped Statement 对象会对SQL执行输出的结果进行定义(可以定义为Map和List类型、基本类型、 POJO类型),Executor执行 器会通过MappedStatement对象在执行SQL语句后,将输出结果映射至Java对象中。这种将输出结果映射到Java对象的过程就类似于JDBC编程中对结果的解析处理过程。 通过上面对MyBatis框架执行流程的讲解,相信对MyBati 框架已经有了一个初步的了 解。**

对于初学者来说,上面所讲解的内容可能不会完全理解,现阶段也不要求完全理解这里讲解MyBatis框架的执行过程是为了方便后面程序的学习。在学习完 MyBatis框架后,自然就会明白上面所讲解的内容了。

3. Mybatis入门

3.1 安装

要使用 MyBatis, 只需将 mybatis-x.x.x.jar 文件置于类路径(classpath)中即可。

如果使用 Maven 来构建项目,则需将下面的依赖代码置于 pom.xml 文件中:

1
2
3
4
5
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>x.x.x</version> //版本号
</dependency>

点击并拖拽以移动

3.2 从 XML 中构建 SqlSessionFactory

每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先配置的 Configuration 实例来构建出 SqlSessionFactory 实例。

从 XML 文件中构建 SqlSessionFactory 的实例非常简单,建议使用类路径下的资源文件进行配置。 但也可以使用任意的输入流(InputStream)实例,比如用文件路径字符串或 file:// URL 构造的输入流。MyBatis 包含一个名叫 Resources 的工具类,它包含一些实用方法,使得从类路径或其它位置加载资源文件更加容易。

1
2
3
String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

点击并拖拽以移动

XML 配置文件中包含了对 MyBatis 系统的核心设置,包括获取数据库连接实例的数据源(DataSource)以及决定事务作用域和控制方式的事务管理器(TransactionManager)。后面会再探讨 XML 配置文件的详细内容,这里先给出一个简单的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
</configuration>

点击并拖拽以移动

3.3 不使用 XML 构建 SqlSessionFactory

如果你更愿意直接从 Java 代码而不是 XML 文件中创建配置,或者想要创建你自己的配置建造器,MyBatis 也提供了完整的配置类,提供了所有与 XML 文件等价的配置项。

当然,还有很多可以在 XML 文件中配置的选项,上面的示例仅罗列了最关键的部分。 注意 XML 头部的声明,它用来验证 XML 文档的正确性。environment 元素体中包含了事务管理和连接池的配置。mappers 元素则包含了一组映射器(mapper),这些映射器的 XML 映射文件包含了 SQL 代码和映射定义信息。

1
2
3
4
5
6
DataSource dataSource = BlogDataSourceFactory.getBlogDataSource();
TransactionFactory transactionFactory = new JdbcTransactionFactory();
Environment environment = new Environment("development", transactionFactory, dataSource);
Configuration configuration = new Configuration(environment);
configuration.addMapper(BlogMapper.class);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);

点击并拖拽以移动

3.4 从 SqlSessionFactory 中获取 SqlSession

既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。

1
2
3
try (SqlSession session = sqlSessionFactory.openSession()) {
Blog blog = (Blog) session.selectOne("org.mybatis.example.BlogMapper.selectBlog", 101);
}

点击并拖拽以移动

这种方式能够正常工作,对使用旧版本 MyBatis 的用户来说也比较熟悉。但现在有了一种更简洁的方式——使用和指定语句的参数和返回值相匹配的接口(比如 BlogMapper.class),现在你的代码不仅更清晰,更加类型安全,还不用担心可能出错的字符串字面值以及强制类型转换。

例如:

1
2
3
4
try (SqlSession session = sqlSessionFactory.openSession()) {
BlogMapper mapper = session.getMapper(BlogMapper.class);
Blog blog = mapper.selectBlog(101);
}

点击并拖拽以移动

3.5 作用域(Scope)和生命周期

理解我们之前讨论过的不同作用域和生命周期类别是至关重要的,因为错误的使用会导致非常严重的并发问题。


提示 对象生命周期和依赖注入框架

依赖注入框架可以创建线程安全的、基于事务的 SqlSession 和映射器,并将它们直接注入到你的 bean 中,因此可以直接忽略它们的生命周期。 如果对如何通过依赖注入框架使用 MyBatis 感兴趣,可以研究一下 MyBatis-Spring 或 MyBatis-Guice 两个子项目。


SqlSessionFactoryBuilder

这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。 因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)。 你可以重用 SqlSessionFactoryBuilder 来创建多个 SqlSessionFactory 实例,但最好还是不要一直保留着它,以保证所有的 XML 解析资源可以被释放给更重要的事情。

SqlSessionFactory

SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。 使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏习惯”。因此 SqlSessionFactory 的最佳作用域是应用作用域。 有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。

SqlSession

每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。 绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。 也绝不能将 SqlSession 实例的引用放在任何类型的托管作用域中,比如 Servlet 框架中的 HttpSession。 如果你现在正在使用一种 Web 框架,考虑将 SqlSession 放在一个和 HTTP 请求相似的作用域中。 换句话说,每次收到 HTTP 请求,就可以打开一个 SqlSession,返回一个响应后,就关闭它。 这个关闭操作很重要,为了确保每次都能执行关闭操作,你应该把这个关闭操作放到 finally 块中。 下面的示例就是一个确保 SqlSession 关闭的标准模式:

1
2
3
try (SqlSession session = sqlSessionFactory.openSession()) {
// 你的应用逻辑代码
}

点击并拖拽以移动

在所有代码中都遵循这种使用模式,可以保证所有数据库资源都能被正确地关闭。

映射器实例

映射器是一些绑定映射语句的接口。映射器接口的实例是从 SqlSession 中获得的。虽然从技术层面上来讲,任何映射器实例的最大作用域与请求它们的 SqlSession 相同。但方法作用域才是映射器实例的最合适的作用域。 也就是说,映射器实例应该在调用它们的方法中被获取,使用完毕之后即可丢弃。 映射器实例并不需要被显式地关闭。尽管在整个请求作用域保留映射器实例不会有什么问题,但是你很快会发现,在这个作用域上管理太多像 SqlSession 的资源会让你忙不过来。 因此,最好将映射器放在方法作用域内。就像下面的例子一样:

1
2
3
4
try (SqlSession session = sqlSessionFactory.openSession()) {
BlogMapper mapper = session.getMapper(BlogMapper.class);
// 你的应用逻辑代码
}

点击并拖拽以移动

4. XML的配置

4.1 配置

MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。 配置文档的顶层结构如下:

属性(properties)这些属性可以在外部进行配置,并可以进行动态替换

1
2
3
4
<properties resource="org/mybatis/example/config.properties">
<property name="username" value="dev_user"/>
<property name="password" value="F2Fa3!33TYyg"/>
</properties>

点击并拖拽以移动

动态配置的属性值

1
2
3
4
5
6
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>

点击并拖拽以移动

4.2 类型别名

类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。例如:

1
2
3
4
5
6
7
8
<typeAliases>
<typeAlias alias="Author" type="domain.blog.Author"/>
<typeAlias alias="Blog" type="domain.blog.Blog"/>
<typeAlias alias="Comment" type="domain.blog.Comment"/>
<typeAlias alias="Post" type="domain.blog.Post"/>
<typeAlias alias="Section" type="domain.blog.Section"/>
<typeAlias alias="Tag" type="domain.blog.Tag"/>
</typeAliases>

点击并拖拽以移动

如果你想限定包名

1
2
3
<typeAliases>
<package name="domain.blog"/>
</typeAliases>

点击并拖拽以移动

注册实体类名

1
2
3
4
@Alias("author")
public class Author {
...
}

点击并拖拽以移动

使用别名的好处

降低冗余,避免出现名称过程导致的错误

5. XML映射器

5.1 select,insert,update 和 delete

MyBatis 的真正强大在于它的语句映射,这是它的魔力所在。由于它的异常强大,映射器的 XML 文件就显得相对简单。如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% 的代码。MyBatis 致力于减少使用成本,让用户能更专注于 SQL 代码。

SQL 映射文件只有很少的几个顶级元素(按照应被定义的顺序列出):

  • cache – 该命名空间的缓存配置。
  • cache-ref – 引用其它命名空间的缓存配置。
  • resultMap – 描述如何从数据库结果集中加载对象,是最复杂也是最强大的元素。
  • parameterMap – 老式风格的参数映射。此元素已被废弃,并可能在将来被移除!请使用行内参数映射。文档中不会介绍此元素。
  • sql – 可被其它语句引用的可重用语句块。
  • insert – 映射插入语句。
  • update – 映射更新语句。
  • delete – 映射删除语句。
  • select – 映射查询语句。

构建mybatis项目

img点击并拖拽以移动

导入必要的maven

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>

</dependencies>

点击并拖拽以移动

mysql和mybatis一定要导入的

创建Database

img点击并拖拽以移动

创建interface(不要忘了创建实体类)

img点击并拖拽以移动

在UserMapper.xml写入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?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="com.dao.UserMapper">
<select id="selectUser" resultType="com.pojo.User">
select * from user
</select>
<select id="selectUserById" resultType="com.pojo.User">
select * from user where id = #{id}
</select>
<select id="selectUserByNP2" parameterType="map" resultType="com.pojo.User">
select * from user where name = #{username} and pwd = #{pwd}
</select>
<insert id="addUser" parameterType="com.pojo.User">
insert into user (id,name,pwd) values (#{id},#{name},#{pwd})
</insert>
<update id="updateUser" parameterType="com.pojo.User">
update user set name=#{name},pwd=#{pwd} where id = #{id}
</update>
<delete id="deleteUser" parameterType="int">
delete from user where id = #{id}
</delete>
<select id="getlike" resultType="com.pojo.User" >
select * from user where name like #{value}
</select>

</mapper>

点击并拖拽以移动

在核心配置文mybatis-config.xml件中加入资源路径

1
2
3
<mappers>
<mapper resource="com/dao/userMapper.xml"/>
</mappers>

点击并拖拽以移动

文件全部如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=utf8"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/dao/userMapper.xml"/>
</mappers>
</configuration>

点击并拖拽以移动

配置JDBC连接池

1
2
3
4
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/数据库名?useSSL=true&useUnicode=true&characterEncoding=utf8
username=用户名
password=密码

点击并拖拽以移动

开始测试

导入实体类简化测试代码,无需多次构造sqlSessionFactory

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class MybatisUtils {

private static SqlSessionFactory sqlSessionFactory;
static {
try {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}

//获取SqlSession连接
public static SqlSession getSession(){
return sqlSessionFactory.openSession();
}

}

点击并拖拽以移动

测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
@Test
public void selectUser() {
SqlSession session = MybatisUtils.getSession();
//方法一:
//List<User> users = session.selectList("com.kuang.mapper.UserMapper.selectUser");
//方法二:
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> users = mapper.selectUser();

for (User user: users){
System.out.println(user);
}
session.close();
}

@Test
public void tsetSelectUserById() {
SqlSession session = MybatisUtils.getSession(); //获取SqlSession连接
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.selectUserById(1);
System.out.println(user);
session.close();
}

@Test
public void testAddUser() {
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = new User(9,"大五","zxcvbn");
int i = mapper.addUser(user);
System.out.println(i);
session.commit(); //提交事务,重点!不写的话不会提交到数据库
session.close();
}

@Test
public void testUpdateUser() {
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.selectUserById(1);
user.setPwd("asdfgh");
int i = mapper.updateUser(user);
System.out.println(i);
session.commit(); //提交事务,重点!不写的话不会提交到数据库
session.close();
}

@Test
public void testDeleteUser() {
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
int i = mapper.deleteUser(5);
System.out.println(i);
session.commit(); //提交事务,重点!不写的话不会提交到数据库
session.close();
}

@Test
public void getLike() {
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> userlist= mapper.getlike("%李%");

for (User user: userlist){
System.out.println(user);
}
session.close();
}

点击并拖拽以移动

测试一下

User{id=1, name=’哈登’, pwd=’abcdef’}
User{id=2, name=’库里’, pwd=’987654’}
User{id=3, name=’保留’, pwd=’asddd’}
User{id=4, name=’乔治’, pwd=’zxcvbn’}
User{id=5, name=’詹姆斯’, pwd=’zsdsdzd’}

Process finished with exit code 0

User{id=1, name=’哈登’, pwd=’abcdef’}

Process finished with exit code 0

img点击并拖拽以移动

5.2 主要元素

img

点击并拖拽以移动

5.3 缓存 [ Cache ]

简介

1、什么是缓存 [ Cache ]?

  • 存在内存中的临时数据。
  • 将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题。

2、为什么使用缓存?

  • 减少和数据库的交互次数,减少系统开销,提高系统效率。

3、什么样的数据能使用缓存?

  • 经常查询并且不经常改变的数据。

mybatis缓存

MyBatis的一级缓存是SqlSession级别的缓存。在操作数据库时需要构造Sqlsession。
在对象中有一个HashMap用于存储缓存数据。不同的 SqlSession 之间的缓存数据区域
(HashMap)是互相不影响的。
一级缓存的作用域是SqlSession范围的,当在同一个 qlSession 中执行两次相同的sql语
句时,第一次执行完毕会将数据库中查询的数据写到缓存 (内存),第二次查询时会从缓存中
获取数据,不再去底层数据库查询,从而提高查询效率。需要注意的是,如果SqlSession执行
了DML操作(insert、update和delete),并提交到数据库 MyBatis 则会清空 SqlSession 中的
一级缓存,这样做的目的是为了保证缓存中存储的是最新的信息,避免出现脏读现象。
当一个SqlSession 结束后该SqlSession 中的一级缓存也就不存在了。Mybatis默认开启一级缓存,不需要进行任何配置。

注意:Mybatis的缓存机制的基于id进行的缓存,也就是说Mybatis使用HashMap缓存数据时,是使用对象id作为key的,而对象作为value保存的。

5.4 一级缓存

示例 mybatisCache

mybatisCache/src/java/Mapper

1
2
3
4
5
6
7
8
public interface UserMapper {
User selectUseById(int id);

List<User> selectAllUser();

void deleteUserById(int id);

}

点击并拖拽以移动

mybatisCache/src/java/Mapper

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?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="Mapper.UserMapper">
<!--根据id查询user-->
<select id="selectUseById" resultType="domain.User"
parameterType="int">
SELECT * FROM tb_cache WHERE id = #{id}
</select>
<!--查询所有user-->
<select id="selectAllUser" resultType="domain.User"
parameterType="int">
SELECT *FROM tb_cache
</select>
<!--根据id删除User-->
<delete id="deleteUserById" parameterType="int">
DELETE FROM tb_cache WHERE id = #{id}
</delete>
</mapper>

点击并拖拽以移动

mybatisCache/src/java/domain

1
2
3
4
5
6
7
@Data
public class User {
private int id;
private String NAME;
private String age;
private String sex;
}

点击并拖拽以移动

mybatisCache/test/java/Testcache

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Testcache {
@Test
public void test1(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper um=sqlSession.getMapper(UserMapper.class);
//执行delete操作
User user=um.selectUseById(1);
System.out.println(user);
//commit提交
User user1=um.selectUseById(1);
System.out.println(user1);
sqlSession.close();
}

}

点击并拖拽以移动

img点击并拖拽以移动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Test
public void test2(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper um=sqlSession.getMapper(UserMapper.class);

User user=um.selectUseById(1);
System.out.println(user);
//执行delete操作
um.deleteUserById(3);
//commit提交
sqlSession.commit();
//再次执行查询,DML操作会清空sqlSession缓存,所以会再次执行selet语句

User user2=um.selectUseById(1);
System.out.println(user2);
sqlSession.close();
}

点击并拖拽以移动

img点击并拖拽以移动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Test
public void test3(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper um=sqlSession.getMapper(UserMapper.class);
User user=um.selectUseById(1);
System.out.println(user);
//关闭一级缓存
sqlSession.close();
//再次获得UserMapping对象
sqlSession=MybatisUtils.getSqlSession();
UserMapper UM=sqlSession.getMapper(UserMapper.class);
User user1=UM.selectUseById(2);
System.out.println(user1);
sqlSession.close();
}

点击并拖拽以移动

img点击并拖拽以移动

5.5 二级缓存

cache元素用来开启当前mapper的namespace下的二级缓存。该元素的属性设置如下:

flushInterval。刷新间隔。可以被设置为任意的正整数,而且它们代表一个合理的毫秒式的时间段。默认情况下是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新>size。缓存数目。可以被设置为任意正整数,要记住你缓存的对象数目和你运行环的可用内存资源数目。默认值是1024。

readOnly。只读。属性可以被设置为true或false。只读的缓存会给所有调用者返回存对象的相同实例,因此这些对象不能被修改。这提供了很重要的性能优势。可读的缓存会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认 false。

eviction。收回策略,默认为LRU。有如下几种:
。LRU。最近最少使用的策略,移除最长时间不被使用的对象。 FIFO。先进先出策略,按对象进入缓存的顺序来移除它们。

SOFT。软引用策略,移除基于垃圾回收器状态和软引用规则的对象。

WEAK。弱引用策略,更积极地移除基于垃圾收集器状态和弱引用规则的对象cache元素用来开启当前mapper的namespace下的二级缓存。该元素的属性设置如下>flushInterval。刷新间隔。可以被设置为任意的正整数,而且它们代表一个合理的毫秒式的时间段。默认情况下是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新

size。缓存数目。可以被设置为任意正整数,要记住你缓存的对象数目和你运行环的可用内存资源数目。默认值是1024。

readOnly。只读。属性可以被设置为true或false。只读的缓存会给所有调用者返回存对象的相同实例,因此这些对象不能被修改。这提供了很重要的性能优势。可读的缓存会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认 false。

eviction。收回策略,默认为LRU。有如下几种:
。LRU。最近最少使用的策略,移除最长时间不被使用的对象。 FIFO。先进先出策略,按对象进入缓存的顺序来移除它们。
SOFT。软引用策略,移除基于垃圾回收器状态和软引用规则的对象。
WEAK。弱引用策略,更积极地移除基于垃圾收集器状态和弱引用规则的对象。

mybatisCache/src/mybatis-config.xml

1
2
3
4
<settings>
<!--开启二级缓存-->
<setting name="cacheEnabled" value="true"/>
</settings>

点击并拖拽以移动

mybatisCache/src/Mapper/UserMapper.xml

1
2
3
<!--开启当前mapper的namespace下的二级缓存-->
<cache eviction="LRU" flushInterval="60000"
size="512" readOnly="true"/>

点击并拖拽以移动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Test
public void test4(){
//获取sqlseesion对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
//查询id为1的User对象
UserMapper um=sqlSession.getMapper(UserMapper.class);
//查询id为1的对象
User user=um.selectUseById(1);
System.out.println(user);
//执行delete操作
um.deleteUserById(2);
//commit提交
sqlSession.commit();
//再次查询id为1的对象,DML操作会清空sqlsession缓存,所以会再次执行select
User user1=um.selectUseById(1);
System.out.println(user1);
//关闭Sqlsession对象
sqlSession.close();
}

点击并拖拽以移动

img点击并拖拽以移动

参考mybatis – MyBatis 3 | 简介


Mybatis入门
https://1902756969.github.io/Hexo/2021/12/23/sql/Mybatis入门/
作者
发布于
2021年12月23日
许可协议