(21) Mybatis 1급 조회 캐시
41120 단어 Mybatis
1 레벨 쿼리 캐시
1. mybatis 1급 캐시는 org 기반입니다.apache.ibatis.cache.impl.Perpetual Cache 클래스의HashMap 로컬 캐시, 역할 영역은 Sql Session이다. 즉, 같은 qlsession에서 같은 ql 조회 문장을 두 번 실행하고 첫 번째 실행이 끝난 후에 조회 결과를 캐시에 쓰고 두 번째는 캐시에서 데이터를 직접 얻으며 데이터베이스에 가서 조회할 필요가 없다.2. SqlSession이 끝나면 이 SqlSession의 캐시와 캐시가 존재하지 않습니다. mybatis는 기본적으로 1레벨 캐시를 열고 닫을 수 없습니다.1급 캐시 메모리는 sql 문장의 id에 따라 저장되며 sql의 구체적인 내용에 따라 저장되지 않습니다.
1 레벨 캐시의 존재를 증명하다
여기에 대부분의 코드를 넣지 않고 핵심 코드만 넣습니다. sql의 인터페이스는 다음과 같습니다.
public interface IStudentDao {
public Student selectStudentById(int id);
}
mapper.xml에 대응하는 sql 문장:
<select id="selectStudentById" resultType="Student">
select * from student where id=#{xxx}
select>
유닛 테스트:
@Test
public void testselectStudentById(){
//
Student student=dao.selectStudentById(17);
System.out.println(student);
//
Student student2=dao.selectStudentById(17);
System.out.println(student2);
}
결과적으로 우리는 우리가 한 번의 조회만 실행했고 두 번째 조회를 할 때 바로 가는 1급 캐시를 볼 수 있다. 데이터베이스에 대해 조회를 하지 않았다. 만약에 데이터베이스에 대해 조회를 한다면 sql문장이 출력될 것이다.
[service] 2018-07-21 09:48:22,534 - dao.IStudentDao.selectStudentById -1349 [main] DEBUG dao.IStudentDao.selectStudentById - ==> Preparing: select * from student where id=?
[service] 2018-07-21 09:48:22,635 - dao.IStudentDao.selectStudentById -1450 [main] DEBUG dao.IStudentDao.selectStudentById - ==> Parameters: 17(Integer)
[service] 2018-07-21 09:48:22,677 - dao.IStudentDao.selectStudentById -1492 [main] DEBUG dao.IStudentDao.selectStudentById - <== Total: 1
Student [id=17, name=hello, age=14, score=94.6]
Student [id=17, name=hello, age=14, score=94.6]
캐시에서 데이터를 읽는 근거는 sql의 id입니까, 아니면 sql 자체입니까?
우리는 캐시가 도대체 무엇에 따라 캐시를 하는지 의문이 생겼다. 그러면 우리는 실험을 해야 한다. 서로 다른 id를 가지고 있지만 ql가 완전히 일치하는 두 개의 ql를 쓰면 결과를 알 수 있다.다음은 같은 namespace에서 진행됩니다: sql 인터페이스:
public interface IStudentDao {
public Student selectStudentById(int id);
// id sql
public Student selectStudentById2(int id);
}
mapper 파일:
<mapper namespace="dao.IStudentDao">
<select id="selectStudentById" resultType="Student">
select * from student where id=#{xxx}
select>
<select id="selectStudentById2" resultType="Student">
select * from student where id=#{xxx}
select>
mapper>
테스트 코드:
@Test
public void testDiffereentId2(){
//
Student student=dao.selectStudentById(17);
System.out.println(student);
// , id, namespace
Student student2=dao.selectStudentById2(17);
System.out.println(student2);
}
결과는 다음과 같다. 우리는 안에서 두 번의 sql를 실행한 것을 볼 수 있다. 그러면 1급 캐시가 sql 자체에 근거한 것이 아니라 sql의 id 캐시에 근거한 것이다.
[service] 2018-07-21 10:26:32,844 - dao.IStudentDao.selectStudentById -957 [main] DEBUG dao.IStudentDao.selectStudentById - ==> Preparing: select * from student where id=?
[service] 2018-07-21 10:26:32,954 - dao.IStudentDao.selectStudentById -1067 [main] DEBUG dao.IStudentDao.selectStudentById - ==> Parameters: 17(Integer)
[service] 2018-07-21 10:26:32,989 - dao.IStudentDao.selectStudentById -1102 [main] DEBUG dao.IStudentDao.selectStudentById - <== Total: 1
Student [id=17, name=hello, age=14, score=94.6]
[service] 2018-07-21 10:26:32,990 - dao.IStudentDao.selectStudentById2 -1103 [main] DEBUG dao.IStudentDao.selectStudentById2 - ==> Preparing: select * from student where id=?
[service] 2018-07-21 10:26:32,991 - dao.IStudentDao.selectStudentById2 -1104 [main] DEBUG dao.IStudentDao.selectStudentById2 - ==> Parameters: 17(Integer)
[service] 2018-07-21 10:26:32,996 - dao.IStudentDao.selectStudentById2 -1109 [main] DEBUG dao.IStudentDao.selectStudentById2 - <== Total: 1
Student [id=17, name=hello, age=14, score=94.6]
다른 Namespace의 같은 id는?
다른 Namespace.같은 id라도 1급 캐시가 적용되지 않습니다. 왜냐하면 sql 캐시는namespace에 따라 구분되기 때문입니다.두 개의 ql 인터페이스는 다음과 같습니다.
public interface IStudentDao {
public Student selectStudentById(int id);
}
public interface IStudentDao2 {
// namespace id
public Student selectStudentById(int id);
}
두 개의 마퍼 파일은 다음과 같습니다.
<mapper namespace="dao.IStudentDao">
<select id="selectStudentById" resultType="Student">
select * from student where id=#{xxx}
select>
mapper>
<mapper namespace="dao.IStudentDao2">
<select id="selectStudentById" resultType="Student">
select * from student where id=#{xxx}
select>
mapper>
유닛 테스트는 다음과 같습니다.
@Test
public void testDiffereentNamespaceSameId(){
//
Student student=dao.selectStudentById(17);
System.out.println(student);
// , id, namespace
IStudentDao2 dao2= sqlSession.getMapper(IStudentDao2.class);
Student student2=dao2.selectStudentById(17);
System.out.println(student2);
}
결과는 다음과 같습니다. 우리는 sql를 두 번 실행한 것을 볼 수 있습니다.또한 1급 캐시가 같은namespace 아래의 같은 id에 근거하고 있다는 것을 증명했다. 같은 id라고 해도namespace는 효력이 발생하지 않는다. 왜냐하면 1급 캐시는namespace에 따라 저장을 구분하기 때문이다.
[service] 2018-07-21 10:37:36,916 - dao.IStudentDao.selectStudentById -1545 [main] DEBUG dao.IStudentDao.selectStudentById - ==> Preparing: select * from student where id=?
[service] 2018-07-21 10:37:37,154 - dao.IStudentDao.selectStudentById -1783 [main] DEBUG dao.IStudentDao.selectStudentById - ==> Parameters: 17(Integer)
[service] 2018-07-21 10:37:37,194 - dao.IStudentDao.selectStudentById -1823 [main] DEBUG dao.IStudentDao.selectStudentById - <== Total: 1
Student [id=17, name=hello, age=14, score=94.6]
[service] 2018-07-21 10:37:37,202 - dao.IStudentDao2.selectStudentById -1831 [main] DEBUG dao.IStudentDao2.selectStudentById - ==> Preparing: select * from student where id=?
[service] 2018-07-21 10:37:37,204 - dao.IStudentDao2.selectStudentById -1833 [main] DEBUG dao.IStudentDao2.selectStudentById - ==> Parameters: 17(Integer)
[service] 2018-07-21 10:37:37,210 - dao.IStudentDao2.selectStudentById -1839 [main] DEBUG dao.IStudentDao2.selectStudentById - <== Total: 1
Student [id=17, name=hello, age=14, score=94.6]
1급 캐시에 대한 추가 삭제의 영향
sqlsession을 제출하든지 말든지, 삭제 수정 작업을 추가합니다.commit () 는 쿼리 캐시와 쿼리 캐시를 모두 지우고 쿼리 캐시를 DB에서 다시 쿼리합니다.ql 인터페이스는 다음과 같습니다.
public interface IStudentDao {
public Student selectStudentById(int id);
// id sql
public Student selectStudentById2(int id);
//
public void insertStudent(Student student);
// id
public void deleteStudentById(int id);
//
public void updateStudent(Student student);
}
mapper.xml 파일:
<mapper namespace="dao.IStudentDao">
<select id="selectStudentById" resultType="Student">
select * from student where id=#{xxx}
select>
<select id="selectStudentById2" resultType="Student">
select * from student where id=#{xxx}
select>
<insert id="insertStudent" parameterType="Student">
insert into student(name,age,score) values(#{name},#{age},#{score})
insert>
<delete id="deleteStudentById">
delete from student where id=#{id}
delete>
<update id="updateStudent">
update student set name=#{name},age=#{age},score=#{score} where id=#{id}
update>
mapper>
유닛 테스트:
public void test03(){
//
Student student=dao.selectStudentById(17);
System.out.println(student);
//
Student student1 = new Student("12112",12,21.6);
//dao.insertStudent(student1);
dao.updateStudent(student1);
student=dao.selectStudentById(17);
System.out.println(student);
}
첫 번째 질의를 수행한 후 삽입 작업을 수행하면 다음과 같은 수준의 캐시가 업데이트됩니다.
[service] 2018-07-21 13:07:27,136 - dao.IStudentDao.selectStudentById -1059 [main] DEBUG dao.IStudentDao.selectStudentById - ==> Preparing: select * from student where id=?
[service] 2018-07-21 13:07:27,247 - dao.IStudentDao.selectStudentById -1170 [main] DEBUG dao.IStudentDao.selectStudentById - ==> Parameters: 17(Integer)
[service] 2018-07-21 13:07:27,288 - dao.IStudentDao.selectStudentById -1211 [main] DEBUG dao.IStudentDao.selectStudentById - <== Total: 1
Student [id=17, name=hello, age=14, score=94.6]
[service] 2018-07-21 13:07:27,289 - dao.IStudentDao.insertStudent -1212 [main] DEBUG dao.IStudentDao.insertStudent - ==> Preparing: insert into student(name,age,score) values(?,?,?)
[service] 2018-07-21 13:07:27,291 - dao.IStudentDao.insertStudent -1214 [main] DEBUG dao.IStudentDao.insertStudent - ==> Parameters: 12112(String), 12(Integer), 21.6(Double)
[service] 2018-07-21 13:07:27,295 - dao.IStudentDao.insertStudent -1218 [main] DEBUG dao.IStudentDao.insertStudent - <== Updates: 1
[service] 2018-07-21 13:07:27,295 - dao.IStudentDao.selectStudentById -1218 [main] DEBUG dao.IStudentDao.selectStudentById - ==> Preparing: select * from student where id=?
[service] 2018-07-21 13:07:27,295 - dao.IStudentDao.selectStudentById -1218 [main] DEBUG dao.IStudentDao.selectStudentById - ==> Parameters: 17(Integer)
[service] 2018-07-21 13:07:27,302 - dao.IStudentDao.selectStudentById -1225 [main] DEBUG dao.IStudentDao.selectStudentById - <== Total: 1
Student [id=17, name=hello, age=14, score=94.6]
첫 번째 쿼리를 수행한 후 다시 업데이트 작업을 수행합니다. 쿼리 데이터가 아니더라도 같은 테이블에 속하고 1레벨 캐시가 업데이트됩니다.
[service] 2018-07-21 23:43:28,073 - dao.IStudentDao.selectStudentById -1081 [main] DEBUG dao.IStudentDao.selectStudentById - ==> Preparing: select * from student where id=?
[service] 2018-07-21 23:43:28,202 - dao.IStudentDao.selectStudentById -1210 [main] DEBUG dao.IStudentDao.selectStudentById - ==> Parameters: 17(Integer)
[service] 2018-07-21 23:43:28,236 - dao.IStudentDao.selectStudentById -1244 [main] DEBUG dao.IStudentDao.selectStudentById - <== Total: 1
Student [id=17, name=hello, age=14, score=94.6]
[service] 2018-07-21 23:43:28,239 - dao.IStudentDao.updateStudent -1247 [main] DEBUG dao.IStudentDao.updateStudent - ==> Preparing: update student set name=?,age=?,score=? where id=?
[service] 2018-07-21 23:43:28,241 - dao.IStudentDao.updateStudent -1249 [main] DEBUG dao.IStudentDao.updateStudent - ==> Parameters: 12112(String), 12(Integer), 21.6(Double), 18(Integer)
[service] 2018-07-21 23:43:28,246 - dao.IStudentDao.updateStudent -1254 [main] DEBUG dao.IStudentDao.updateStudent - <== Updates: 1
[service] 2018-07-21 23:43:28,246 - dao.IStudentDao.selectStudentById -1254 [main] DEBUG dao.IStudentDao.selectStudentById - ==> Preparing: select * from student where id=?
[service] 2018-07-21 23:43:28,246 - dao.IStudentDao.selectStudentById -1254 [main] DEBUG dao.IStudentDao.selectStudentById - ==> Parameters: 17(Integer)
[service] 2018-07-21 23:43:28,251 - dao.IStudentDao.selectStudentById -1259 [main] DEBUG dao.IStudentDao.selectStudentById - <== Total: 1
Student [id=17, name=hello, age=14, score=94.6]
쿼리 작업을 수행한 후 삭제 작업을 수행하면 레벨1 캐시도 업데이트됩니다.
[service] 2018-07-21 23:44:49,296 - dao.IStudentDao.selectStudentById -1172 [main] DEBUG dao.IStudentDao.selectStudentById - ==> Preparing: select * from student where id=?
[service] 2018-07-21 23:44:49,457 - dao.IStudentDao.selectStudentById -1333 [main] DEBUG dao.IStudentDao.selectStudentById - ==> Parameters: 17(Integer)
[service] 2018-07-21 23:44:49,504 - dao.IStudentDao.selectStudentById -1380 [main] DEBUG dao.IStudentDao.selectStudentById - <== Total: 1
Student [id=17, name=hello, age=14, score=94.6]
[service] 2018-07-21 23:44:49,505 - dao.IStudentDao.deleteStudentById -1381 [main] DEBUG dao.IStudentDao.deleteStudentById - ==> Preparing: delete from student where id=?
[service] 2018-07-21 23:44:49,505 - dao.IStudentDao.deleteStudentById -1381 [main] DEBUG dao.IStudentDao.deleteStudentById - ==> Parameters: 18(Integer)
[service] 2018-07-21 23:44:49,508 - dao.IStudentDao.deleteStudentById -1384 [main] DEBUG dao.IStudentDao.deleteStudentById - <== Updates: 1
[service] 2018-07-21 23:44:49,509 - dao.IStudentDao.selectStudentById -1385 [main] DEBUG dao.IStudentDao.selectStudentById - ==> Preparing: select * from student where id=?
[service] 2018-07-21 23:44:49,509 - dao.IStudentDao.selectStudentById -1385 [main] DEBUG dao.IStudentDao.selectStudentById - ==> Parameters: 17(Integer)
[service] 2018-07-21 23:44:49,517 - dao.IStudentDao.selectStudentById -1393 [main] DEBUG dao.IStudentDao.selectStudentById - <== Total: 1
Student [id=17, name=hello, age=14, score=94.6]
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
SpringMVC와 Mybatis 집합은 호출 저장 프로세스, 사무 제어 실례를 실현한다SSM 프레임워크에서 호출 데이터베이스의 저장 프로세스와 사무 제어에 자주 사용되는데 다음은 증빙서류를 저장하는 예를 들어 소개한다. 1. Oracle에 저장된 프로세스 코드는 다음과 같습니다(주요 논리는 증빙 서류...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.