zoukankan      html  css  js  c++  java
  • spring管理hibernate,mybatis,一级缓存失效原因

    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到底干了什么??????/

     

     

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

     

     

     

     

     

     

     

  • 相关阅读:
    springmvc乱码问题
    51nod 还是01串
    51nod 1276 岛屿的数量
    poj 2486 a apple tree
    hdu 1011 Starship Troopers
    poj 1155 TELE
    hdu 4586 Play the Dice
    hdu 5023 A Corrupt Mayor's Performance Art(线段树水题)
    Appleman and Tree
    hdu 4003
  • 原文地址:https://www.cnblogs.com/zhangyu0217----/p/7574704.html
Copyright © 2011-2022 走看看