MyBatis整合Druid连接池&缓存机制&延迟加载

MyBtis整合Druid连接池

MyBatis作为一个ORM框架,在进行数据库操作时是需要和数据库连接的,MyBatis支持基于数据库连接池的连接创建方式。

当我们配置MyBatis数据源是,只要配置了dataSource标签的type属性值为POOLED时,就可以使用MyBatis内置的连接池管理连接。

如果想要使用第三方的数据库连接池,则需进行自定义配置

常见的连接池:

  • DBCP
  • C3P0(效率比较低)
  • Druid(性能也比较好,提供了比较便捷的监控系统)
  • Hikari(性能最好)

添加Druid依赖

<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.10</version>
</dependency>

将MyBatis自带的连接池替换为Druid

创建Druid连接池工厂

public class DruidDataSourceFactory extends PooledDataSourceFactory {

    public DruidDataSourceFactory() {
        this.dataSource = new DruidDataSource();
    }
}

将DruidDataSourceFactory配置给MyBatis数据源

<environment id="mysql">
            <transactionManager type="JDBC"></transactionManager>

<!--           POOLED 表示使用MyBatis内置的连接池实现
                MyBatis需要一个连接池工厂,这个工厂可以产生数据库连接池
                POOLOED
    -->
            <dataSource type="com.ccl.Utils.DruidDataSourceFactory">
                <property name="driverClass" value="${driver}"/>
                <property name="jdbcUrl" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>

MyBatis缓存

MyBatis 是基于JDBC的封装,使数据库操作更加便捷;MyBatis除了对JDBC操作步骤进行封装之外,也对其性能进行了优化:

  • 在MyBatis中引入了缓存机制,用于提升MyBatis的检索效率
  • 在MyBatis中引入了延迟加载机制,用于减少对数据库不必要的访问

缓存的工作原理

缓存实际上就是存储数据的内存

在这里插入图片描述

MyBatis缓存

MyBatis缓存分为一级缓存和二级缓存

一级缓存

一级缓存也叫SqlSession级缓存,为每个SqlSession对象单独分配的缓存内存,无需手动改开启可直接使用;多个SqlSession的缓存是不共享的。

特性:

  • 如果多次查询使用的是同一个SqlSession对象,则第一次查询之后数据会存放到缓存中,后续的查询则直接访问缓存中存储的数据
  • 在这里插入图片描述

特性:

  • 如果第一次查询完成之后,对查询出的对象进行修改(此修改会影响到缓存),第二次查询会直接访问缓存,造成第二次查询的结果与第一次不同/与数据库不一致
  • 如果第一次查询之后第二次查询之前,使用当前sqlsession执行了修改操作,此修改操作会使第一次查询并缓存大的数据失效,因此第二次查询会再次访问数据库
  • 在这里插入图片描述
  • 当我们再进行查询时想要跳过混村直接查询数据库,则可以通过sqlSession.clearCache();来清除当前SqlSession的缓存

测试代码

   @Test
   public void testQueryMemberById(){
       SqlSession sqlSession1 = MyBatisUtil.getFactory().openSession();
       SqlSession sqlSession2 = MyBatisUtil.getFactory().openSession();
       MemberDao memberDao = sqlSession1.getMapper(MemberDao.class);
       Member member = memberDao.queryMemberById(1);
       System.out.println(member);

       memberDao.updateMember(1,39);
       sqlSession1.commit();
//       sqlSession.clearCache();    //清空缓存
 //      MyBatisUtil.close();


       System.out.println("===================");

       MemberDao memberDao1 = sqlSession1.getMapper(MemberDao.class);
       Member member1 = memberDao1.queryMemberById(1);
       System.out.println(member1);
   }

二级缓存

二级缓存也称之为SqlSessionFactory级缓存,通过一个factory对象获取的SqlSession可以共享二级缓存:

应用服务器中SqlSessionFactory是单例的,incident我们二级缓存可以实现全局共享

特性:

  • 二级缓存默认没有开启,需要再mybatis-config.xml中的setting标签开启
  • 二级缓存只能缓存实现序列化接口的对象
  • 再mybatis-config.xml中开启使用二级缓存
<settings>
    <setting name="cacheEnable" value="true"/>
</settings>
  • 在需要使用二级缓存的Mapper文件中配置cache标签使用二级缓存
<cache/>
  • 被缓存的实体类实现序列化接口

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @ToString
    public class Member implements Serializable  {
        private Integer member_id;
        private String member_nick;
        private String member_gender;
        private Integer member_age;
        private String member_city;
    }
    

延迟加载

延迟加载 :如果在MyBatis中开启了延迟加载,在执行了子查询(至少查询两次以上),默认只执行第一次查询,当用到子查询的查询结果时,才会触发子查询的执行,如果无需使用子查询结果,则子查询不会执行


版权声明:本文为qq_17514043原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。