<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    廉頗老矣,尚能飯否

    java:從技術到管理

    常用鏈接

    統計

    最新評論

    hibernate緩存【轉載】

    hibernate 一級緩存:(緩存的是實體對象)

    一級緩存很短和session的生命周期一致,一級緩存也叫session級的緩存或事務緩存

     

    哪些方法支持一級緩存:

    *get()

    *load()

    *iterate()  (查詢實體對象)

     

    如何管理一級緩存:

    * session.clear() session.evict()

     

    如何避免一次性大量的實體數據入庫導致內存溢出

    *先flush,再clear

     

    如果數據量特別大,考慮采用jdbc實現,如果jdbc也不能滿足要求,可以考慮采用數據庫本身的特定導入工具

     

    一.Load測試: 在同一個session中發出兩次load查詢

           Student sutdent = (Student)session.load(Student.class,1);

           System.out.println(student.getName());

     

           sutdent = (Student)session.load(Student.class,1);

           System.out.println(student.getName());

           在同一個session中發出兩次load查詢,第一次load的時候不會去查詢數據庫,因為他是LAZY的,當使用的時候才去查詢數據庫,  第二次load的時候也不會,當使用的時候也不會查詢數據庫,因為他在緩存里找到,不會發出sql

     

     

    Load測試: 開啟兩個session中發出兩次load查詢

    Student sutdent = (Student)session.load(Student.class,1);

           System.out.println(student.getName());

    sessioin.close();

    ………..

           sutdent = (Student)session.load(Student.class,1);

           System.out.println(student.getName());

           開啟兩個session中發出兩次load查詢,第一次load的時候不會去查詢數據庫,因為他是LAZY的,當使用的時候才去查詢數據庫,  第二次load的時候也不會,當使用的時候查詢數據庫,因為session間不能共享一級緩存的數據,因為他會隨session的生命周期存在和消亡

     

     

    二.Get測試: 在同一個session中發出兩次get查詢

        Student sutdent = (Student)session.get(Student.class,1);

           System.out.println(student.getName());

     

           sutdent = (Student)session.get(Student.class,1);

           System.out.println(student.getName());

           在同一個session中發出兩次get查詢, 第一次get的時候去查詢數據庫,第二次get的時候不會查詢數據庫,因為他在緩存里找到,不會發出sql

     

     

    三.iterate測試: 在同一個session中發出兩次iterator查詢

    Student student = (Student)session.createQuery(“from Student s where s.id=1”).iterate().next();

    System.out.println(student.getName());

     

    student = (Student)session.createQuery(“from Student s where s.id=1”).iterate().next();

    System.out.println(student.getName());

           在同一個session中發出兩次iterator查詢,第一次iterate().next()的時候會發出查詢id的sql,使用的時候會發出相應的查詢實體對象,第二次iterate().next()的時候會發出查詢id的sql,不會發出查詢實體對象的sql,因為iterate使用緩存,不會發出sql

     

     

    四.Iterate查詢屬性測試: 同一個session中發出兩次查詢屬性

    String name = (String)session.createQuery(“select s.name from Student s where s.id=1”).iterate().next();

    System.out.println(name);

     

    String name = (String)session.createQuery(“select s.name from Student s where s.id=1”).iterate().next();

    System.out.println(name);

           在同一個session中發出兩次查詢屬性, 第一次iterate().next()的時候會發出查詢屬性的sql,第二次iterate().next()的時候會發出查詢屬性的sql,iterate查詢普通屬性,一級緩存不會緩存,所以會發出sql

     

     

    五.同一個session中先save,再發出load查詢save過的數據

     

           Student stu = new Student();

           stu.setName(“王五”);

     

       Serializable id = session.save(stu);

     

    Student sutdent = (Student)session.load(Student.class,id);

           System.out.println(student.getName());

     

          

    save的時候,他會在緩存里放一份,不會發出sql,因為save是使用緩存的

    六.同一個session中先調用load查詢,然后執行sessio.clear()session.evict(),再調用load查詢

     

    Student sutdent = (Student)session.load(Student.class,1);

           System.out.println(student.getName());

           session.clear();

     

    Student sutdent = (Student)session.load(Student.class,1);

           System.out.println(student.getName());

     

     

           sessio.clear()或session.evict()可以管理一級緩存,一級緩存無法取消,但可以管理.

    上面的語句都會發出sql 因為一級緩存中的實體被清除了

     

    七.向數據庫中批量加入1000條數據

     

    for(int i=0;i<1000;i++){

           Student student = new Student();

           student.setName(“s” + i);

           session.save(student);

    //每20條數據就強制session將數據持久化,同時清除緩存,避免大量數據造成內存溢出

           if( i %20 == 0 ){

                  session.flush();

                  session.clear();

    }

    }

    =========================================================================================

    hibernate 二級緩存:(緩存的是實體對象,二級緩存是放變化不是很大的數據)








    二級緩存也稱進程級的緩存或SessionFactory級的緩存,而二級緩存可以被所有的session(hibernate中的)共享二級緩存的生命周期和SessionFactory的生命周期一致,SessionFactory可以管理二級緩存

     

    二級緩存的配置和使用:

    1.將echcache.xml文件拷貝到src下, 二級緩存hibernate默認是開啟的,手動開啟

    2.開啟二級緩存,修改hibernate.cfg.xml文件,

    <property name=”hibernate.cache.user_second_level_cache”>true</property>

    3.指定緩存產品提供商

    <property name=”hibernate.cache.provider_calss”>org.hibernate.cache.EhCacheProvider</property>

     

    4.指定那些實體類使用二級緩存(兩種方法,推薦使用第二種)

    第一種:在*.hbm.xml中,在<id>之前加入

    <cache usage=”read-only” />, 使用二級緩存

    第二種:在hibernate.cfg.xml配置文件中,在<mapping resource=”com/Studnet.hbm.xml” />后面加上:

    <class-cache class=” com.Studnet” usage=”read-only” /> 

     

    二級緩存是緩存實體對象的

    了解一級緩存和二級緩存的交互

     

     

     

     

    測試二級緩存:

    一.開啟兩個session中發出兩次load查詢(getload一樣,同樣不會查詢數據庫),

    Student sutdent = (Student)session.load(Student.class,1);

           System.out.println(student.getName());

    sessioin.close();

    ………..

           sutdent = (Student)session.load(Student.class,1);

           System.out.println(student.getName());

    開啟兩個session中發出兩次load查詢,第一次load的時候不會去查詢數據庫,因為他是LAZY的,當使用的時候才去查詢數據庫,  第二次load的時候也不會,當使用的時候查詢數據庫,開啟了二級緩存,也不會查詢數據庫。

     

     

    二.開啟兩個session,分別調用load,再使用sessionFactory清楚二級緩存

    Student sutdent = (Student)session.load(Student.class,1);

           System.out.println(student.getName());

    sessioin.close();

    ………..

    SessionFactory factory = HibernateUtil.getSessionFactory();

    //factory.evict(Student.class); //清除所有Student對象

    Factory.evict(Student.class,1); //清除指定id=1 的對象

     

           sutdent = (Student)session.load(Student.class,1);

           System.out.println(student.getName());

    開啟兩個session中發出兩次load查詢,第一次load的時候不會去查詢數據庫,因為他是LAZY的,當使用的時候才去查詢數據庫,  第二次load的時候也不會,當使用的時候查詢數據庫,它要查詢數據庫,因為二級緩存中被清除了

     

    三.一級緩存和二級緩存的交互

     

    session.setCacheMode(CacheMode.GET);    //設置成 只是從二級緩存里讀,不向二級緩存里寫數據

    Student sutdent = (Student)session.load(Student.class,1);

           System.out.println(student.getName());

    sessioin.close();

    ………..

    SessionFactory factory = HibernateUtil.getSessionFactory();

    //factory.evict(Student.class); //清除所有Student對象

    Factory.evict(Student.class,1); //清除指定id=1 的對象

     

           sutdent = (Student)session.load(Student.class,1);

           System.out.println(student.getName());

    開啟兩個session中發出兩次load查詢,第一次load的時候不會去查詢數據庫,因為他是LAZY的,當使用的時候才去查詢數據庫,  第二次load的時候也不會,當使用的時候查詢數據庫,它要查詢數據庫,因為 設置了CacheMode為GET,(load設置成不能往二級緩沖中寫數據), 所以二級緩沖中沒有數據

     

     

     

    session.setCacheMode(CacheMode.PUT);  //設置成只是向二級緩存里寫數據,不讀數據

    Student sutdent = (Student)session.load(Student.class,1);

           System.out.println(student.getName());

    sessioin.close();

    ………..

    SessionFactory factory = HibernateUtil.getSessionFactory();

    //factory.evict(Student.class); //清除所有Student對象

    Factory.evict(Student.class,1); //清除指定id=1 的對象

     

           sutdent = (Student)session.load(Student.class,1);

           System.out.println(student.getName());

    開啟兩個session中發出兩次load查詢,第一次load的時候不會去查詢數據庫,因為他是LAZY的,當使用的時候才去查詢數據庫,  第二次load的時候也不會,當使用的時候查詢數據庫,它要查詢數據庫,因為設置了CacheMode為POST,(load設置成只是向二級緩存里寫數據,不讀數據)

    ====================================================================================

     

    hibernate查詢緩存(hibernate默認是關閉的)

     

    查詢緩存是針對普通屬性結果集的緩存

    對實體對象的結果集只緩存id

     

    查詢緩存的生命周期,當前關聯的表發生修改,那么查詢緩存生命周期結束

     

    查詢緩存的配置和使用:

    1. 啟用查詢緩存:在hibernate.cfg.xml中加入:

    <property name=”hibernate.cache.use_query_cache”>true</property>

      2. 在程序中必須手動啟用查詢緩存,如:query.setCacheable(true);

     

     

    測試查詢緩存:

    一.  開啟查詢緩存,關閉二級緩存,開啟一個session,分別調用query.list  (查詢屬性)

     

    Query query = session.createQuery(“select s.name from Student s”);

    //啟用查詢緩存

    query.setCacheable(true);

     

    List names = query.list();

    for(Iterator iter = names.terator();iter.hasNext();){

           String name = (String)iter.next();

           System.out.println(name);

    }

     

    System.out.println(“------------------------------------------”);

     

    query = session.createQuery(“select s.name from Student s”);

    //啟用查詢緩存

    query.setCacheable(true);

     

    names = query.list();

    for(Iterator iter = names.terator();iter.hasNext();){

           String name = (String)iter.next();

           System.out.println(name);

    }

    第二次沒有去查詢數據庫,因為啟用了查詢緩存

     

    二.  開啟查詢緩存,關閉二級緩存,開啟兩個session,分別調用query.list  (查詢屬性)

     

    Query query = session.createQuery(“select s.name from Student s”);

    //啟用查詢緩存

    query.setCacheable(true);

     

    List names = query.list();

    for(Iterator iter = names.terator();iter.hasNext();){

           String name = (String)iter.next();

           System.out.println(name);

    }

     

    session.close();

     

    System.out.println(“------------------------------------------”);

    ………

    Query query = session.createQuery(“select s.name from Student s”);

    //啟用查詢緩存

    query.setCacheable(true);

     

    List names = query.list();

    for(Iterator iter = names.terator();iter.hasNext();){

           String name = (String)iter.next();

           System.out.println(name);

    }

    第二次沒有去查詢數據庫,因為查詢緩存生命周期與session生命周期無關

     

    三.  開啟查詢緩存,關閉二級緩存,開啟兩個session,分別調用query.iterate (查詢屬性)

     

    Query query = session.createQuery(“select s.name from Student s”);

    //啟用查詢緩存

    query.setCacheable(true);

     

    for(Iterator iter =query.iterate();iter.hasNext();){

           String name = (String)iter.next();

           System.out.println(name);

    }

     

    session.close();

     

    System.out.println(“------------------------------------------”);

    ………

    Query query = session.createQuery(“select s.name from Student s”);

    //啟用查詢緩存

    query.setCacheable(true);

     

    for(Iterator iter = query.iterate();iter.hasNext();){

           String name = (String)iter.next();

           System.out.println(name);

    }

    第二去查詢數據庫,因為查詢緩存只對query.list()起作用,對query.iterate()不起作用,也就是說query.iterate()不使用查詢緩存

     

    四.  關閉查詢緩存,關閉二級緩存,開啟兩個session,分別調用query.list (查詢實體對象)

     

    Query query = session.createQuery(“ from Student s”);

    //query.setCacheable(true);

    List students = query.list();

    for(Iterator iter = students.iterate();iter.hasNext();){

           Student stu = (Student)iter.next();

           System.out.println(stu.getName());

    }

     

    session.close();

     

    System.out.println(“------------------------------------------”);

    ………

    Query query = session.createQuery(“ from Student s”);

    //query.setCacheable(true);

    List students = query.list();

    for(Iterator iter = students.iterate();iter.hasNext();){

           Student stu = (Student)iter.next();

           System.out.println(stu.getName());

    }

    第二去查詢數據庫,因為list默認每次都會發出查詢sql

     

    五.  開啟查詢緩存,關閉二級緩存,開啟兩個session,分別調用query.list (查詢實體對象)

     

    Query query = session.createQuery(“ from Student s”);

    query.setCacheable(true);

    List students = query.list();

    for(Iterator iter = students.iterate();iter.hasNext();){

           Student stu = (Student)iter.next();

           System.out.println(stu.getName());

    }

     

    session.close();

     

    System.out.println(“------------------------------------------”);

    ………

    Query query = session.createQuery(“ from Student s”);

    query.setCacheable(true);

    List students = query.list();

    for(Iterator iter = students.iterate();iter.hasNext();){

           Student stu = (Student)iter.next();

           System.out.println(stu.getName());

    第二去查詢數據庫時,會發出N條sql語句,因為開啟了查詢緩存,關閉了二級緩存,那么查詢緩存會緩存實體對象的id,所以hibernate會根據實體對象的id去查詢相應的實體,如果緩存中不存在相應的實體,那么將發出根據實體id查詢的sql語句,否則不會發出sql,使用緩存中的數據

     

    六.  開啟查詢緩存,開啟二級緩存,開啟兩個session,分別調用query.list (查詢實體對象)

     

    Query query = session.createQuery(“ from Student s”);

    query.setCacheable(true);

    List students = query.list();

    for(Iterator iter = students.iterate();iter.hasNext();){

           Student stu = (Student)iter.next();

           System.out.println(stu.getName());

    }

     

    session.close();

     

    System.out.println(“------------------------------------------”);

    ………

    Query query = session.createQuery(“ from Student s”);

    query.setCacheable(true);

    List students = query.list();

    for(Iterator iter = students.iterate();iter.hasNext();){

           Student stu = (Student)iter.next();

           System.out.println(stu.getName());

    }

     

    第二不會發出sql,因為開啟了二級緩存和查詢緩存,查詢緩存緩存了實體對象的id列表,hibernate會根據實體對象的id列表到二級緩存中取得相應的數據



    柳德才
    13691193654
    18942949207
    QQ:422157370
    liudecai_zan@126.com
    湖北-武漢-江夏-廟山

    posted on 2009-04-08 17:08 liudecai_zan@126.com 閱讀(2052) 評論(0)  編輯  收藏 所屬分類: 程序人生

    主站蜘蛛池模板: 久久国产精品免费| 亚洲国产精品成人AV在线| 99免费精品视频| 亚洲国产香蕉人人爽成AV片久久 | 日本一道本不卡免费| 亚洲精品成人网久久久久久| 国产精品久久亚洲一区二区| 国产日产成人免费视频在线观看| 亚洲成a人无码亚洲成www牛牛| 免费看片A级毛片免费看| 亚洲乱理伦片在线观看中字| 日韩高清在线免费看| 美女被吸屁股免费网站| 亚洲成人高清在线| 国产特黄特色的大片观看免费视频| 国产精品亚洲αv天堂无码| 国产又黄又爽又大的免费视频| 亚洲婷婷五月综合狠狠爱| 两个人日本WWW免费版| 亚洲av无码乱码国产精品| 真实国产乱子伦精品免费| 国产亚洲国产bv网站在线| 日韩成人在线免费视频| 香蕉视频免费在线播放| 亚洲va无码va在线va天堂| 免费在线观看视频网站| 亚洲av永久中文无码精品综合 | 中文字幕成人免费高清在线 | 亚洲国产精品自在自线观看| 全亚洲最新黄色特级网站| 91国内免费在线视频| 亚洲一卡二卡三卡四卡无卡麻豆| 国产成人免费a在线视频色戒| 51午夜精品免费视频| 亚洲伊人久久精品| vvvv99日韩精品亚洲| 99re6在线视频精品免费下载| 亚洲GV天堂无码男同在线观看| 亚洲精品自在在线观看| 国产一精品一AV一免费孕妇| 一级人做人爰a全过程免费视频|