域名弄好了网站怎么建设,宁波中科网站建设有限公司,北京专业网站优化,企业信息的网站1、二级缓存使用
在 MyBatis 中默认二级缓存是不开启的#xff0c;如果要使用需手动开启。在 mybatis-config.xml 配置文件中设置 cacheEnabled true #xff0c;配置如下#xff1a;
?xml version1.0 encodingUTF-8 ?
!DOCTYPE c…1、二级缓存使用
在 MyBatis 中默认二级缓存是不开启的如果要使用需手动开启。在 mybatis-config.xml 配置文件中设置 cacheEnabled true 配置如下
?xml version1.0 encodingUTF-8 ?
!DOCTYPE configurationPUBLIC -//mybatis.org//DTD Config 3.0//ENhttp://mybatis.org/dtd/mybatis-3-config.dtd
configuration!--对应的设置都在 Configuration 配置类保存着直接点进源码查看即可--settings!--开启二级缓存--setting namecacheEnabled valuetrue/setting namelazyLoadingEnabled valuetrue/setting namemultipleResultSetsEnabled valuetrue/setting nameuseColumnLabel valuetrue/setting nameuseGeneratedKeys valuefalse/setting nameautoMappingBehavior valuePARTIAL/!--修改默认 SQL 执行器,默认是 SIMPLE,但是修改成 REUSE 会好一点点这也是数据库优化的一个关键之处--setting namedefaultExecutorType valueREUSE/setting namedefaultStatementTimeout value25/setting namesafeRowBoundsEnabled valuefalse/setting namemapUnderscoreToCamelCase valuefalse/!--修改作用域查看 LocalCacheScope 枚举值修改成 STATEMENT 之后一级缓存失效但是不一定没用一级缓存只是作用域缩小了而已后面的嵌套、子查询就用到了一级缓存--setting namelocalCacheScope valueSESSION/setting namejdbcTypeForNull valueOTHER/setting namelazyLoadTriggerMethods valueequals,clone,hashCode,toString//settingspluginsplugin interceptororg.apache.ibatis.gwmtest.plugin.MyPageInterceptor/plugin/pluginsenvironments defaultdevelopmentenvironment iddevelopmenttransactionManager typeJDBC/dataSource typePOOLEDproperty namedriver valuecom.mysql.cj.jdbc.Driver/property nameurl valuejdbc:mysql://localhost:3306/gwmdb?useSSLfalse/property nameusername valueroot/property namepassword valueitsme999//dataSource/environment/environmentsmappersmapper resourcemapper/PersonMapper.xml//mappers/configuration
或者通过 Configuration 配置方式修改调用 configuration.setCacheEnabled(true) 代码如下
public class MyBatisCacheTest {private static SqlSessionFactory sqlSessionFactory;private static Configuration configuration;private static JdbcTransaction jdbcTransaction;private static Connection connection;private static final String resource /mybatis-config.xml;private static MappedStatement mappedStatement;private static SqlSession sqlSession;private static SqlSession sqlSession2;static {try {InputStream inputStream MyBatisCacheTest.class.getResourceAsStream(resource);sqlSessionFactory new SqlSessionFactoryBuilder().build(inputStream);configuration sqlSessionFactory.getConfiguration();configuration.setCacheEnabled(true);connection DriverManager.getConnection(jdbc:mysql://localhost:3306/gwmdb?useSSLfalseallowPublicKeyRetrievaltrue, root, itsme999);jdbcTransaction new JdbcTransaction(connection);String statement org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson;mappedStatement configuration.getMappedStatement( statement);// 注意这里设置了自动提交sqlSession sqlSessionFactory.openSession(true);sqlSession2 sqlSessionFactory.openSession(true);} catch (Exception e) {e.printStackTrace();}}
}记得打开开关之后该如何使用二级缓存有两种方式注解式、xml 配置、注解配置结合体提前准备两个文件 PersonMapper.xml 和 PersonMapper 接口。
1、使用注解缓存—CacheNamespace
直接在 PersonMapper 接口上面添加注解 CacheNamespace通过 CacheNamespace 设置缓存命名空间这个注解一加上就相当于在 PersonMapper 接口文件中准备好一个二级缓存代码如下
CacheNamespace
public interface PersonMapper {Select(select id,user_name as userName,age as age from test_user where id #{myId})Person getPerson(Param(myId) Integer id);
}
使用代码如下 public static void main(String[] args) throws Exception {PersonMapper mapper sqlSession.getMapper(PersonMapper.class);Person person mapper.getPerson(1);sqlSession.commit();Person person1 mapper.getPerson(1);System.out.println(personperson1 (person person1));}
这里一定要注意二级缓存必须要显示提交才能够命中。否则二级缓存命中率为 0.0 为什么后面源码中会分析最终输出结果如下
2023-02-16 14:31:37,201 DEBUG [main] -org.apache.ibatis.transaction.jdbc.JdbcTransaction Opening JDBC Connection
2023-02-16 14:31:37,216 DEBUG [main] -org.apache.ibatis.datasource.pooled.PooledDataSource Created connection 19986569.
2023-02-16 14:31:37,222 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson Preparing: select id,user_name as userName,age as age from test_user where id ?
2023-02-16 14:31:37,276 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson Parameters: 1(Integer)
2023-02-16 14:31:37,350 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson Total: 1
2023-02-16 14:31:37,364 WARN [main] -org.apache.ibatis.io.SerialFilterChecker As you are using functionality that deserializes object streams, it is recommended to define the JEP-290 serial filter. Please refer to https://docs.oracle.com/pls/topic/lookup?ctxjavase15idGUID-8296D8E8-2B93-4B9A-856E-0A65AF9B8C66
2023-02-16 14:31:37,369 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper Cache Hit Ratio [org.apache.ibatis.gwmtest.dao.PersonMapper]: 0.5
personperson1 false
会看到 Cache Hit Ratio 命中率为 0.5说明已经命中二级缓存。但是发现最终personperson1 false 这个是因为反序列化重新生成一个 Person 类型实例。肯定是完全两个不同的实例。就比如网络传输 Person接受端生成的 Person 能和你发送端 Person 实例一样嘛。
注意此时是在 PersonMapper 加上CacheNamespace 注解相当于二级缓存是在 PersonMapper 接口上准备好了。并且测试时查询使用的也是 Select 注解方式并且测试使用的时同一个 SqlSession现在准备弄两个不同 SqlSession 在测试一下代码如下 public static void main(String[] args) throws Exception {PersonMapper mapper sqlSession.getMapper(PersonMapper.class);PersonMapper mapper1 sqlSession2.getMapper(PersonMapper.class);Person person mapper.getPerson(1);sqlSession.commit();Person person1 mapper1.getPerson(1);mapper.getPerson(1);System.out.println(personperson1 (person person1));}
运行结果
2023-02-16 15:11:27,441 DEBUG [main] -org.apache.ibatis.transaction.jdbc.JdbcTransaction Opening JDBC Connection
2023-02-16 15:11:27,453 DEBUG [main] -org.apache.ibatis.datasource.pooled.PooledDataSource Created connection 19986569.
2023-02-16 15:11:27,460 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson Preparing: select id,user_name as userName,age as age from test_user where id ?
2023-02-16 15:11:27,511 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson Parameters: 1(Integer)
2023-02-16 15:11:27,572 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson Total: 1
2023-02-16 15:11:27,586 WARN [main] -org.apache.ibatis.io.SerialFilterChecker As you are using functionality that deserializes object streams, it is recommended to define the JEP-290 serial filter. Please refer to https://docs.oracle.com/pls/topic/lookup?ctxjavase15idGUID-8296D8E8-2B93-4B9A-856E-0A65AF9B8C66
2023-02-16 15:11:27,592 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper Cache Hit Ratio [org.apache.ibatis.gwmtest.dao.PersonMapper]: 0.5
2023-02-16 15:11:27,592 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper Cache Hit Ratio [org.apache.ibatis.gwmtest.dao.PersonMapper]: 0.6666666666666666
personperson1 false
发现还是可以命中二级缓存这就可以在多线程下不同 SqlSession 同时访问二级缓存提高查询效率。
现在准备在 PesonMapper 接口中再添加一个查询方法 getPerson2()该方法不再使用 Select 方式代码如下
CacheNamespace
public interface PersonMapper {Select(select id,user_name as userName,age as age from test_user where id #{666})Person getPerson(Integer id);Person getPerson2(Integer id);
}然后再 PesonMapper.xml 配置文件中实现该方法配置如下
?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtd
mapper namespaceorg.apache.ibatis.gwmtest.dao.PersonMapperselect idgetPerson2 resultTypeorg.apache.ibatis.gwmtest.entity.Personselect id,user_name as userName,age as age from test_user where id #{666}/select
/mapper
然后测试代码如下 public static void ma333in(String[] args) throws Exception {PersonMapper mapper sqlSession.getMapper(PersonMapper.class);PersonMapper mapper1 sqlSession2.getMapper(PersonMapper.class);Person person mapper.getPerson2(1);sqlSession.commit();Person person1 mapper1.getPerson2(1);System.out.println(personperson1 (person person1));}
输出结果
2023-02-16 15:22:07,088 DEBUG [main] -org.apache.ibatis.transaction.jdbc.JdbcTransaction Opening JDBC Connection
2023-02-16 15:22:07,102 DEBUG [main] -org.apache.ibatis.datasource.pooled.PooledDataSource Created connection 1487470647.
2023-02-16 15:22:07,108 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson2 Preparing: select id,user_name as userName,age as age from test_user where id ?
2023-02-16 15:22:07,159 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson2 Parameters: 1(Integer)
2023-02-16 15:22:07,200 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson2 Total: 1
2023-02-16 15:22:07,202 DEBUG [main] -org.apache.ibatis.transaction.jdbc.JdbcTransaction Opening JDBC Connection
2023-02-16 15:22:07,210 DEBUG [main] -org.apache.ibatis.datasource.pooled.PooledDataSource Created connection 1796371666.
2023-02-16 15:22:07,210 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson2 Preparing: select id,user_name as userName,age as age from test_user where id ?
2023-02-16 15:22:07,211 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson2 Parameters: 1(Integer)
2023-02-16 15:22:07,212 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson2 Total: 1
personperson1 false
发现没有命中二级缓存因为不同 SqlSession所以一级缓存也没有命中。为什么没有命中二级缓存明明在开启了二级缓存但是你要知道二级缓存是在哪里开启的是在 PersonMapper 接口上注意是接口文件上PersonMapper.xml 资源文件中压根没有开启二级缓存所以你使用 PersonMapper.xml 配置中的方法肯定命中不了二级缓存。那么要怎么才能够让他使用到 PersonMapper 接口上二级缓存呢可以使用 cache-ref 标签代码如下
?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtd
mapper namespaceorg.apache.ibatis.gwmtest.dao.PersonMappercache-ref namespaceorg.apache.ibatis.gwmtest.dao.PersonMapper/select idgetPerson2 resultTypeorg.apache.ibatis.gwmtest.entity.Personselect id,user_name as userName,age as age from test_user where id #{666}/select
/mappercache-ref 标签中 namespace 属性可以引用到 PersonMapper 接口上配置二级缓存。最后测试可以命中二级缓存。
以上就是通过 CacheNamespace 注解使用二级缓存的步骤。通知也要注意 Mapper 接口和 Mapper 配置文件中准备的二级缓存不是同一个要使用同一个就需要互相进行引入。 cache-ref 标签就是用于配置文件中引入接口中配置的二级缓存。
2、使用 xml 配置缓存
直接在 PersonMapper.xml 配置中加上 cache/ 标签相当于在 PersonMapper.xml 配置中准备好一个二级缓存和上面注解式的不一样上面是在 PersonMapper 接口中准备二级缓存两个缓存是一样的可以互相引用配置如下
?xml version1.0 encodingUTF-8 ?
!DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtd
mapper namespaceorg.apache.ibatis.gwmtest.dao.PersonMapperselect idgetPerson2 resultTypeorg.apache.ibatis.gwmtest.entity.Personselect id,user_name as userName,age as age from test_user where id #{666}/select
/mapper
对应 PersonMapper 接口代码如下 public interface PersonMapper {Select(select id,user_name as userName,age as age from test_user where id #{666})Person getPerson(Integer id);Person getPerson2(Integer id);
}注意此时不要用 CacheNamespace 注解因为在 xml 中已经通过 cache/ 标签准备好二级缓存所以这里不能再去构建一个二级缓存会冲突报错错误如下
Caused by: java.lang.IllegalArgumentException: Caches collection already contains value for org.apache.ibatis.gwmtest.dao.PersonMapperat org.apache.ibatis.session.Configuration$StrictMap.put(Configuration.java:1021)at org.apache.ibatis.session.Configuration$StrictMap.put(Configuration.java:977)at org.apache.ibatis.session.Configuration.addCache(Configuration.java:713)at org.apache.ibatis.builder.MapperBuilderAssistant.useNewCache(MapperBuilderAssistant.java:140)at org.apache.ibatis.builder.annotation.MapperAnnotationBuilder.parseCache(MapperAnnotationBuilder.java:190)at org.apache.ibatis.builder.annotation.MapperAnnotationBuilder.parse(MapperAnnotationBuilder.java:121)at org.apache.ibatis.binding.MapperRegistry.addMapper(MapperRegistry.java:72)at org.apache.ibatis.session.Configuration.addMapper(Configuration.java:848)at org.apache.ibatis.builder.xml.XMLMapperBuilder.bindMapperForNamespace(XMLMapperBuilder.java:432)at org.apache.ibatis.builder.xml.XMLMapperBuilder.parse(XMLMapperBuilder.java:97)at org.apache.ibatis.builder.xml.XMLConfigBuilder.mapperElement(XMLConfigBuilder.java:378)at org.apache.ibatis.builder.xml.XMLConfigBuilder.parseConfiguration(XMLConfigBuilder.java:120)
提示你已经存在缓存你可以直接引用但是你不要再重新准备可以使用 CacheNamespaceRef 注解引入在此之前先接着测试下能不能命中二级缓存。
定义好了 PersonMapper 接口和 PersonMapper.xml 之后开始测试先测试 getPerson() 方法注意这个方法是在 PersonMapper 接口上的要知道测试的 PersonMapper 接口上面没有 CacheNamespace 和 CacheNamespaceRef 注解修饰测试代码如下 public static void main(String[] args) throws Exception {PersonMapper mapper sqlSession.getMapper(PersonMapper.class);PersonMapper mapper1 sqlSession2.getMapper(PersonMapper.class);Person person mapper.getPerson(1);sqlSession.commit();Person person1 mapper1.getPerson(1);mapper.getPerson(1);System.out.println(personperson1 (person person1));}
输出结果
2023-02-16 15:43:42,638 DEBUG [main] -org.apache.ibatis.transaction.jdbc.JdbcTransaction Opening JDBC Connection
2023-02-16 15:43:42,652 DEBUG [main] -org.apache.ibatis.datasource.pooled.PooledDataSource Created connection 255944888.
2023-02-16 15:43:42,658 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson Preparing: select id,user_name as userName,age as age from test_user where id ?
2023-02-16 15:43:42,703 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson Parameters: 1(Integer)
2023-02-16 15:43:42,760 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson Total: 1
2023-02-16 15:43:42,763 DEBUG [main] -org.apache.ibatis.transaction.jdbc.JdbcTransaction Opening JDBC Connection
2023-02-16 15:43:42,770 DEBUG [main] -org.apache.ibatis.datasource.pooled.PooledDataSource Created connection 1935972447.
2023-02-16 15:43:42,770 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson Preparing: select id,user_name as userName,age as age from test_user where id ?
2023-02-16 15:43:42,771 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson Parameters: 1(Integer)
2023-02-16 15:43:42,772 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson Total: 1
personperson1 false
发现没有使用到二级缓存因为在 PersonMapper 接口上压根就没有定义二级缓存直接去连接两次数据库查询那怎么才能让他使用到二级缓存并且命中呢上面说过在使用 CacheNamespace 注解准备缓存直接冲突所以这里应该使用 CacheNamespaceRef 注解来引用在 PersonMapper.xml 中配置的二级缓存。代码如下
CacheNamespaceRef(PersonMapper.class)
public interface PersonMapper {Select(select id,user_name as userName,age as age from test_user where id #{666})Person getPerson(Integer id);Person getPerson2(Integer id);
}测试结果
2023-02-16 15:49:48,135 DEBUG [main] -org.apache.ibatis.transaction.jdbc.JdbcTransaction Opening JDBC Connection
2023-02-16 15:49:48,146 DEBUG [main] -org.apache.ibatis.datasource.pooled.PooledDataSource Created connection 294184992.
2023-02-16 15:49:48,153 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson Preparing: select id,user_name as userName,age as age from test_user where id ?
2023-02-16 15:49:48,212 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson Parameters: 1(Integer)
2023-02-16 15:49:48,264 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper.getPerson Total: 1
2023-02-16 15:49:48,281 WARN [main] -org.apache.ibatis.io.SerialFilterChecker As you are using functionality that deserializes object streams, it is recommended to define the JEP-290 serial filter. Please refer to https://docs.oracle.com/pls/topic/lookup?ctxjavase15idGUID-8296D8E8-2B93-4B9A-856E-0A65AF9B8C66
2023-02-16 15:49:48,285 DEBUG [main] -org.apache.ibatis.gwmtest.dao.PersonMapper Cache Hit Ratio [org.apache.ibatis.gwmtest.dao.PersonMapper]: 0.5
personperson1 false
发现又可以命中二级缓存。然后在测试 getPerson2() 方法最终也是可以命中二级缓存的。
以上就是对 Mybatis 二级缓存的具体使用步骤。