mybatis缓存:一级缓存和二级缓存

hibernate缓存:一级缓存和二级缓存

关于缓存:

缓存是介于物理数据源与应用程序之间,是对数据库中的数据复制一份临时放在内存中的容器,

其作用是为了减少应用程序对物理数据源访问的次数,从而提高了应用程序的运行性能。

Hibernate在进行读取数据的时候,根据缓存机制在相应的缓存中查询,如果在缓存中找到了需要的数据(我们把这称做“缓存命 中"),

则就直接把命中的数据作为结果加以利用,避免了大量发送SQL语句到数据库查询的性能损耗。

一般我们在项目整合中 存在数据访问的性能问题,研究了下缓存在各个阶段的应用,以在5个方面进行缓存的设计:

1.最底层可以配置的是MySQL自带的query cache,

2.mybatis的一级缓存,默认情况下都处于开启状态,只能使用自带的PerpetualCache,无法配置第三方缓存

3.mybatis的二级缓存,可以配置开关状态,默认使用自带的PerpetualCache,但功能比较弱,能够配置第三方缓存,

4.service层的缓存配置,结合spring,可以灵活进行选择

5.hibernate的一级缓存,默认也是开启状态,session级别的,可以自由使用。但这里注意下hibernate获取session的 方式。

6.hibernate的二级缓存需要引用 第三方的 插件,并在hibernate配置文件中进行相应的配置。

7.针对实际业务情况,直接缓存部分html页面,直接返回给客户端。

发现在整合的项目测试中被spring整合的mybatis和hibernate的一级缓存都失效了。

首先1.mybatis和hibernate的一级缓存生效的范围是sqlsession,是为了在sqlsession没有关闭时,业务需要重复查询相同数据使用的。一旦sqlsession关闭,则由这个sqlsession缓存的数据将会被清空。

spring管理的mybatis

 @Test
public void TestBi(){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
BillService service=(BillService)context.getBean("billServiceImpl"); List<Bill> alls = service.findAlls();
System.out.println("-----------------------------------------------");
List<Bill> a = service.findAlls();
System.out.println(alls.size());
}
applicationContext.xml是我spring的配置文件,管理session
测试结果:
ogging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter.
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@144e54da] was not registered for synchronization because synchronization is not active
JDBC Connection [285401532, URL=jdbc:mysql:///supermarket_ssh, UserName=root@localhost, MySQL Connector Java] will not be managed by Spring
==> Preparing: select * from bill
==> Parameters:
<== Columns: bid, bmoney, bname, createtime, paystate, supId, hscode, scount, sunit
<== Row: 24, 150262, 猕猴桃山西, 2017-09-06, 1, 3, ssh-code, 1000, bdss
<== Row: 26, 1500, 苹果梨山西, 2017-08-25, 0, 1, ssh-code, 50, bdss
<== Row: 27, 150262, 苹果梨山西, 2017-08-25, 0, 1, ssh-code, 1000, bdss
<== Row: 29, 2561, xx, 2017-08-25, 0, 1, ssh-code, 0, bdss
<== Row: 30, 3642, aa, 2017-08-25, 0, 1, ssh-code, 1000, 56ds3fs
<== Row: 31, 0, bb, 2017-08-25, 0, 3, ssh-code, 52, bdss
<== Row: 33, 3335, aa, 2017-08-25, 0, 3, ssh-code, 1000, 56ds3fs
<== Row: 41, 2000, 小炒肉, 2017-09-03, 1, 3, ssh-code, 100, bdqn
<== Row: 42, 0, zahngyu, 2017-09-03, 1, 12, ssh-code, 100, bdqn
<== Row: 44, 200, 共百搭, 2017-09-06, 1, 3, dsfas, 15, dfa
<== Row: 45, 5000, 张雨张雨, 2017-09-06, 0, 14, ssh-supmarket, 50, bdqn
<== Row: 49, 0, dfaf, 2017-09-09, 0, 1, s-code, 3, dfa
<== Row: 50, 0, 宫保鸡丁, 2017-09-10, 0, 1, gbjd-code, 2, bdqn
<== Row: 52, 0, f'da, 2017-09-10, 1, 1, f'da, 5, f'da
<== Row: 55, 0, hznagu, 2017-09-10, 1, 1, ssh-code, 25, bdqn
<== Row: 56, 0, 宫保鸡丁, 2017-09-10, 0, 1, ssj-code, 2, bdqn
<== Row: 57, 0, dfa, 2017-09-10, 1, 1, dfa, 2, fda
<== Row: 58, 0, fda, 2017-09-10, 0, 1, dfa, 25, dfa
<== Row: 59, 0, dfa, 2017-09-10, 0, 1, fda, 2, dfa
<== Total: 19
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@144e54da]
19
-----------------------------------------------
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@d68b796] was not registered for synchronization because synchronization is not active
JDBC Connection [1441587130, URL=jdbc:mysql:///supermarket_ssh, UserName=root@localhost, MySQL Connector Java] will not be managed by Spring
==> Preparing: select * from bill
==> Parameters:
<== Columns: bid, bmoney, bname, createtime, paystate, supId, hscode, scount, sunit
<== Row: 24, 150262, 猕猴桃山西, 2017-09-06, 1, 3, ssh-code, 1000, bdss
<== Row: 26, 1500, 苹果梨山西, 2017-08-25, 0, 1, ssh-code, 50, bdss
<== Row: 27, 150262, 苹果梨山西, 2017-08-25, 0, 1, ssh-code, 1000, bdss
<== Row: 29, 2561, xx, 2017-08-25, 0, 1, ssh-code, 0, bdss
<== Row: 30, 3642, aa, 2017-08-25, 0, 1, ssh-code, 1000, 56ds3fs
<== Row: 31, 0, bb, 2017-08-25, 0, 3, ssh-code, 52, bdss
<== Row: 33, 3335, aa, 2017-08-25, 0, 3, ssh-code, 1000, 56ds3fs
<== Row: 41, 2000, 小炒肉, 2017-09-03, 1, 3, ssh-code, 100, bdqn
<== Row: 42, 0, zahngyu, 2017-09-03, 1, 12, ssh-code, 100, bdqn
<== Row: 44, 200, 共百搭, 2017-09-06, 1, 3, dsfas, 15, dfa
<== Row: 45, 5000, 张雨张雨, 2017-09-06, 0, 14, ssh-supmarket, 50, bdqn
<== Row: 49, 0, dfaf, 2017-09-09, 0, 1, s-code, 3, dfa
<== Row: 50, 0, 宫保鸡丁, 2017-09-10, 0, 1, gbjd-code, 2, bdqn
<== Row: 52, 0, f'da, 2017-09-10, 1, 1, f'da, 5, f'da
<== Row: 55, 0, hznagu, 2017-09-10, 1, 1, ssh-code, 25, bdqn
<== Row: 56, 0, 宫保鸡丁, 2017-09-10, 0, 1, ssj-code, 2, bdqn
<== Row: 57, 0, dfa, 2017-09-10, 1, 1, dfa, 2, fda
<== Row: 58, 0, fda, 2017-09-10, 0, 1, dfa, 25, dfa
<== Row: 59, 0, dfa, 2017-09-10, 0, 1, fda, 2, dfa
<== Total: 19
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@d68b796]
[entity.Bill@6afd9125, entity.Bill@2d444b03, entity.Bill@5e98c92c, entity.Bill@bf9839, entity.Bill@22a2c691, entity.Bill@6c9a6b5a, entity.Bill@dfe196a, entity.Bill@25368553, entity.Bill@1e6b1f3b, entity.Bill@acf6a17, entity.Bill@373e118c, entity.Bill@4bf21aa9, entity.Bill@3b47433, entity.Bill@3c38c22b, entity.Bill@3253b3f0, entity.Bill@154a6b60, entity.Bill@48cf768b, entity.Bill@2c6fc505, entity.Bill@5defe20d]

