MyBatis로 (d) - 캐시 및 보조 캐시

  • 설명 : 지속성 프레임 워크의 대부분과 마찬가지로, MyBatis로는 성능 향상을 위해 전략을 캐싱하여 데이터베이스 쿼리의 수를 줄이기 위해 캐싱 전략을 제공합니다.

캐시

  • 의 존재를 증명 캐시
    캐시하는 한 SQLSESSION로 더 높이 또는 가까운 SQLSESSION 레벨 캐시, 그것은 존재한다.
  • 쓰기 사용자 인터페이스 지속성 계층 다오
public interface IUserDao {
	/**
	* 根据 id 查询
	* @param userId
	* @return
	*/
	User findById(Integer userId);
}
  • 레이어 매핑 파일 지속성 쓰기 사용자
<?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.itheima.dao.IUserDao">
	<!-- 根据 id 查询 --> 
	<select id="findById" resultType="UsEr" parameterType="int" useCache="true">
		select * from user where id = #{uid}
	</select>
</mapper>
  • 작문 시험 방법
public class UserTest {
	private InputStream in ;
	private SqlSessionFactory factory;
	private SqlSession session;
	private IUserDao userDao;
	
	@Test
	public void testFindById() {
		//6.执行操作
		User user = userDao.findById(41);
		System.out.println("第一次查询的用户:"+user);
		User user2 = userDao.findById(41);
		System.out.println("第二次查询用户:"+user2);
		System.out.println(user == user2);
	}
	
	@Before
	//在测试方法执行之前执行
	public void init()throws Exception {
		//1.读取配置文件
		in = Resources.getResourceAsStream("SqlMapConfig.xml");
		//2.创建构建者对象
		SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
		//3.创建 SqlSession 工厂对象
		factory = builder.build(in);
		//4.创建 SqlSession 对象
		session = factory.openSession();
		//5.创建 Dao 的代理对象
		userDao = session.getMapper(IUserDao.class);
	}
	
	@After
	//在测试方法执行完成之后执行
	public void destroy() throws Exception{
		//7.释放资源
		session.close();
		in.close();
	} 
}

다음과 같이 테스트 결과는 다음과 같습니다
그림 삽입 설명 여기

  • 우리는이 비록 위의 코드에서 우리는 두 번 쿼리를 볼 수 있지만, 우리의 MyBatis 레벨 캐시 작업 사용할 수있는 데이터베이스 작업의 끝에서만 구현 할 수 있습니다. 버퍼의 존재 레코드 (41)의 ID에서 두 번째 쿼리 결과, 그리고 SQL 문을 데이터베이스 쿼리의 데이터 만 캐시에서 쿼리를 실행하지 않기 때문에.
  • 의 캐시 분석
    당신의 SQLSESSION을 수정, 추가, 삭제, (커밋 호출 할 때 캐시가 가까운), () 메소드 등 캐시 SQLSESSION 범위, 그것은 캐시를 비우는 것입니다.
    그림 삽입 설명 여기
  • 삭제 캐시 테스트
	/**
	* 测试一级缓存
	*/
	@Test
	public void testFirstLevelCache(){
		User user1 = userDao.findById(41);
		System.out.println(user1);
		
		sqlSession.clearCache();//此方法也可以清空缓存

		userDao = sqlSession.getMapper(IUserDao.class);
		User user2 = userDao.findById(41);
		System.out.println(user2);
		System.out.println(user1 == user2);
	}
	/**
	* 测试缓存的同步
	*/
	@Test
	public void testClearlCache(){
		//1.根据 id 查询用户
		User user1 = userDao.findById(41);
		System.out.println(user1);
		//2.更新用户信息
		user1.setUsername("update user clear cache");
		user1.setAddress("北京市海淀区");
		userDao.updateUser(user1);
		//3.再次查询 id 为 41 的用户
		User user2 = userDao.findById(41);
		System.out.println(user2);
		System.out.println(user1 == user2);
	}
当执行sqlSession.close()后,再次获取sqlSession并查询id=41的User对象时,又重新执行了sql 
语句,从数据库进行了查询操作。

MyBatis로 보조 캐시

