> Java > java지도 시간 > 본문

쿼리 캐시란 무엇입니까? MyBatis 쿼리 캐시 사용법 소개

零下一度
풀어 주다: 2017-06-25 10:56:07
원래의
2367명이 탐색했습니다.

재인쇄할 소스를 표시해 주세요:

앞서 언급한 대로: Spring+SpringMVC+MyBatis 심층 학습 및 구성(7) - MyBatis 지연 로딩

1. 쿼리 캐시란 무엇입니까

mybatis는 데이터베이스 부담을 줄이기 위해 쿼리 캐시를 제공합니다. , 데이터베이스 성능을 향상시킵니다.

mybatis는 1단계 캐시와 2단계 캐시를 제공합니다.

첫 번째 수준 캐시는 SqlSession 수준 캐시입니다. 데이터베이스를 운영할 때 sqlSession 객체를 생성해야 합니다. 객체에는 캐시 데이터를 저장하기 위한 데이터 구조(HashMap)가 있습니다. 서로 다른 sqlSession 간의 캐시 데이터 영역(HashMap)은 서로 영향을 미치지 않습니다.

두 번째 수준 캐시는 매퍼 수준 캐시입니다. 여러 sqlSession은 동일한 Mapper의 sql 문을 작동합니다. 두 번째 수준 캐시는 sqlSession에 걸쳐 있습니다.

캐싱을 사용하는 이유는 무엇인가요?

캐시에 데이터가 있으면 데이터베이스에서 데이터를 가져올 필요가 없으므로 시스템 성능이 크게 향상됩니다.

2. 1차 캐시

2.1 1차 캐시의 작동 원리

처음으로 사용자 ID가 1인 사용자 정보에 대한 쿼리를 시작하는 경우 먼저 ID가 1인 사용자 정보가 있는지 확인합니다. 캐시가 아닌 경우 데이터베이스에서 사용자 정보를 쿼리합니다.

사용자 정보를 가져오고 첫 번째 수준 캐시에 사용자 정보를 저장합니다.

sqlSession이 커밋 작업(삽입, 업데이트, 삭제 수행)을 수행하는 경우 sqlSession에서 첫 번째 수준 캐시를 삭제합니다. 이 작업의 목적은 캐시에 최신 정보를 저장하고 더티 읽기를 방지하는 것입니다.

두 번째로 사용자 ID 1의 사용자 정보를 쿼리하기 위해 전송되며, 먼저 캐시에 ID 1의 사용자 정보가 있는지 확인하고, 캐시에 사용자 정보를 직접 가져옵니다.

2.2 레벨 1 캐시 테스트

Mybatis는 기본적으로 레벨 1 캐시를 지원하며 구성 파일에서 구성할 필요가 없습니다.

위의 첫 번째 수준 캐시 원칙 단계에 따라 테스트하세요.

    @Testpublic void testCache1() throws Exception{
        SqlSession sqlSession=sqlSessionFactory.openSession();
        UserMapper userMapper=sqlSession.getMapper(UserMapper.class);//下边查询使用一个SqlSession//第一次发起请求,查询id为1的用户User user1=userMapper.findUserById(1);
        System.out.println(user1);        //如果sqlSession去执行commit操作(执行插入、更新、删除),清空sqlSession中的一级缓存,//这样做的目的是为了让缓存中存储的是最新的信息,避免脏读。//更新user1的信息user1.setUsername("测试用户22");
        userMapper.updateUser(user1);//执行commit操作去清空缓存        sqlSession.commit();        //第二次发起请求,查询id为1的用户User user2=userMapper.findUserById(1);
        System.out.println(user2);

        sqlSession.close();
    }
로그인 후 복사

2.3 레벨 1 캐시 애플리케이션

은 mybatis와 spring을 통합하여 공식 개발되었으며, 트랜잭션은 서비스에서 제어됩니다.

서비스 메소드에는 많은 Mapper 메소드 호출이 포함됩니다.

service{

  //실행 시작 시 트랜잭션을 시작하고 SqlSession 객체를 생성합니다

  //처음 매퍼 메소드 findUserById(1)가 호출될 때

 

  //두 번째 매퍼 메소드 findUserById( 1) 호출되면 1단계 캐시에서 데이터를 가져옵니다

  //메소드가 종료되고 sqlSession이 닫힙니다

}