测试结果有点多啊但明显是没有使用到mybatis的一级缓存。

如果我们使用mybatis自己管理的session来看下测试结果

@Test
public void TestBi(){ SqlSession session = MyBatisUtil.getSessionTwo(); BillDao mapper = session.getMapper(BillDao.class);
List<Bill> b1 = mapper.findAlls();
System.out.println(b1.size());
List<Bill> b2 = mapper.findAlls();
System.out.println(b2.size());
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@6d20ec1b]
==> Preparing: select * from bill
==> Parameters:
<== Columns: bid, bmoney, bname, createtime, paystate, supId, hscode, scount, sunit
<== Row: 24, 150262, 猕猴桃山西, 2017-09-06, 1, 3, ssh-code, 1000, bdss
<== Row: 26, 1500, 苹果梨山西, 2017-08-25, 0, 1, ssh-code, 50, bdss
<== Row: 27, 150262, 苹果梨山西, 2017-08-25, 0, 1, ssh-code, 1000, bdss
<== Row: 29, 2561, xx, 2017-08-25, 0, 1, ssh-code, 0, bdss
<== Row: 30, 3642, aa, 2017-08-25, 0, 1, ssh-code, 1000, 56ds3fs
<== Row: 31, 0, bb, 2017-08-25, 0, 3, ssh-code, 52, bdss
<== Row: 33, 3335, aa, 2017-08-25, 0, 3, ssh-code, 1000, 56ds3fs
<== Row: 41, 2000, 小炒肉, 2017-09-03, 1, 3, ssh-code, 100, bdqn
<== Row: 42, 0, zahngyu, 2017-09-03, 1, 12, ssh-code, 100, bdqn
<== Row: 44, 200, 共百搭, 2017-09-06, 1, 3, dsfas, 15, dfa
<== Row: 45, 5000, 张雨张雨, 2017-09-06, 0, 14, ssh-supmarket, 50, bdqn
<== Row: 49, 0, dfaf, 2017-09-09, 0, 1, s-code, 3, dfa
<== Row: 50, 0, 宫保鸡丁, 2017-09-10, 0, 1, gbjd-code, 2, bdqn
<== Row: 52, 0, f'da, 2017-09-10, 1, 1, f'da, 5, f'da
<== Row: 55, 0, hznagu, 2017-09-10, 1, 1, ssh-code, 25, bdqn
<== Row: 56, 0, 宫保鸡丁, 2017-09-10, 0, 1, ssj-code, 2, bdqn
<== Row: 57, 0, dfa, 2017-09-10, 1, 1, dfa, 2, fda
<== Row: 58, 0, fda, 2017-09-10, 0, 1, dfa, 25, dfa
<== Row: 59, 0, dfa, 2017-09-10, 0, 1, fda, 2, dfa
<== Total: 19
19
19

