SSM之Mybatis_ch7
XML映射文件细解(五)
- cache——命名空间的缓存配置
- cache-ref——引用其他命名空间的缓存配置
- resultMap——从数据库结果集中加载对象,是最复杂也最强大的元素
- sql——可被其他语句引用的可重用语句块
- insert——映射插入语句
- update——映射更新语句
- delete——映射删除语句
- select——映射查询语句
此篇讲述cache缓存相关的内容
测试连通
Usermapper.java:列出此次要用到的几个方法
public interface UserMapper {
// 根据id查询用户
User queryUserById(@Param("id") int id);
List<User> queryUsers();
boolean updateUser(User user);
}
Usermapper.xml中相关的代码
<select id="queryUsers" resultType="user">
select * from mybatis.user
</select>
Test类中相关的代码
@Test
public void queryUsers() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
try {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = mapper.queryUsers();
for (User user : userList) {
System.out.println(user);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
sqlSession.close();
}
}
测试结果
开始验证
一级缓存
一次会话中查询到的记录会在本地缓存中。一级缓存默认是开启的。
Usermapper.xml中相关的代码
<select id="queryUserById" resultType="user">
select * from mybatis.user where id=#{id}
</select>
Test类中相关的代码
@Test
public void queryUserById() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
try {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user1 = mapper.queryUserById(1);
System.out.println(user1);
// 再次执行相同的查询
User user2 = mapper.queryUserById(1);
System.out.println(user2);
// 判断两个查询的结果的是否相等(hascode是否相等)
System.out.println(user1 == user2);
} catch (Exception e) {
e.printStackTrace();
} finally {
sqlSession.close();
}
}
运行结果:
select语句结果会被缓存,但是insert、update和delete会刷新缓存
也可以直接手动清理缓存sqlSession.clearCache();
Usermapper.xml中相关的代码
<update id="updateUser" parameterType="user">
update mybatis.user set name=#{name},pwd=#{pwd} where id=#{id}
</update>
在上面的查询use1和use2之间增加这一行
mapper.updateUser(new User(3,"reflect999","654321"));
运行结果
二级缓存
也叫作全局缓存,基于namespace级别的,即一个名称空间对应一个二级缓存。当一次会话关闭,将会把一级缓存存入到二级缓存。
在XML配置文件显示开启全局缓存
<!--显示的开启全局缓存-->
<setting name="cacheEnabled" value="true"/>
Usermapper.xml中相关的代码
<!-- 在当前Mapper中使用二级缓存-->
<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
<!-- 官方默认的配置-->
<!-- <cache eviction="FIFO"-->
<!-- flushInterval="60000"-->
<!-- size="512"-->
<!-- readOnly="true"/>-->
测试类中的相关代码
// 测试二级缓存
@Test
public void Test(){
SqlSession sqlSession1 = MybatisUtils.getSqlSession();
SqlSession sqlSession2 = MybatisUtils.getSqlSession();
try {
UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
User user1 = mapper1.queryUserById(1);
System.out.println(user1.hashCode());
} catch (Exception e) {
e.printStackTrace();
} finally {
sqlSession1.close();
}
try {
UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
User user2 = mapper2.queryUserById(1);
System.out.println(user2.hashCode());
} catch (Exception e) {
e.printStackTrace();
} finally {
sqlSession2.close();
}
}
运行结果
注:当使用上述官方的默认缓存配置,可能出现序列化错误,只需要将pojo类User实现Serializable即可。
全部代码
项目结构图
1.Pojo类User
package com.reflect.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* author: Administrator
* date: 2021/1/2 - 18:17
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private int id;
private String name;
private String pwd;
}
2.UserMapper类和UserMapper.xml
package com.reflect.mapper;
import com.reflect.pojo.User;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* author: Administrator
* date: 2021/1/2 - 18:18
*/
public interface UserMapper {
List<User> queryUsers();
// 根据id查询用户
User queryUserById(@Param("id") int id);
boolean updateUser(User user);
}
<?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.reflect.mapper.UserMapper">
<!-- 在当前Mapper中使用二级缓存-->
<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
<!-- 官方默认的配置-->
<!-- <cache eviction="FIFO"-->
<!-- flushInterval="60000"-->
<!-- size="512"-->
<!-- readOnly="true"/>-->
<select id="queryUsers" resultType="user">
select * from mybatis.user
</select>
<!-- 可在此处显示定义不使用缓存,即设置为false,默认为true-->
<select id="queryUserById" resultType="user" useCache="true">
select * from mybatis.user where id=#{id}
</select>
<update id="updateUser" parameterType="user">
update mybatis.user set name=#{name},pwd=#{pwd} where id=#{id}
</update>
</mapper>
3.Mybatis工具类与Mybatis配置文件、dbconfig数据库配置信息
package com.reflect.utils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.InputStream;
/**
* author: Administrator
* date: 2021/1/2 - 18:22
*/
public class MybatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (Exception e) {
e.printStackTrace();
}
}
public static SqlSession getSqlSession() {
return sqlSessionFactory.openSession();
}
}
<?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>
<properties resource="dbconfig.properties">
</properties>
<!-- 开启驼峰命名-->
<settings>
<!-- 调试错误时建议开启日志功能,以方便观察错误-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- 显示的开启全局缓存-->
<setting name="cacheEnabled" value="true"/>
</settings>
<!-- 设置别名-->
<typeAliases>
<package name="com.reflect.pojo"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- 此处的resource要注意是'/',而不是'.'-->
<mapper resource="com/reflect/mapper/UserMapper.xml"/>
</mappers>
</configuration>
driver=com.mysql.cj.jdbc.Driver
#url中&在配置文件可以直接写,但是在程序中需要进行可能转义
url=jdbc:mysql://192.168.199.131:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8
username=root
password=123456
4.测试类MyTest
import com.reflect.mapper.UserMapper;
import com.reflect.pojo.User;
import com.reflect.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
/**
* author: Administrator
* date: 2021/1/2 - 18:25
*/
public class MyTest {
@Test
public void queryUsers() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
try {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = mapper.queryUsers();
for (User user : userList) {
System.out.println(user);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
sqlSession.close();
}
}
// 测试一级缓存
@Test
public void queryUserById() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
try {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user1 = mapper.queryUserById(1);
System.out.println(user1);
mapper.updateUser(new User(3,"reflect999","654321"));
// 再次执行相同的查询
User user2 = mapper.queryUserById(1);
System.out.println(user2);
// 判断两个查询的结果的是否相等(hascode是否相等)
System.out.println(user1 == user2);
} catch (Exception e) {
e.printStackTrace();
} finally {
sqlSession.close();
}
}
// 测试二级缓存
@Test
public void Test(){
SqlSession sqlSession1 = MybatisUtils.getSqlSession();
SqlSession sqlSession2 = MybatisUtils.getSqlSession();
try {
UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
User user1 = mapper1.queryUserById(1);
System.out.println(user1.hashCode());
} catch (Exception e) {
e.printStackTrace();
} finally {
sqlSession1.close();
}
try {
UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
User user2 = mapper2.queryUserById(1);
System.out.println(user2.hashCode());
} catch (Exception e) {
e.printStackTrace();
} finally {
sqlSession2.close();
}
}
}
5.自定义缓存相关的配置文件
有需要的可以自行研究,此处只是验证缓存存在,不做过多概述。
<?xml version="1.0" encoding="UTF-8" ?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
updateCheck="false">
<!-- diskStore: 为缓存路径,ehcache分为内存和磁盘两级,此属性定义磁盘的缓存位置。参数解释如下:
user.home - 用户主目录
user.dir - 用户当前工作目录
java.io.tmpdir - 默认临时文件路径
-->
<diskStore path="./tmpdir/Tmp_Ehcache"/>
<defaultCache
eternal="false"
maxElementsInMemory="1000"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="1800"
timeToLiveSeconds="259200"
memoryStoreEvictionPolicy="LRU"/>
<cache
name="cloud_user"
eternal="false"
maxElementsInMemory="5000"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="1800"
timeToLiveSeconds="259200"
memoryStoreEvictionPolicy="LRU"/>
</ehcache>
因为许多东西用纯文字和代码无法演示出来,所以想尽量将自己所知识的分享出来,希望能对大家学习略有帮助,也是我自己学习路上的最好写照!有关其它配置,有兴趣的可以在MyBatis官网参考。
因为可能写的也并不是特别好,所以如果有什么不对的地方,希望大家不吝赐教!
至此,MyBatis部分到此告一段落了!