写点什么

Mybatis 延迟加载和查询缓存

  • 2022 年 4 月 16 日
  • 本文字数:3653 字

    阅读完需:约 12 分钟

开启二级缓存:


在核心配置文件 SqlMapConfig.xml 中加入


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


| 描述 | 允许值 | 默认值 |


| --- | --- | --- |


| cacheEnabled 对在此配置文件下的所有 cache 进行全局性开/关设置。 | true false | true |


要在你的 Mapper 映射文件中添加一行: ,表示此 mapper


[](()开启二级缓存。




二级缓存需要查询结果映射的 pojo 对象实现 java.io.Serializable 接口实现序列化和反序列化操作,注意如果存在父类、成员 pojo 都需要实现序列化接口。


为了将缓存数据取出执行反序列化,因为二级缓存存储介质多种多样,不一定在内存。


[](()禁用二级缓存:




在 statement 中设置 useCache=false 可以禁用当前 select 语句的二级缓存,即每次查询都会发出 sql 去查询,默认情况是 true,即该 sql 使用二级缓存。


<select id="findOrderListResultMap" resultMap="ordersUserMap" useCache="false">


刷新缓存(就是清空缓存):


设置 statement 配置中的 flushCache=“true” 属性,默认情况下为 true 即刷新缓存,如果改成 false 则不会刷新。使用缓存时如果手动修改数据库表中的查询数据会出现脏读。


<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User" flushCache="true">


应用场景:


对于访问多的查询请求且用户对查询结果实时性要求不高,此时可采用 mybatis 二级缓存技术降低数据库访问量,提高访问速度,业务场景比如:耗时较高的统计分析 sql、电话账单查询 sql 等。


实现方法如下:通过设置刷新间隔时间,由 mybatis 每隔一段时间自动清空缓存,根据数据变化频率设置缓存刷新间隔 flushInterval,比如设置为 30 分钟、60 分钟、24 小时等,根据需求而定。


局限性:


mybatis 二级缓存对细粒度的数据级别的缓存实现不好,比如如下需求:对商品信息进行缓存,由于商品信息查询访问量大,但是要求用户每次都能查询最新的商品信息,此时如果使用 mybatis 的二级缓存就无法实现当一个商品变化时只刷新该商品的缓存信息而不刷新其它商品的信息,因为 mybaits 的二级缓存区域以 mapper 为单位划分,当一个商品信息变化会将所有商品 《一线大厂 Java 面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》开源 信息的缓存数据全部清空。解决此类问题需要在业务层根据需求对数据有针对性缓存。


[](()案例


================================================================



UserMapper.java


package com.xbj.mapper;


import com.xbj.po.TUser;


import java.util.List;


/**


  • 延迟加载


*/


public interface UserMapper {


//延迟加载


List<TUser> userIncludeOrder();


TUser findUserById(Integer id);


List<TUser> findAll();


void deleteById(Integer id);


}


UserMapper.xml


<?xml version="1.0" encoding="UTF-8" ?>


<!DOCTYPE mapper


PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"


"http://mybatis.org/dtd/mybatis-3-mapper.dtd">


<mapper namespace="com.xbj.mapper.UserMapper">


<cache />


<sql id="baseSql">


SELECT * from t_user


</sql>


<resultMap id="userInfos" type="TUser" autoMapping="true">


<id property="id" column="id"/>


<collection property="tOrders" ofType="TOrder" select="findorderByUid" column="id"/>


</resultMap>


<select id="findorderByUid" resultType="TOrder" parameterType="int">


SELECT * from t_order where uid=#{id}


</select>


<select id="userIncludeOrder" resultMap="userInfos">


SELECT * from t_user


</select>


<select id="findUserById" parameterType="int" resultType="TUser">


SELECT * FROM t_user where id=#{id}


</select>


<select id="findAll" resultType="TUser">


SELECT * from t_user


</select>


<delete id="deleteById" parameterType="int" >


DELETE from t_user WHERE id=#{id}


</delete>


</mapper>


pom.xml


<?xml version="1.0" encoding="UTF-8"?>


<project xmlns="http://maven.apache.org/POM/4.0.0"


xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"


xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">


<modelVersion>4.0.0</modelVersion>


<groupId>groupId</groupId>


<artifactId>dome02</artifactId>


<version>1.0-SNAPSHOT</version>


<dependencies>


<dependency>


<groupId>org.mybatis</groupId>


<artifactId>mybatis</artifactId>


<version>3.4.6</version>


</dependency>


<dependency>


<groupId>mysql</groupId>


<artifactId>mysql-connector-java</artifactId>


<version>5.1.47</version>


</dependency>


<dependency>


<groupId>junit</groupId>


<artifactId>junit</artifactId>


<version>4.12</version>


</dependency>


<dependency>


<groupId>log4j</groupId>


<artifactId>log4j</artifactId>


<version>1.2.14</version>


</dependency>


</dependencies>


</project>


sqlMapConfig.xml


<?xml version="1.0" encoding="UTF-8" ?>


<!DOCTYPE configuration


PUBLIC "-//mybatis.org//DTD Config 3.0//EN"


"http://mybatis.org/dtd/mybatis-3-config.dtd">


<configuration>


<settings>


<setting name="lazyLoadingEnabled" value="true"/>


</settings>


<typeAliases>


<package name="com.xbj.po" />


</typeAliases>


<environments default="development">


<environment id="development">


<transactionManager type="JDBC"/>


<dataSource type="POOLED">


<property name="driver" value="com.mysql.jdbc.Driver"/>


<property name="url" value="jdbc:mysql://localhost:3306/user"/>


<property name="username" value="root"/>


<property name="password" value="root"/>


</dataSource>


</environment>


</environments>


<mappers>


<package name="com.xbj.mapper" />


</mappers>


</configuration>


log4j.properties

Global logging configuration

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


log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n


TOrder.java


package com.xbj.po;


import java.io.Serializable;


import java.util.List;


/**


  • @Author:晓宇码匠

  • @Date:2019/6/21 0021


*/


public class TUser implements Serializable {


private int id;


private String username;


private String password;


private Integer age;


private List<TOrder> tOrders;


public List<TOrder> gettOrders() {


return tOrders;


}


public void settOrders(List<TOrder> tOrders) {


this.tOrders = tOrders;


}


public int getId() {


return id;


}


public void setId(int id) {


this.id = id;


}


public String getUsername() {


return username;


}


public void setUsername(String username) {


this.username = username;


}


public String getPassword() {


return password;


}


public void setPassword(String password) {


this.password = password;


}


public Integer getAge() {


return age;


}


public void setAge(Integer age) {


this.age = age;


}


@Override


public boolean equals(Object o) {


if (this == o) return true;


if (o == null || getClass() != o.getClass()) return false;


TUser tUser = (TUser) o;


if (id != tUser.id) return false;


if (username != null ? !username.equals(tUser.username) : tUser.username != null) return false;


if (password != null ? !password.equals(tUser.password) : tUser.password != null) return false;


if (age != null ? !age.equals(tUser.age) : tUser.age != null) return false;


return true;


}


@Override


public int hashCode() {


int result = id;


result = 31 * result + (username != null ? username.hashCode() : 0);


result = 31 * result + (password != null ? password.hashCode() : 0);


result = 31 * result + (age != null ? age.hashCode() : 0);


return result;


}


@Override


public String toString() {


return "TUser{" +


"id=" + id +


", username='" + username + ''' +


", password='" + password + ''' +


", age=" + age +


'}';


}


}


TUser.java


package com.xbj.po;


import java.io.Serializable;


import java.util.List;


/**


  • @Author:晓宇码匠

  • @Date:2019/6/21 0021


*/


public class TUser implements Serializable {


private int id;


private String username;


private String password;


private Integer age;


privat Java 开源项目【ali1024.coding.net/public/P7/Java/git】 e List<TOrder> tOrders;


public List<TOrder> gettOrders() {


return tOrders;


}


public void settOrders(List<TOrder> tOrders) {


this.tOrders = tOrders;


}


public int getId() {


return id;


}


public void setId(int id) {


this.id = id;


}


public String getUsername() {


return username;


}

最后

金三银四马上就到了,希望大家能好好学习一下这些技术点


学习视频:



大厂面试真题:



用户头像

还未添加个人签名 2022.04.13 加入

还未添加个人简介

评论

发布
暂无评论
Mybatis延迟加载和查询缓存_Java_爱好编程进阶_InfoQ写作平台