很明显,只访问了一次数据库,说明单独使用mybatis的 一级缓存是 有效的。

再看看hibernate和 spring整和的情况下,测试hibernate的一级缓存:

@org.junit.Test
public void TestOneCache(){ //被spring管理的hibernate 一级缓存失效
ApplicationContext context = new ClassPathXmlApplicationContext("spring-hiberanate.xml");
BillService service= (BillService)context.getBean("billServiceImpl");
List<Bill> allBills = service.findAllBills();
System.out.println(allBills.size());
System.out.println("---------------------------------");
List<Bill> allBillss = service.findAllBills();
System.out.println(allBillss.size()); }

测试结果:

Hibernate: select bill0_.bid as bid1_1_, bill0_.bmoney as bmoney2_1_, bill0_.bname as bname3_1_, bill0_.createtime as createti4_1_, bill0_.hscode as hscode5_1_, bill0_.paystate as paystate6_1_, bill0_.scount as scount7_1_, bill0_.sunit as sunit8_1_, bill0_.supId as supId9_1_ from bill bill0_
Hibernate: select supplier0_.supId as supId1_2_0_, supplier0_.createtime as createti2_2_0_, supplier0_.supName as supName3_2_0_, supplier0_.supUserName as supUserN4_2_0_, supplier0_.supUserTel as supUserT5_2_0_, supplier0_.supcode as supcode6_2_0_, supplier0_.supfax as supfax7_2_0_ from supplier supplier0_ where supplier0_.supId=?
Hibernate: select supplier0_.supId as supId1_2_0_, supplier0_.createtime as createti2_2_0_, supplier0_.supName as supName3_2_0_, supplier0_.supUserName as supUserN4_2_0_, supplier0_.supUserTel as supUserT5_2_0_, supplier0_.supcode as supcode6_2_0_, supplier0_.supfax as supfax7_2_0_ from supplier supplier0_ where supplier0_.supId=?
Hibernate: select supplier0_.supId as supId1_2_0_, supplier0_.createtime as createti2_2_0_, supplier0_.supName as supName3_2_0_, supplier0_.supUserName as supUserN4_2_0_, supplier0_.supUserTel as supUserT5_2_0_, supplier0_.supcode as supcode6_2_0_, supplier0_.supfax as supfax7_2_0_ from supplier supplier0_ where supplier0_.supId=?
Hibernate: select supplier0_.supId as supId1_2_0_, supplier0_.createtime as createti2_2_0_, supplier0_.supName as supName3_2_0_, supplier0_.supUserName as supUserN4_2_0_, supplier0_.supUserTel as supUserT5_2_0_, supplier0_.supcode as supcode6_2_0_, supplier0_.supfax as supfax7_2_0_ from supplier supplier0_ where supplier0_.supId=?
19
---------------------------------
Hibernate: select bill0_.bid as bid1_1_, bill0_.bmoney as bmoney2_1_, bill0_.bname as bname3_1_, bill0_.createtime as createti4_1_, bill0_.hscode as hscode5_1_, bill0_.paystate as paystate6_1_, bill0_.scount as scount7_1_, bill0_.sunit as sunit8_1_, bill0_.supId as supId9_1_ from bill bill0_
Hibernate: select supplier0_.supId as supId1_2_0_, supplier0_.createtime as createti2_2_0_, supplier0_.supName as supName3_2_0_, supplier0_.supUserName as supUserN4_2_0_, supplier0_.supUserTel as supUserT5_2_0_, supplier0_.supcode as supcode6_2_0_, supplier0_.supfax as supfax7_2_0_ from supplier supplier0_ where supplier0_.supId=?
Hibernate: select supplier0_.supId as supId1_2_0_, supplier0_.createtime as createti2_2_0_, supplier0_.supName as supName3_2_0_, supplier0_.supUserName as supUserN4_2_0_, supplier0_.supUserTel as supUserT5_2_0_, supplier0_.supcode as supcode6_2_0_, supplier0_.supfax as supfax7_2_0_ from supplier supplier0_ where supplier0_.supId=?
Hibernate: select supplier0_.supId as supId1_2_0_, supplier0_.createtime as createti2_2_0_, supplier0_.supName as supName3_2_0_, supplier0_.supUserName as supUserN4_2_0_, supplier0_.supUserTel as supUserT5_2_0_, supplier0_.supcode as supcode6_2_0_, supplier0_.supfax as supfax7_2_0_ from supplier supplier0_ where supplier0_.supId=?
Hibernate: select supplier0_.supId as supId1_2_0_, supplier0_.createtime as createti2_2_0_, supplier0_.supName as supName3_2_0_, supplier0_.supUserName as supUserN4_2_0_, supplier0_.supUserTel as supUserT5_2_0_, supplier0_.supcode as supcode6_2_0_, supplier0_.supfax as supfax7_2_0_ from supplier supplier0_ where supplier0_.supId=?
19

