十四十五十六十七、日志连接池缓存延迟加载

十四、MyBatis日志配置

MyBatis作为一个封装好的ORM框架,其运行过程没办法跟踪,为了让开发者了解MyBatis执行流程及每个执行过程说完成的工作MyBatis本身集成了log4j日志框架,对其运行过程进行跟踪记录。我们只需对MyBatis进行相关的日志配置,就可以看到MyBatis运行过程中的日志信息。

14.1 添加日志依赖

<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

14.2 添加日志配置文件

  • 在resources目录下创建名为log4j.properties文件
  • 在log4j文件中配置日志输出的方式
### Log4j配置 ###
### 与Spring结合需要在web.xml中指定此文件位置,并添加监听器 ###
#定义log4j的输出级别和输出目的地(目的地可以自定义名称,和后面的对应)
#[ level ] , appenderName1 , appenderName2
log4j.rootLogger=DEBUG,console,file

#-----------------------------------#
#1 定义日志输出目的地为控制台
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
####可以灵活地指定日志输出格式,下面一行是指定具体的格式 ###
#%c: 输出日志信息所属的类目,通常就是所在类的全名
#%m: 输出代码中指定的消息,产生的日志具体信息
#%n: 输出一个回车换行符,Windows平台为"/r/n",Unix平台为"/n"输出日志信息换行
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n

#-----------------------------------#
#2 文件大小到达指定尺寸的时候产生一个新的文件
log4j.appender.file = org.apache.log4j.RollingFileAppender
#日志文件输出目录
log4j.appender.file.File=log/tibet.log
#定义文件最大大小
log4j.appender.file.MaxFileSize=10mb
###输出日志信息###
#最低级别
log4j.appender.file.Threshold=ERROR
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n

#-----------------------------------#
#3 druid
log4j.logger.druid.sql=INFO
log4j.logger.druid.sql.DataSource=info
log4j.logger.druid.sql.Connection=info
log4j.logger.druid.sql.Statement=info
log4j.logger.druid.sql.ResultSet=info

#4 mybatis 显示SQL语句部分
log4j.logger.org.mybatis=DEBUG
#log4j.logger.cn.tibet.cas.dao=DEBUG
#log4j.logger.org.mybatis.common.jdbc.SimpleDataSource=DEBUG#
#log4j.logger.org.mybatis.common.jdbc.ScriptRunner=DEBUG#
#log4j.logger.org.mybatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG#
#log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG`

14.3 日志信息的级别

在使用日志框架输出日志信息的时候,会根据输出的日志信息的重要程度分为以下5个级别

级别介绍
DEBUG输出调试信息
INFO输出提示信息
WARN输出警告信息
ERROR一般性错误信息
FATAL致命性错误信息

15、配置数据库连接池Druid

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

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

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

15.1常见的连接池

  • DBCP
  • C3P0
  • Druid 性能比较好,提供了比较便捷的监控系统
  • Hikari 性能最好

img

15.2 添加Druid依赖

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

15.3 创建Druid连接池工厂

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

15.4 将DruidDataSourceFactory配置给MyBatis数据源

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

十六、MyBatis缓存

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

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

16.1 缓存工作原理

缓存是存储数据的内存

执行查询操作数据时

  1. 先检查缓存中是否存在要查询的数据
  2. 如果存在,则直接从缓存中获取数据并返回(不会查数据库)
  3. 如果不存在,则从数据库查询,查询之后将数据返回,同时存到缓存中,以供下次查询使用

16.2 MyBatis缓存

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

16.2.1 一级缓存

也叫做SqlSession级缓存,为每个SqlSession单独分配的缓存内存,无需手动开启,多个SqlSession的缓存是不共享的

特性:

  1. 如果多次查询使用的是同一个SqlSession对象,则第一次查询的数据会存放到缓存,后续查询可以直接访问缓存中的数据
  2. 如果第一次查询完成后,对查询出的对象进行修改,直接设置对象属性的方式修改(此修改会影响到缓存),第二次查询会直接访问缓存,造成第二次查询的结果与数据库不一致;
  3. 所以在第一次查询过后想要跳过缓存,可以通过sqlSession.clearCache();清除缓存,以此来保证数据的一致性
  4. 如果第一次查询之后,第二次查询之前,使用当前的SqlSession执行了修改操作(调用dao的方法修改数据库中的信息),此修改操作会使第一次查询并缓存的数据失效,因此第二次查询会再次访问数据库。
16.2.2 两次查询与数据库数据不一致的问题

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3DTwUGbT-1655988637157)(C:\Users\Huangwei\AppData\Roaming\Typora\typora-user-images\image-20220623200123548.png)]

16.2.3 二级缓存

二级缓存也称为SqlSessionFactory级缓存,通过同一个factory对象获取的SqlSession可以共享二级缓存;在应用服务器中SqlSessionFactory是单例的,因此二级缓存可以实现全局共享

特性:

  1. 二级缓存默认没有开启,需要在mybatis-config.xml中的settings标签开启
  2. 二级缓存只能缓存实现序列化接口的对象
  • 在mybatis-config.xml中的settings标签开启使用二级缓存
<settings>
    <setting name="cacheEnabled" value="true"/>
</settings>
  • 在需要使用二级缓存的Mapper文件中配置cache标签使用二级缓存
<cache/>
  • 被缓存的实体类实现序列化接口
@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Member implements Serializable {
    private int memberId;
    private String memberNick;
    private String memberGender;
    private int memberAge;
    private String memberCity;
}
  • 多个SqlSession对象必须来自于同一个SqlSessionFactory,第一次查询后执行sqlSession.commit(),会将当前sqlSession的查询结果缓存到二级缓存

16.3 查询操作的缓存开关

<select id="searchMember" resultMap="memberMap" useCache="true">

十七、延迟加载机制

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


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