Mybatis延迟加载中有两个标签支持延迟加载

延迟加载

延迟加载也叫做懒加载lazy

按需要进行加载,是优化查询速度的方法

Mybatis中有两个标签支持延迟加载

<association>

<collection>

 

操作步骤:

1. 打开延迟加载开关,关闭积极加载开关

核心配置文件sqlMapconfig.xml

<settings>

<!-- 打开延迟加载开关 -->

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

<!-- 关闭积极加载开关 -->

<setting name="aggressiveLazyLoading" value="false"/>

</settings>

 

2. 编写代码

映射文件:

<resultMap type="cn.itcast.po.Orders" id="orderAndUserLazyResultMap">

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

<result column="user_id" property="userId"/>

<result column="number" property="number"/>

<result column="createtime" property="createtime"/>

<result column="note" property="note"/>

<!--

使用延迟加载

select:调用要执行的sql语句,使用那个sqlnamespace+.+sql语句的id

例如:cn.itcast.mapper.UserMapper.findUserById

column:是orders表中与user表关联的字段

 -->

<association property="user" javaType="cn.itcast.po.User"

select="cn.itcast.mapper.UserMapper.findUserById" column="user_id">

</association>

</resultMap>

 

<select id="findOrderAndUserLazy" resultMap="orderAndUserLazyResultMap">

select * from orders

</select>

 

接口:

public List<Orders> findOrderAndUserLazy();

 

测试代码:

@Test

public void testFindOrderAndUserLazy() throws Exception{

SqlSession openSession = sqlSessionFactory.openSession();

OrdersMapper ordersMapper = openSession.getMapper(OrdersMapper.class);

List<Orders> list = ordersMapper.findOrderAndUserLazy();

for(Orders order : list){

String number = order.getNumber();

System.out.println(number);

User user = order.getUser();

System.out.println(user.getUsername());

}

}

 

 

 

 

 

总结

1. 对单个对象的映射关系使用:<association

2. 对集合对象的映射关系使用:<collection

3. 延迟加载:需要在核心配置文件中配置开关;在mybatisassociationcollection支持延迟加载

缓存

优化查询速度

 

 

 

 

 

 

 

 

 

 

 

 

 

 

3.1 一级缓存

SqlSession级别的,一级缓存由mybatis自己控制,不需要人为干预

1. 第一次查询会查询一级缓存,如果缓存中没有数据会从数据库中查询

2. 如果有更新、删除、修改操作,那么会清空缓存

3. 接着再次执行查询则会去数据库中查询数据并放到缓存中

4. 再次查询则直接从缓存中查询数据

 

映射文件:

<select id="findUserByIdCache1" parameterType="int" resultType="user">

select * from User where id=#{aaa}

</select>

 

接口:

public User findUserByIdCache1(Integer id);

 

测试代码:

@Test

public void testFindUserByIdCache1() throws Exception{

SqlSession openSession = sqlSessionFactory.openSession();

//获得Mapper对象

UserMapper userMapper = openSession.getMapper(UserMapper.class);

//第一次查询

User user1 = userMapper.findUserByIdCache1(1);

System.out.println(user1);

user1.setUsername("李四");

userMapper.updateUserById(user1);

openSession.commit();

//第二次查询

User user2 = userMapper.findUserByIdCache1(1);

System.out.println(user2);

}

 

 

3.2 二级缓存

二级缓存中的数据可以存储在内存中,或者硬盘中。

 

操作步骤:

1. 开启二级缓存

SqlMapConfig.xml中加入

<!-- 开启二级缓存 -->

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

 

2. 在需要二级缓存的映射文件中加入<cache />

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">

<!--

namespace:命名空间,作用为Sql隔离

 -->

<mapper namespace="cn.itcast.mapper.UserMapper">

<!-- 使用二级缓存 -->

<cache />

3. 将查询的POJO实现Serializable接口