和mybatis一样,被spring管理的hibernate 的一级缓存无效。说明问题 出在spring身上。

先看下spring整合mybatis,sessionFactory是由mybatis提供的,进入sqlSessionFactory类内部。

/**
* Copyright 2009-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ibatis.session; import java.sql.Connection; /**
* Creates an {@link SqlSesion} out of a connection or a DataSource
*
* @author Clinton Begin
*/
public interface SqlSessionFactory { SqlSession openSession(); SqlSession openSession(boolean autoCommit);
SqlSession openSession(Connection connection);
SqlSession openSession(TransactionIsolationLevel level); SqlSession openSession(ExecutorType execType);
SqlSession openSession(ExecutorType execType, boolean autoCommit);
SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level);
SqlSession openSession(ExecutorType execType, Connection connection); Configuration getConfiguration(); }

然后找到它的一个实现类,sqlsessionManager,它同时还实现了SqlSession

**
* @author Larry Meadors
*/
public class SqlSessionManager implements SqlSessionFactory, SqlSession { private final SqlSessionFactory sqlSessionFactory;
private final SqlSession sqlSessionProxy; private ThreadLocal<SqlSession> localSqlSession = new ThreadLocal<SqlSession>(); private SqlSessionManager(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
this.sqlSessionProxy = (SqlSession) Proxy.newProxyInstance(
SqlSessionFactory.class.getClassLoader(),
new Class[]{SqlSession.class},
new SqlSessionInterceptor());
}

private ThreadLocal<SqlSession> localSqlSession = new ThreadLocal<SqlSession>();这个是让session和当前的线程绑定

关于一级缓存失效的原因还要看他的另一个方法,实现自SqlSession

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
final SqlSession sqlSession = SqlSessionManager.this.localSqlSession.get();
if (sqlSession != null) {
try {
return method.invoke(sqlSession, args);
} catch (Throwable t) {
throw ExceptionUtil.unwrapThrowable(t);
}
} else {
final SqlSession autoSqlSession = openSession();
try {
final Object result = method.invoke(autoSqlSession, args);
autoSqlSession.commit();
return result;
} catch (Throwable t) {
autoSqlSession.rollback();
throw ExceptionUtil.unwrapThrowable(t);
} finally {
autoSqlSession.close();
}
}
}
//这是close方法
@Override
public void close() {
final SqlSession sqlSession = localSqlSession.get();
if (sqlSession == null) {
throw new SqlSessionException("Error: Cannot close. No managed session is started.");
}
try {
sqlSession.close();
} finally {
localSqlSession.set(null); //释放线程
}
}

