spring管理hibernate,mybatis,一级缓存失效原因
关于缓存:
缓存是介于物理数据源与应用程序之间,是对数据库中的数据复制一份临时放在内存中的容器,
其作用是为了减少应用程序对物理数据源访问的次数,从而提高了应用程序的运行性能。
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,一级缓存失效原因的更多相关文章
- spring整合mybatis后,mybatis一级缓存失效的原因
一般来说,可以在5个方面进行缓存的设计: 最底层可以配置的是数据库自带的query cache, mybatis的一级缓存,默认情况下都处于开启状态,只能使用自带的PerpetualCache,无法配 ...
- ssh整合hibernate 使用spring管理hibernate二级缓存,配置hibernate4.0以上二级缓存
ssh整合hibernate 使用spring管理hibernate二级缓存,配置hibernate4.0以上二级缓存 hibernate : Hibernate是一个持久层框架,经常访问物理数据库 ...
- Mybatis一级缓存和二级缓存 Redis缓存
一级缓存 Mybatis的一级缓存存放在SqlSession的生命周期,在同一个SqlSession中查询时,Mybatis会把执行的方法和参数通过算法生成缓存的键值,将键值和查询结果存入一个Map对 ...
- MyBatis之一级缓存及其一级缓存失效
定义: 一级缓存:本地缓存:与数据库同一次会话(sqlSession)期间查询到的数据会放在本地缓存中,如果以后要获取相同的数据直接从缓存中获取,不会再次向数据库查询数据一个SqlSession拥有一 ...
- 四 Hibernate的一级缓存&事务管理及其配置
持久态对象: 自动更新数据库,原理是一级缓存. 缓存:是一种优化的方式,将数据存入内存,从缓存/内存中获取,不用通过存储源 Hibernate框架中提供了优化手段:缓存,抓取策略 Hibernate中 ...
- Mybaits 源码解析 (十二)----- Mybatis的事务如何被Spring管理?Mybatis和Spring事务中用的Connection是同一个吗?
不知道一些同学有没有这种疑问,为什么Mybtis中要配置dataSource,Spring的事务中也要配置dataSource?那么Mybatis和Spring事务中用的Connection是同一个吗 ...
- java-mybaits-014-数据库缓存设计【querycache、mybatis一级缓存、二级缓存】
一.概述 一般来说,可以在5个方面进行缓存的设计: 1.最底层可以配置的是数据库自带的query cache, 2.mybatis的一级缓存,默认情况下都处于开启状态,只能使用自带的Perpetual ...
- Spring管理Hibernate
为什么要用Hibernate框架? 既然用Hibernate框架访问管理持久层,那为何又提到用Spring来管理以及整合Hibernate呢? 首先我们来看一下Hibernate进行操作的步骤.比如添 ...
- MyBatis一级缓存引起的无穷递归
MyBatis一级缓存引起的无穷递归 引言: 最近在项目中参与了一个领取优惠劵的活动,当多个用户领取同一张优惠劵的时候,使用了数据库锁控制并发,起初的设想是:如果多个人同时领一张劵,第一个到达的人领取 ...
随机推荐
- 【CentOS 7】scp示例
1,从远端拷贝到本地 /tmp路径 root@raspberrypi:/download/api_weather# scp root@123.207.xxx.xxx:/xxx/* /tmp 2,从本地 ...
- 一文拆解Faas的真实案例
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文来自腾讯云技术沙龙,本次沙龙主题为Serverless架构开发与SCF部署实践 刘敏洁:具有多年云计算行业经验,曾任职于华为.UClou ...
- iOS 开发中,关于xxx.xcodeproj 文件冲突的解决方案 (以后谁不会了,直接将连接给他)
iOS 开发中,关于xxx.xcodeproj 文件冲突的解决方案 (一有冲突要手把手教一遍,太麻烦了,现在总结下,以后谁不会了,连接直接发他). 关于xxx.xcodeproj 文件冲突的话,是比较 ...
- Redux和React-Redux的实现(一):Redux的实现和context
react使用redux做状态管理,实现多个组件之间的信息共享,解决了父子组件.兄弟组件之间的复杂通信问题.vue有vuex,总之是一种flux的思想.react提供了react-redux这个库,一 ...
- React.js - 入门
React.js - 第1天 1. React简介 React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设 ...
- Daily Srum 10.30
Android那一组打算用SQL Server这个关系型数据库,而王鹿鸣他们一组却是依赖于Hbase,这是一件很麻烦的事,所以我打算在这两方面都建立一个数据库.虽然挺麻烦,但是还是为了扩展性所做的必要 ...
- ADT图及图的实现及图的应用
图: 图中涉及的定义: 有向图: 顶点之间的相关连接具有方向性: 无向图: 顶点之间相关连接没有方向性: 完全图: 若G是无向图,则顶点数n和边数e满足:0<=e<=n(n-1)/2,当e ...
- JPEG图像压缩算法流程详解
JPEG图像压缩算法流程详解 JPEG代表Joint Photographic Experts Group(联合图像专家小组).此团队创立于1986年,1992年发布了JPEG的标准而在1994年获得 ...
- 安恒杯2月月赛-应该不是xss
1. 打开题目一看,是个留言板 2. 查看源码发现有几个js文件 依次打开发现在main.js里存在这样一段代码 3. 访问 /#login是登录的界面,/#chgpass是修改密码的界面,其中修改密 ...
- PHP学习心得1
php是动态网站开发的优秀语言,在学习的时候万万不能冒进.在系统的学习前,我认为不应该只是追求实现某种效果,因为即使你复制他人的代码调试成功,实现了你所期望的效果,你也不了解其中的原理,这样你很难利用 ...