보조 캐시 레벨 캐시를 매핑하는 맵퍼는, 복수 SQLSESSION SQL 문은 보조 캐시의 SQLSESSION에서 보조 캐시의 SQLSESSION의 복수를 공유 할 수 있습니다, 같은 매퍼가 매핑 조작합니다.

  • 2 차 캐쉬의 구성도
    그림 삽입 설명 여기
    차 캐시의 MyBatis의 제집니다.
    sqlSession1는 사용자 정보 쿼리 데이터가 보조 캐시에 저장됩니다 쿼리 사용자 정보를 조회 할 수 있습니다.
    동일한 데이터가 실행을 저지 SQL을 매핑 매퍼 SqlSession3을 수행 할 경우, 매퍼 매핑의 2 차 캐시 영역이 삭제됩니다.
    캐시에서 직접 촬영 한 데이터가있는 경우 sqlSession2 sqlSession1는 먼저 캐시에 데이터가 있는지 찾을 것 같은 사용자 정보를 조회합니다.
ON과 OFF 차 캐시
  • 첫 번째 단계 : SqlMapConfig.xml에서 보조 캐시 파일을 켭니다
<settings>
	<!-- 开启二级缓存的支持 --> 
	<setting name="cacheEnabled" value="true"/>
</settings>
因为 cacheEnabled 取值默认就为 true,所以这一步可以省略不配置。为 true 代表开启二级缓存;
为false 代表不开启二级缓存。
  • 단계 : 구성 관련 매퍼 매핑 파일
<cache>标签表示当前这个 mapper 映射将使用二级缓存,区分的标准就看 mapper 的 namespace值。

<?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.itheima.dao.IUserDao">
		<!-- 开启二级缓存的支持 -->
		<cache></cache>
	</mapper>
  • 세 번째 단계 : 위의 문장 구성이 useCache 속성
<!-- 根据 id 查询 --> 
<select id="findById" resultType="user" parameterType="int" useCache="true">
	select * from user where id = #{uid}
</select> 
	将 UserDao.xml 映射文件中的<select>标签中设置 useCache=true”代表当前这个 
statement 要使用二级缓存,如果不使用二级缓存可以设置为 false。
注意:针对每次查询都需要最新的数据 sql,要设置成 useCache=false,禁用二级缓存。
  • 차 캐시 테스트
public class SecondLevelCacheTest {
private InputStream in;
private SqlSessionFactory factory; @Before//用于在测试方法执行之前执行
public void init()throws Exception{
//1.读取配置文件,生成字节输入流
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.获取 SqlSessionFactory
factory = new SqlSessionFactoryBuilder().build(in);
}@After//用于在测试方法执行之后执行
public void destroy()throws Exception{
in.close();
}
/**
* 测试一级缓存
*/
@Test
public void testFirstLevelCache(){
	SqlSession sqlSession1 = factory.openSession();
	IUserDao dao1 = sqlSession1.getMapper(IUserDao.class);
	User user1 = dao1.findById(41);
	System.out.println(user1);
	sqlSession1.close();//一级缓存消失
	
	SqlSession sqlSession2 = factory.openSession();
	IUserDao dao2 = sqlSession2.getMapper(IUserDao.class);
	User user2 = dao2.findById(41);
	System.out.println(user2);
	sqlSession2.close();
	System.out.println(user1 == user2);
	}
}

위의 테스트 후에, 우리는이 개 질문의 구현, 그리고 첫 번째 쿼리를 수행 한 후, 우리는 두 번째 쿼리를 수행하기 위해 이동하여 첫 번째 레벨 캐시를 폐쇄 발견, 우리는 데이터베이스에 발행 된 어떠한 SQL 문을 발견이 너무 데이터는 단지 우리가 차 캐시를 부르는에서 파생 될 수있다.

  • 차 캐시 노트
	当我们在使用二级缓存时,所缓存的类一定要实现 java.io.Serializable 接口,
这种就可以使用序列化
方式来保存对象。
public class User implements Serializable {
	private Integer id;
	private String username;
	private Date birthday;
	private String sex;
	private String address; 
} 
게시 58 개 원래 기사 · 원 찬양 7 · 전망 9247

추천

출처blog.csdn.net/Mr_OO/article/details/102573733