看下红色部分的代码,当一个非空的session传过来,重新 opensession() 在代码执行到最后执行autoSqlSession.close()方法,关闭session,释放线程,跳出递归;

大致总结一下:

session和当前线程绑定的过程以及mybatis失效的原因

1,获得请求

2,spring检查到了这种需求,于是去申请一个mybatis的sqlsession(资源池),并将申请到的sqlsession与当前线程绑定,放入threadlocal里面

3,template从threadlocal获取到sqlsession,去执行查询

4,查询结束,清空threadlocal中与当前线程绑定的sqlsession,释放资源

5,我们又需要访问数据,拿到新的session

6,返回到步骤2

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 @org.junit.Test
public void TestOneCache(){ //没有被spring管理使用一级缓存
Session session = HibernateUtil.currentSession();
System.out.println(session);
List<Bill> list=session.createQuery( "from Bill ").list();
System.out.println(list.size());
List<Bill> lists = session.createQuery( "from Bill ").list();
System.out.println(lists.size()); //被spring管理的hibernate 一级缓存失效
/*ApplicationContext context = new ClassPathXmlApplicationContext("spring-hiberanate.xml");
BillService service= (BillService)context.getBean("billServiceImpl");
List<Bill> allBills = service.findAllBills();
System.out.println(allBills.size());
System.out.println("---------------------------------");
List<Bill> allBillss = service.findAllBills();
System.out.println(allBillss.size());*/ }

很明显走的缓存

Hibernate:
select
bill0_.bid as bid1_1_,
bill0_.bmoney as bmoney2_1_,
bill0_.bname as bname3_1_,
bill0_.createtime as createti4_1_,
bill0_.hscode as hscode5_1_,
bill0_.paystate as paystate6_1_,
bill0_.scount as scount7_1_,
bill0_.sunit as sunit8_1_,
bill0_.supId as supId9_1_
from
bill bill0_
Hibernate:
select
supplier0_.supId as supId1_2_0_,
supplier0_.createtime as createti2_2_0_,
supplier0_.supName as supName3_2_0_,
supplier0_.supUserName as supUserN4_2_0_,
supplier0_.supUserTel as supUserT5_2_0_,
supplier0_.supcode as supcode6_2_0_,
supplier0_.supfax as supfax7_2_0_
from
supplier supplier0_
where
supplier0_.supId=?
Hibernate:
select
supplier0_.supId as supId1_2_0_,
supplier0_.createtime as createti2_2_0_,
supplier0_.supName as supName3_2_0_,
supplier0_.supUserName as supUserN4_2_0_,
supplier0_.supUserTel as supUserT5_2_0_,
supplier0_.supcode as supcode6_2_0_,
supplier0_.supfax as supfax7_2_0_
from
supplier supplier0_
where
supplier0_.supId=?
Hibernate:
select
supplier0_.supId as supId1_2_0_,
supplier0_.createtime as createti2_2_0_,
supplier0_.supName as supName3_2_0_,
supplier0_.supUserName as supUserN4_2_0_,
supplier0_.supUserTel as supUserT5_2_0_,
supplier0_.supcode as supcode6_2_0_,
supplier0_.supfax as supfax7_2_0_
from
supplier supplier0_
where
supplier0_.supId=?
Hibernate:
select
supplier0_.supId as supId1_2_0_,
supplier0_.createtime as createti2_2_0_,
supplier0_.supName as supName3_2_0_,
supplier0_.supUserName as supUserN4_2_0_,
supplier0_.supUserTel as supUserT5_2_0_,
supplier0_.supcode as supcode6_2_0_,
supplier0_.supfax as supfax7_2_0_
from
supplier supplier0_
where
supplier0_.supId=?
19
Hibernate:
select
bill0_.bid as bid1_1_,
bill0_.bmoney as bmoney2_1_,
bill0_.bname as bname3_1_,
bill0_.createtime as createti4_1_,
bill0_.hscode as hscode5_1_,
bill0_.paystate as paystate6_1_,
bill0_.scount as scount7_1_,
bill0_.sunit as sunit8_1_,
bill0_.supId as supId9_1_
from
bill bill0_
19

