mybatis cache: first-level cache and second-level cache
hibernate caching: first-level caching and second-level caching
With regard to caching:
Caching is between physical data sources and applications. It copies data in a database and temporarily stores it in memory.
Its purpose is to reduce the number of times the application accesses physical data sources, thereby improving the performance of the application.
When Hibernate reads data, it queries in the corresponding cache according to the cache mechanism, if it finds the data it needs in the cache (we call it "cache life").
Then the hit data is directly used as the result to avoid the performance loss of sending a large number of SQL statements to the database query.
Generally, we have the problem of data access performance in project integration. We study the application of lower cache in different stages to design the cache in five aspects:
1. The bottom layer can be configured is MySQL With query cache,
2.mybatis Level 1 cache, which is open by default, can only use its own Perpetual Cache and cannot configure third-party caches.
3.mybatis secondary cache, which can configure switch state, defaults to its own Perpetual Cache, but has weak function and can configure third-party cache.
4. The cache configuration of service layer, combined with spring, can be flexibly selected.
5.hibernate's first-level cache is also open by default, session-level, and can be used freely. But here's how hibernate gets sessions.
6.hibernate's secondary cache needs to refer to third-party plug-ins and configure them in the hibernate configuration file.
7. According to the actual business situation, directly cache some html pages and return them to the client.
It was found that the first level caches of mybatis and hibernate integrated by spring failed in the integrated project test.
Firstly, the first level cache of mybatis and hibernate is sqlsession, which is used to query the same data repeatedly when the sqlsession is not closed. Once the sqlsession is closed, the data cached by the sqlsession will be emptied.
mybatis managed by spring
@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 is my spring configuration file that manages session
Test results:
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, Kiwifruit Shanxi, 2017-09-06, 1, 3, ssh-code, 1000, bdss <== Row: 26, 1500, Apple Pear Shanxi, 2017-08-25, 0, 1, ssh-code, 50, bdss <== Row: 27, 150262, Apple Pear Shanxi, 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, Braised steak fillet, 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, Total joking, 2017-09-06, 1, 3, dsfas, 15, dfa <== Row: 45, 5000, Zhang Yu Zhang Yu, 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, Kung Pao Chicken, 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, Kung Pao Chicken, 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, Kiwifruit Shanxi, 2017-09-06, 1, 3, ssh-code, 1000, bdss <== Row: 26, 1500, Apple Pear Shanxi, 2017-08-25, 0, 1, ssh-code, 50, bdss <== Row: 27, 150262, Apple Pear Shanxi, 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, Braised steak fillet, 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, Total joking, 2017-09-06, 1, 3, dsfas, 15, dfa <== Row: 45, 5000, Zhang Yu Zhang Yu, 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, Kung Pao Chicken, 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, Kung Pao Chicken, 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]
The test results were a little bit too many, but apparently mybatis level 1 cache was not used.
If we use session s managed by mybatis itself to look at the test results
@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, Kiwifruit Shanxi, 2017-09-06, 1, 3, ssh-code, 1000, bdss <== Row: 26, 1500, Apple Pear Shanxi, 2017-08-25, 0, 1, ssh-code, 50, bdss <== Row: 27, 150262, Apple Pear Shanxi, 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, Braised steak fillet, 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, Total joking, 2017-09-06, 1, 3, dsfas, 15, dfa <== Row: 45, 5000, Zhang Yu Zhang Yu, 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, Kung Pao Chicken, 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, Kung Pao Chicken, 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
Obviously, only one visit to the database shows that using mybatis's first-level cache alone is effective.
Looking at the case of hibernate and spring integration, test hibernate's level 1 cache:
@org.junit.Test public void TestOneCache(){ //cover spring Managerial hibernate Primary Cache Failure 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()); }
Test results:
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
Like mybatis, the primary cache of hibernate managed by spring is invalid. Explain that spring is the problem.
Let's first look at spring integration mybatis, session Factory is provided by mybatis and goes into the sqlSessionFactory class.
/** * 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(); }
Then find one of its implementation classes, sqlsession Manager, which also implements 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 >(); this is to bind session to the current thread
The reason for the failure of the first level cache depends on his other method, which is implemented from 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(); } } }
//This is close Method @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); //Release thread } }
Look at the code in the red section. When a non-empty session comes in, reopen session () to execute the autoSqlSession.close() method at the end of the code execution, close session, release thread, and jump out of recursion.
To summarize briefly:
session and current thread binding process and the cause of mybatis failure
1. Get a request
2. Spring checks this requirement and applies for a mybatis sqlsession (resource pool) and binds the applied sqlsession to the current thread and puts it into threadlocal
3. Template gets sqlsession from threadlocal to execute queries
4. Query ends, empty the sqlsession bound to the current thread in threadlocal, and release resources
5. We need to access data and get new session s.
6, go back to step 2
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@org.junit.Test public void TestOneCache(){ //Not being spring Managing the use of first-level caching 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()); //cover spring Managerial hibernate Primary Cache Failure /*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());*/ }
Cache that obviously goes
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
-- hibernate cache managed by spring
@org.junit.Test public void TestOneCache(){ //cover spring Managerial hibernate Primary Cache Failure 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
Primary Cache Failure
Then look at the spring integrated hibernate configuration file. The session Factory of spring+hibernate is managed by spring. Go into the configuration file and find the 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 has two methods to get session: openSession() and getCurrentSession().
A: session s created by getCurrentSession are bound to the current thread, while openSession is not.
B: The thread created by getCurrentSession automatically closes after the transaction rolls back or the transaction commits, while openSession must be closed manually.
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; }
-- Turn down his source code and feel like a maze of sessions. Turn it over and come back. Looks like a callback. I don't understand. But I think he "flushes" every time he gets sessions on request, but the same is true of sessions I get with tool classes.
I don't know what spring has done to hibernate to invalidate the first level cache. What on earth did you tm do??????? /
Thank you very much for sharing what you want to know.