동일한 사용자 정보를 쿼리하기 위해 두 개의 서비스 호출이 실행되는 경우 1단계 캐시는 사용되지 않습니다. , 세션 메서드가 종료되고 sqlSession이 닫히기 때문입니다.

3. 2차 캐시

3.1 2차 캐시 원칙

먼저 mybatis의 2차 캐시를 활성화하세요.

sqlSession1은 사용자 ID 1로 사용자 정보를 쿼리합니다. 사용자 정보를 쿼리한 후 쿼리 데이터가 2차 캐시에 저장되어 있다는 것을 후회합니다.

sqlSession3이 동일한 매퍼에서 SQL을 실행하고 커밋 제출을 실행하면 매퍼 아래의 2차 캐시 영역에 있는 데이터가 지워집니다.

sqlSession2는 사용자 ID가 1인 사용자 정보를 쿼리하여 캐시에 데이터가 있는지 확인하고, 데이터가 있으면 캐시에서 직접 가져옵니다.

두 번째 수준 캐시와 첫 번째 수준 캐시의 차이점은 두 번째 수준 캐시의 범위가 더 크고 여러 sqlSession이 UserMapper의 두 번째 수준 캐시 영역을 공유할 수 있다는 것입니다. UserMapper에는 두 번째 수준 캐시 영역(네임스페이스로 구분됨)이 있고 다른 매퍼에도 자체적인 두 번째 수준 캐시 영역(네임스페이스로 구분됨)이 있습니다.

각 네임스페이스 매퍼에는 두 번째 수준 캐시 영역이 있습니다. 두 매퍼의 네임스페이스가 동일한 경우 SQL 쿼리를 실행하는 두 매퍼에서 얻은 데이터는 동일한 두 번째 수준 캐시 영역에 저장됩니다.

3.2 두 번째 수준 캐시 켜기

mybatis의 두 번째 수준 캐시는 SqlMapConfig.xml에서 두 번째 수준 캐시의 기본 스위치를 설정하는 것 외에도 두 번째 수준도 활성화해야 합니다. 특정 mapper.xml에 캐시합니다.

핵심 구성 파일 SqlMapConfig.xml에 추가:

<setting name="cacheEnabled" value="true"/>
로그인 후 복사

Description

허용 값

기본값

cacheEnabled

바로 여기 있습니다. 구성 파일 아래의 캐시는 전역적으로 켜거나 끌 수 있습니다.

참 거짓

在UserMapper.xml中开启二级缓存,UserMapper.xml下的sql执行完成后存储在它的缓存区域(HashMap)。

3.3调用pojo类实现序列化接口

为了将缓存数据取出执行反序列划操作,因为二级缓存数据存储介质多种多样,不一定在内存。可能在硬盘、远程等。

3.4测试方法

    @Testpublic void testCache2() throws Exception{
        SqlSession sqlSession1=sqlSessionFactory.openSession();
        SqlSession sqlSession2=sqlSessionFactory.openSession();
        SqlSession sqlSession3=sqlSessionFactory.openSession();
        
        UserMapper userMapper1=sqlSession1.getMapper(UserMapper.class);
        UserMapper userMapper2=sqlSession2.getMapper(UserMapper.class);
        UserMapper userMapper3=sqlSession3.getMapper(UserMapper.class);        //第一次发起请求,查询id为1的用户User user1=userMapper1.findUserById(1);
        System.out.println(user1);//这里执行关闭操作,将sqlSession中的数据写到二级缓存区域        sqlSession1.close();        //使用sqlSession3执行commit()操作User user=userMapper3.findUserById(1);
        user1.setUsername("Joanna");
        userMapper3.updateUser(user);//执行提交,清空UserMapper下边的二级缓存        sqlSession3.commit();
        sqlSession3.close();        //第二次发起请求,查询id为1的用户User user2=userMapper2.findUserById(1);
        System.out.println(user2);
        sqlSession2.close();
    }
로그인 후 복사

3.5禁用二级缓存

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