--被spring管理的hibernate缓存

 @org.junit.Test
public void TestOneCache(){ //被spring管理的hibernate 一级缓存失效
ApplicationContext context = new ClassPathXmlApplicationContext("spring-hiberanate.xml");
BillService service= (BillService)context.getBean("billServiceImpl");
List<Bill> allBills = service.findAllBills();
System.out.println(allBills.size());
System.out.println("---------------------------------");
List<Bill> allBillss = service.findAllBills();
System.out.println(allBillss.size()); }
Hibernate: select bill0_.bid as bid1_1_, bill0_.bmoney as bmoney2_1_, bill0_.bname as bname3_1_, bill0_.createtime as createti4_1_, bill0_.hscode as hscode5_1_, bill0_.paystate as paystate6_1_, bill0_.scount as scount7_1_, bill0_.sunit as sunit8_1_, bill0_.supId as supId9_1_ from bill bill0_
Hibernate: select supplier0_.supId as supId1_2_0_, supplier0_.createtime as createti2_2_0_, supplier0_.supName as supName3_2_0_, supplier0_.supUserName as supUserN4_2_0_, supplier0_.supUserTel as supUserT5_2_0_, supplier0_.supcode as supcode6_2_0_, supplier0_.supfax as supfax7_2_0_ from supplier supplier0_ where supplier0_.supId=?
Hibernate: select supplier0_.supId as supId1_2_0_, supplier0_.createtime as createti2_2_0_, supplier0_.supName as supName3_2_0_, supplier0_.supUserName as supUserN4_2_0_, supplier0_.supUserTel as supUserT5_2_0_, supplier0_.supcode as supcode6_2_0_, supplier0_.supfax as supfax7_2_0_ from supplier supplier0_ where supplier0_.supId=?
Hibernate: select supplier0_.supId as supId1_2_0_, supplier0_.createtime as createti2_2_0_, supplier0_.supName as supName3_2_0_, supplier0_.supUserName as supUserN4_2_0_, supplier0_.supUserTel as supUserT5_2_0_, supplier0_.supcode as supcode6_2_0_, supplier0_.supfax as supfax7_2_0_ from supplier supplier0_ where supplier0_.supId=?
Hibernate: select supplier0_.supId as supId1_2_0_, supplier0_.createtime as createti2_2_0_, supplier0_.supName as supName3_2_0_, supplier0_.supUserName as supUserN4_2_0_, supplier0_.supUserTel as supUserT5_2_0_, supplier0_.supcode as supcode6_2_0_, supplier0_.supfax as supfax7_2_0_ from supplier supplier0_ where supplier0_.supId=?
19
---------------------------------
Hibernate: select bill0_.bid as bid1_1_, bill0_.bmoney as bmoney2_1_, bill0_.bname as bname3_1_, bill0_.createtime as createti4_1_, bill0_.hscode as hscode5_1_, bill0_.paystate as paystate6_1_, bill0_.scount as scount7_1_, bill0_.sunit as sunit8_1_, bill0_.supId as supId9_1_ from bill bill0_
Hibernate: select supplier0_.supId as supId1_2_0_, supplier0_.createtime as createti2_2_0_, supplier0_.supName as supName3_2_0_, supplier0_.supUserName as supUserN4_2_0_, supplier0_.supUserTel as supUserT5_2_0_, supplier0_.supcode as supcode6_2_0_, supplier0_.supfax as supfax7_2_0_ from supplier supplier0_ where supplier0_.supId=?
Hibernate: select supplier0_.supId as supId1_2_0_, supplier0_.createtime as createti2_2_0_, supplier0_.supName as supName3_2_0_, supplier0_.supUserName as supUserN4_2_0_, supplier0_.supUserTel as supUserT5_2_0_, supplier0_.supcode as supcode6_2_0_, supplier0_.supfax as supfax7_2_0_ from supplier supplier0_ where supplier0_.supId=?
Hibernate: select supplier0_.supId as supId1_2_0_, supplier0_.createtime as createti2_2_0_, supplier0_.supName as supName3_2_0_, supplier0_.supUserName as supUserN4_2_0_, supplier0_.supUserTel as supUserT5_2_0_, supplier0_.supcode as supcode6_2_0_, supplier0_.supfax as supfax7_2_0_ from supplier supplier0_ where supplier0_.supId=?
Hibernate: select supplier0_.supId as supId1_2_0_, supplier0_.createtime as createti2_2_0_, supplier0_.supName as supName3_2_0_, supplier0_.supUserName as supUserN4_2_0_, supplier0_.supUserTel as supUserT5_2_0_, supplier0_.supcode as supcode6_2_0_, supplier0_.supfax as supfax7_2_0_ from supplier supplier0_ where supplier0_.supId=?
19