public class User implements Serializable{

private static final long serialVersionUID = -6538886943664906447L;

private int id;

private String username;// 用户姓名

private String sex;// 性别

private Date birthday;// 生日

private String address;// 地址

映射文件:

<select id="findUserByIdCache2" parameterType="int" resultType="user">

select * from User where id=#{aaa}

</select>

 

接口:

public User findUserByIdCache2(Integer id);

 

测试代码:

@Test

public void testFindUserByIdCache2() throws Exception{

SqlSession openSession = sqlSessionFactory.openSession();

//获得Mapper对象

UserMapper userMapper = openSession.getMapper(UserMapper.class);

//第一次查询

User user = userMapper.findUserByIdCache2(1);

System.out.println(user);

openSession.close();

//第二次查询

openSession = sqlSessionFactory.openSession();

userMapper = openSession.getMapper(UserMapper.class);

User user1 = userMapper.findUserByIdCache2(1);

System.out.println(user1);

}

 

测试代码:

@Test

public void testFindUserByIdCache2() throws Exception{

SqlSession openSession = sqlSessionFactory.openSession();

//获得Mapper对象

UserMapper userMapper = openSession.getMapper(UserMapper.class);

//第一次查询

User user = userMapper.findUserByIdCache2(1);

System.out.println(user);

openSession.close();

//执行更新操作

openSession = sqlSessionFactory.openSession();

userMapper = openSession.getMapper(UserMapper.class);

user.setUsername("王六");

userMapper.updateUserById(user);

openSession.commit();

openSession.close();

//第二次查询

openSession = sqlSessionFactory.openSession();

userMapper = openSession.getMapper(UserMapper.class);

User user1 = userMapper.findUserByIdCache2(1);

System.out.println(user1);

openSession.close();

//第三次查询

openSession = sqlSessionFactory.openSession();

userMapper = openSession.getMapper(UserMapper.class);

User user2 = userMapper.findUserByIdCache2(1);

System.out.println(user2);

openSession.close();

}

 

 

3.3 分布式缓存

 

 

 

 

 

 

 

 

 

 

 

 

 

1. 导入jar

 

2. 添加ehcache.xml

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

xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">

<diskStore path="E:\" />

<!-- maxElementsInMemory内存中缓存的最大个数 -->

<!-- maxElementsOnDisk硬盘上缓存的最大个数 -->

<!-- eternal设置缓存中的数据是否永远不过期 -->

<!-- overflowToDisk设置缓存中的数据是否永远不过期 -->

<!-- overflowToDisk缓存数据闲置时间,超过则删除数据-->

<!-- timeToIdleSeconds缓存数据闲置时间,超过则删除数据-->

<!-- timeToLiveSeconds缓存数据存活时间,超过则删除数据 -->

<!-- diskExpiryThreadIntervalSeconds磁盘缓存清理线程运行间隔-->

<!-- memoryStoreEvictionPolicy缓存策略,最近最少使用,当缓存大小到达极限时删除最近很少使用的-->

<defaultCache 

maxElementsInMemory="1000" 

maxElementsOnDisk="10000000" 

eternal="false" 

overflowToDisk="false" 

timeToIdleSeconds="120"

timeToLiveSeconds="120" 

diskExpiryThreadIntervalSeconds="120"

memoryStoreEvictionPolicy="LRU">

</defaultCache>

</ehcache>

 

 

3. 配置映射文件中使用ehcache实现

<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>

 

4. 测试(同二级缓存测试)

 

 

 

flushCache刷新缓存:不配置默认为true

如果配置成false就是永远不刷新缓存,也就意味着缓存中的数据如果更新或者删除还有添加的时候,就成了脏数据了。

useCache是否使用缓存:如果不配置默认为true使用缓存。

如果遇到刷新,更改,删除操作频繁的情况下可以设置成false,不适用缓存,因为缓存的清空还有填充数据,也是需要耗费资源的

 

 

3.4 缓存的使用:

增加、修改、删除这样的操作很少的情况下才能使用缓存。

比如电话局的话务系统,话单的查询功能可以使用缓存。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值