Mybatis
缓存
一级缓存
-
定义及sqlSesson:
-
一级缓存定义:
一级缓存是mybatis基于
hashmap
实现的一个类,名字叫做PerpetualCache
(永久缓存)。 -
SqlSession
-
定义:
SqlSession
是mybatis的一个关键对象,代表了与数据库的一次会话。 -
作用:
mybatis通过
sqlSession
执行数据库操作,sqlSession
通过持有Executor
对象,提供了一系列方法,用于-
执行Sql语句:
Executor
持有的statementHandler
-
处理数据库操作的结果:
Executor
持有的resultHandler
-
负责数据库连接
-
事务提交和回滚:
Executor
持有的transactionHandler
-
缓存的处理:
Executor
持有的PerpetualCache
-
-
与一级缓存的关系:
一级缓存属于
sqlSession
级别,意思是,只要当前的sqlSession
会话没有关闭,当前会话下获取相同的数据,直接去本地缓存获取,不再查询数据库。 -
来源
sqlSession
是由sqlSessionFactory
进行创建的,sqlSessionFactory
是mybatis中管理sqlSession
的工厂类。
-
-
-
一级缓存失效的条件
一级缓存失效由于是基于
sqlSession
的,失效情况很容易猜想,-
会话已关闭,不是同一个sqlSession
-
查询条件不同,没有命中缓存
-
执行了增删改这种操作,刷新了缓存
-
手动清理了缓存
-
-
包含关系
一次会话包含了
sqlSession
对象,这个sqlSession
包含一个Executor
对象,Executor
对象持有缓存PerpetualCache
。会话结束后,这些东西全部被释放掉。
二级缓存
-
定义:
二级缓存是
mapper
这种映射级别的,也可以说是sqlSessionFactory
对象级别的缓存。意思是说,由同一个
sqlSessionFactory
创建出来的sqlSession
,在操作同一个xxxMapper
映射的sql语句时,都会共享缓存数据。换句话说,一次连接关闭了,缓存的数据不会被删掉。 -
开启步骤:二级缓存需要手动开启
-
在mybatis的配置文件/类中指定开启
-
xml方式开启
<settings> <!--开启二级缓存--> <setting name="cacheEnabled" value="true"/> </settings>
-
java配置类开启
-
不完全脱离xml的型式(因为有一些dataSource什么的可能写到xml中了)
SqlSessionFactoryBuilder().build()
,build()方法中传入inputStream
public class MyBatisConfig { public static SqlSessionFactory getSqlSessionFactory() throws IOException { // 先获取到一个xml文件配置 // 当然这个xml文件不一定完全满足SqlSessionFactoryBuilder().build(inputStream)时的要求 String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //配置是针对sqlSessionFactory进行配置的,配置之后,该工厂生产的所有sqlFactory都拥有相同的配置 Configuration configuration = sqlSessionFactory.getConfiguration(); // 开启二级缓存 configuration.setCacheEnabled(true); return sqlSessionFactory; } }
-
完全脱离xml的情况:
SqlSessionFactoryBuilder().build()
,build()方法中传入自己创建的configuration
。public class MyBatisConfig { public static SqlSessionFactory getSqlSessionFactory() { //创建一个数据库对象 DataSource dataSource = createDataSource(); //创建一个事务工厂,这个也是默认的事务管理器 TransactionFactory transactionFactory = new JdbcTransactionFactory(); //创建一个环境 Environment environment = new Environment("development", transactionFactory, dataSource); //创建一个配置,将环境绑定到配置上 org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration(environment); // 开启二级缓存 configuration.setCacheEnabled(true); return new SqlSessionFactoryBuilder().build(configuration); } private static DataSource createDataSource() { PooledDataSource dataSource = new PooledDataSource(); dataSource.setDriver("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/mydatabase"); dataSource.setUsername("username"); dataSource.setPassword("password"); return dataSource; } }
-
注:
mybatis-config.xml
指定的是sqlsessionFactory
的配置, -
-
还需要在
xxxMapper.xml
中声明使用二级缓存。<cache eviction="FIFO" #收回策略 flushInterval="6000" #刷新间隔 size="512" #引用数目 readOnly="true"/> #只读
-
还需要再
<select>
标签中声明使用二级缓存<select id="findById" parameterType="int" resultType="User" useCache="true" > select * from user where id = #{id} </select>
-
将pojo对象实现
Serializable
接口因为二级缓存存储介质多种多样
注:
-
只有关闭了
sqlSession
之后,才会将数据写到二级缓存中 -
二级缓存的过期时间不能手动设置
-
-
缓存的查询流程
先查询二级缓存,二级没查到,再去查询一级缓存,一级也没有,就去查数据库,sqlSession关闭之后,会写入到二级缓存中。
mybatis使用过程
-
首先读取
mybatis-config.xml
配置文件 -
将
mybatis-config.xml
变为数据流,通过sqlSessionFactoryBuilder.build()
的方式创建sqlSessionFactory
实例, -
通过
sqlSessionFactory
实例创建sqlSession
-
与数据库打交道
-
Executor
执行器完成和数据库的交互主要就是靠
Executor
执行器,这个是核心器。是由sqlSession
持有的。本身是一个接口,实现了这个接口的类中有几个关键的handler
:ParameterHandler
,负责处理 SQL 语句的参数,将参数设置到 SQL 语句中,并执行相应的预处理工作。StatementHandler
,负责处理 SQL 语句的执行过程,包括 SQL 语句的解析、编译和执行。ResultSetHandler
,负责处理 SQL 语句的执行结果,将数据库返回的结果集映射为 Java 对象,并提供相应的结果处理方法。TransactionHandler
, 负责管理数据库连接和事务的生命周期,包括事务的开启、提交、回滚等操作。
-
MappedStatement
-
功能:
StatementHandler
是负责执行MappedStatement
中描述的 SQL 语句的组件 -
定义:
MappedStatement
维护一条<select|update|delete|insert>
节点的封装。意思是,在 Mapper 文件(通常是 XML 格式的文件)中,通过 、、、 等标签来定义 SQL 语句,每个标签对应一个 MappedStatement 对象。
-
-
与数据库打交道的方式
-
使用传统的api方式:
传统API方式也包含两种方式,一种是将sql写入到
xxxmapper.xml
中,另一种是直接将Sql写到编码中-
sql写到
xxxmapper.xml
中需要两个内容statementId和查询参数,传递给
sqlSession
,由sqlSession
完成和数据库的交互// 获取 SqlSession 对象 SqlSession sqlSession = sqlSessionFactory.openSession(); // 执行查询操作,返回单个结果 Object result = sqlSession.selectOne("namespace.statementId", parameter); // 执行查询操作,返回结果列表 List<Object> resultList = sqlSession.selectList("namespace.statementId", parameter); // 执行删除操作 int rowsAffected = sqlSession.delete("namespace.statementId", parameter); // 提交事务 sqlSession.commit(); // 关闭 SqlSession 对象 sqlSession.close();
-
sql写到java代码中
// 构建 SqlSessionFactory SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build( Main.class.getResourceAsStream("mybatis-config.xml")); // 获取 SqlSession try (SqlSession sqlSession = sqlSessionFactory.openSession()) { // 定义 SQL 语句 String selectStatement = "SELECT * FROM users WHERE id = ?"; // 执行查询操作 User user = sqlSession.selectOne(selectStatement, 1); // 输出查询结果 System.out.println(user); }
-
-
使用mapper代理方式
-
配置文件方式
<!-- 这是单独的一个mapper --> <configuration> <mappers> <mapper resource="com/example/mapper/UserMapper.xml"/> </mappers> </configuration>
如果是多个mapper,那么:
<!-- mybatis-config.xml --> <configuration> <mappers> <!-- 批量扫描 com.example.mapper 包下的 Mapper 接口 --> <package name="com.example.mapper"/> </mappers> </configuration>
-
配置类方式
配置类进行配置可以使用
sqlSesionFactory
进行处理,也可以使用一个新的类,叫做:ConfigurationCustomizer
@Configuration //@MapperScan("com.example.mapper") 也可以直接在这里进行配置 public class MyBatisConfig { @Bean public ConfigurationCustomizer mybatisConfigurationCustomizer() { return new ConfigurationCustomizer() { @Override public void customize(Configuration configuration) { // 批量加载 Mapper 接口 configuration.addMappers("com.example.mapper"); } }; } }
public class MyBatisConfig { public SqlSessionFactory sqlSessionFactory() throws IOException { String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); Configuration configuration = sqlSessionFactory.getConfiguration(); configuration.addMappers("com.example.mapper"); return sqlSessionFactory; } }
-
-
-
mybatis的优化
- 引入日志文件
- 手动提交事务
- 缓存优化
- 延迟加载优化