一级缓存失效

然后看下spring集成的hibernate配置文件,spring+hibernate的sessionFactory是交给spring来管理的,进入配置文件 找到LocalSessionFactory

 <bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan">
<list>
<value>zy.entity</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
   private static final ThreadLocal<Session> thread=new ThreadLocal<Session>();

hibernate有两个方法获取session,一个是openSession(),一个是getCurrentSession()

a:getCurrentSession创建的session会绑定到当前线程,而openSession不会。

b:getCurrentSession创建的线程会在事务回滚或事务提交后自动关闭,而openSession必须手动关闭

 public Session openSession() throws HibernateException {
return this.withOptions().openSession();
} public Session openTemporarySession() throws HibernateException {
return this.withOptions().autoClose(false).flushBeforeCompletion(false).connectionReleaseMode(ConnectionReleaseMode.AFTER_STATEMENT).openSession();
}
 public SessionBuilder autoClose(boolean autoClose) {
this.autoClose = autoClose;
return this;
}
 public SessionBuilder flushBeforeCompletion(boolean flushBeforeCompletion) {
this.flushBeforeCompletion = flushBeforeCompletion;
return this;
}

--翻了下他的源码,感觉获得session的过程像个迷宫似的,翻着翻着回来了,貌似回调,不懂,不过我觉得,他是根据请求每次获得session时都“冲洗了”一下,但是我用工具类得到的session也是这样啊

不知道spring到底对hibernate干了什么,让一级缓存失效。你tm到底干了什么??????/

----希望知道的分享一下 ,非常感谢。

