Mybatis相关整理(三)

一、MyBatis日志配置

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

  1. 添加日志框架依赖
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
  1. 添加日志配置文件
  • 在resources目录下创建名为 log4j.properties文件
  • log4j.properties文件配置日志输出的方式
# 声明日志的输出级别及输出方式
log4j.rootLogger=DEBUG,stdout
# MyBatis logging configuration...
log4j.logger.org.mybatis.example.BlogMapper=TRACE
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
# 定义日志的打印格式  %t 表示线程名称  %5p 日志级别 %msg日志信息
log4j.appender.stdout.layout.ConversionPattern=[%t] %5p - %msg \:%m%n
  1. 日志信息的级别
    在这里插入图片描述

二、MyBatis缓存

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

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

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

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

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

    特性:
    1.如果多次查询使用的是同一个SqlSession对象,则第一次查询之后数据会存放到缓存,后续的查询则直接访问缓存中存储的数据;

    2.如果第一次查询完成之后,对查询出的对象进行修改(此修改会影响到缓存),第二次查询会直接访问缓存,造成第二次查询的结果与数据库不一致;

    3.当我们进行在查询时想要跳过缓存直接查询数据库,则可以通过sqlSession.clearCache();来清除当前SqlSession的缓存;

    4.如果第一次查询之后第二查询之前,使用当前的sqlsession执行了修改操作,此修改操作会使第一次查询并缓存的数据失效,因此第二次查询会再次访问数据库。

测试代码:

@Test
public void testQueryMemberById(){
    SqlSession sqlSession1 = MyBatisUtil.getSqlSessionFactory().openSession();
    SqlSession sqlSession2 = MyBatisUtil.getSqlSessionFactory().openSession();

    MemberDAO memberDAO1 = sqlSession1.getMapper(MemberDAO.class);
    Member member1 = memberDAO1.queryMemberById(1);
    System.out.println(member1);

    member1.setMemberAge(99);
    sqlSession1.clearCache();
    System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");

    MemberDAO memberDAO2 = sqlSession1.getMapper(MemberDAO.class);
    Member member2 =memberDAO2.queryMemberById(1);
    System.out.println(member2);
}

两次查询与数据库数据不一致问题
第一次查询之后,进行了修改操作,数据库数据已经被修改,但是第二查询的时候依然显示的修改前的数据。

原因:修改操作和查询操作不是同一个线程,因此使用的不同的studentDAO对象(使用不同的sqlSession),因此修改操作不会导致查询操作的缓存失效,第二次查询的时候依然访问的是缓存而没有查数据库

解决方案:
1.让修改操作和查询操作使用相同的SqlSession(不太合理)
2.每次进行查询操作之后,清空缓存,让再次查询的时候绕过缓存直接访问数据库

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

    特性:
    1.二级缓存默认没有开启,需要在mybatis-config.xml中的settings标签开启
    2.二级缓存只能缓存实现序列化接口的对象

在mybatis-config.xml开启使用二级缓存

<settings>
    <setting name="cacheEnabled" value="true"/>
</settings>

在需要使用二级缓存的Mapper文件中配置cache标签使用功能二级缓存

<cache/>

被缓存的实体类实现序列化接口

@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class Member implements Serializable {
    private int memberId;
    private String memberNick;
    private String memberGender;
    private int memberAge;
    private String memberCity;
}

查询操作的缓存开关

<select id="queryMemberById" resultMap="memberMap" useCache="false">
    select member_id,member_nick,member_gender,member_age,member_city
    from members
    where member_id=#{mid}
</select>

三、延迟加载

延迟加载也叫懒加载、惰性加载,使用延迟加载可以提高程序的运行效率,针对于数据持久层的操作,在某些特定的情况下去访问特定的数据库,在其他情况下可以不访问某些表,从一定程度上减少了Java应用与数据库的交互次数。
如果在MyBatis开启了延迟加载,在执行了子查询(至少查询两次及以上)时,默认只执行第一次查询,当用到子查询的查询结果时,才会触发子查询的执行;如果无需使用子查询结果,则子查询不会执行.

开启延迟加载:
config.xml中

<settings>
<!--打印SQL-->
<setting namem"logImpl" valuem"STDOUT_LOGGING-/><!--开启延迟加载-->
<setting name="lazyLoadingEnabled" value="true" />
</settings>

mapper层中:fetchType=“lazy”

<resultMap id="classMap" type="Clazz">
    <id column="cid" property="classId"/>
    <result column="cname" property="className"/>
    <result column="cdesc" property="classDesc"/>
    <collection property="stus" select="com.qfedu.dao.StudentDAO.queryStudentsByCid" column="cid" fetchType="lazy"/>
</resultMap>

<select id="queryClassByCid" resultMap="classMap">
    select cid,cname,cdesc
    from classes
    where cid=#{cid}
</select>

四、Mybatis逆向工程

逆向工程即传统开发的反向工程
Mybatis框架需要:实体类、自定义Mapper接口,Mapper.xml
传统的开发中上述的三个组件需要开发者手动创建,逆向工程可以帮助开发者来自动创建三个组件,减轻开发者的工作量,提高工作效率。
使用方法
MyBatis Generator,简称MBG,是一个专门为MyBatis框架开发者定制的代码生成器,可自动生成MyBatis 框架所需的实体类、Mapper 接口、Mapper .xml,支持基本的CRUD操作,但是一些相对复杂的SQL需要开发者自己来完成。
1.新建Maven工程,pom.xml文件中引入相关依赖
在这里插入图片描述
2.创建MBG配置文件generatorConfig.xml

1)jdbcConnection配置数据库连接信息

2)javaModelGenerator配置JavaBean 的生成策略。

3)sqlMapGenerator配置SQL映射文件生成策略。

4)JavaClientGenerator配置 Mapper接口的生成策略。

5)table配置目标数据表。(tableName:表名,domainObjectName: JavaBean类名)
在这里插入图片描述3.创建generator执行的类
在这里插入图片描述
在这里插入图片描述
执行完后会自动创建entity类等

参考链接:

https://www.bilibili.com/video/BV15Q4y1m78a?p=42

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值