spring管理hibernate,mybatis,一级缓存失效原因的更多相关文章

  1. spring整合mybatis后,mybatis一级缓存失效的原因

    一般来说,可以在5个方面进行缓存的设计: 最底层可以配置的是数据库自带的query cache, mybatis的一级缓存,默认情况下都处于开启状态,只能使用自带的PerpetualCache,无法配 ...

  2. ssh整合hibernate 使用spring管理hibernate二级缓存,配置hibernate4.0以上二级缓存

    ssh整合hibernate 使用spring管理hibernate二级缓存,配置hibernate4.0以上二级缓存 hibernate  : Hibernate是一个持久层框架,经常访问物理数据库 ...

  3. Mybatis一级缓存和二级缓存 Redis缓存

    一级缓存 Mybatis的一级缓存存放在SqlSession的生命周期,在同一个SqlSession中查询时,Mybatis会把执行的方法和参数通过算法生成缓存的键值,将键值和查询结果存入一个Map对 ...

  4. MyBatis之一级缓存及其一级缓存失效

    定义: 一级缓存:本地缓存:与数据库同一次会话(sqlSession)期间查询到的数据会放在本地缓存中,如果以后要获取相同的数据直接从缓存中获取,不会再次向数据库查询数据一个SqlSession拥有一 ...

  5. 四 Hibernate的一级缓存&事务管理及其配置

    持久态对象: 自动更新数据库,原理是一级缓存. 缓存:是一种优化的方式,将数据存入内存,从缓存/内存中获取,不用通过存储源 Hibernate框架中提供了优化手段:缓存,抓取策略 Hibernate中 ...

  6. Mybaits 源码解析 (十二)----- Mybatis的事务如何被Spring管理?Mybatis和Spring事务中用的Connection是同一个吗?

    不知道一些同学有没有这种疑问,为什么Mybtis中要配置dataSource,Spring的事务中也要配置dataSource?那么Mybatis和Spring事务中用的Connection是同一个吗 ...

  7. java-mybaits-014-数据库缓存设计【querycache、mybatis一级缓存、二级缓存】

    一.概述 一般来说,可以在5个方面进行缓存的设计: 1.最底层可以配置的是数据库自带的query cache, 2.mybatis的一级缓存,默认情况下都处于开启状态,只能使用自带的Perpetual ...

  8. Spring管理Hibernate

    为什么要用Hibernate框架? 既然用Hibernate框架访问管理持久层,那为何又提到用Spring来管理以及整合Hibernate呢? 首先我们来看一下Hibernate进行操作的步骤.比如添 ...

  9. MyBatis一级缓存引起的无穷递归

    MyBatis一级缓存引起的无穷递归 引言: 最近在项目中参与了一个领取优惠劵的活动,当多个用户领取同一张优惠劵的时候,使用了数据库锁控制并发,起初的设想是:如果多个人同时领一张劵,第一个到达的人领取 ...

随机推荐

  1. Hyperledger Fabric CA User’s Guide——概述(二)

    概述 下面的图表说明了如何将Hyperledger Fabric CA与总体的Hyperledger Fabric结构相匹配. 有两种方式与一种Hyperledger Fabric CA服务器进行交互 ...

  2. Plasma Cash 合约解读

    作者介绍 虫洞社区·签约作者 steven bai Plasma Cash 合约解读 Plasma Cash 合约解读 1. 合约代码 2. 合约文件简单介绍 3. Plasma Cash 的基础数据 ...

  3. Tomcat分析

    最近闲来无事,总结了一下tomcat的一些知识,分享出来供大家参考,如有错误,请及时与我联系. 1. 入门示例:虚拟主机提供web服务 该示例通过设置虚拟主机来提供web服务,因为是入门示例,所以设置 ...

  4. jaxb教程(忘记了过来看看)

    链接 原文链接

  5. 结对编程-->总结报告

    项目github地址 PSP时间表格 结对编程中关于Information Hiding, Interface Design, Loose Coupling原则的使用 Information Hidi ...

  6. jsp九大内置对象之session和application

    session和application 用的都是特别多尤其是application,但是想全面学习一下内置对象所以都了解一下. session又被称为是会话生存期是用户进入浏览器到关闭浏览器的期间.s ...

  7. 1到N中“1”出现的次数

    题目:给定一个十进制的正整数,写下从1开始,到N的所有整数,然后数一下其中出现“1”的个数 思路:刚开始做的时候,是想从1到N进行遍历,其中每个数都出现1的个数加起来,最后得出结果,但是老师让我们找规 ...

  8. 剑指offer:旋转数组的最小数字

    题目描述: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个 ...

  9. Android界面设计适配不同屏幕的尺寸和密度解读

    Android是运行在各种提供不同的屏幕尺寸和密度的设备.Android系统提供跨设备的统一开发环境和处理大部分的工作,以调整每个应用程序的用户界面,以在其上显示的画面. 同时,该系统提供了API,允 ...

  10. BeanUtil工具类的使用

    BeanUtils的使用 1.commons-beanutils的介绍 commons-beanutils是Apache组织下的一个基础的开源库,它提供了对Java反射和内省的API的包装,依赖内省, ...