hibernate一級緩存
一級緩存很短和session的生命周期一致,一級緩存也叫session級的緩存或事務(wù)級緩存
那些方法支持一級緩存:
* get()
* load()
* iterate(查詢實(shí)體對象)
如何管理一級緩存:
* session.clear(),session.evict()
如何避免一次性大量的實(shí)體數(shù)據(jù)入庫導(dǎo)致內(nèi)存溢出
* 先flush,再clear
如果數(shù)據(jù)量特別大,考慮采用jdbc實(shí)現(xiàn),如果jdbc也不能滿足要求可以考慮采用數(shù)據(jù)本身的特定導(dǎo)入工具
//在同一個(gè)session中發(fā)出兩次load查詢Student student = (Student)session.load(Student.class, 1);System.out.println("student.name=" + student.getName());//不會發(fā)出sql,因?yàn)閘oad使用緩存student = (Student)session.load(Student.class, 1);System.out.println("student.name=" + student.getName());//在同一個(gè)session中發(fā)出兩次get查詢Student student = (Student)session.get(Student.class, 1);System.out.println("student.name=" + student.getName());//不會發(fā)出sql,因?yàn)間et使用緩存student = (Student)session.get(Student.class, 1);System.out.println("student.name=" + student.getName());//在同一個(gè)session中發(fā)出兩次iterate查詢實(shí)體對象Student student = (Student)session.createQuery("from Student s where s.id=1").iterate().next();System.out.println("student.name=" + student.getName());//會發(fā)出查詢id的sql,不會發(fā)出查詢實(shí)體對象的sql,因?yàn)閕terate使用緩存student = (Student)session.createQuery("from Student s where s.id=1").iterate().next();System.out.println("student.name=" + student.getName());//在同一個(gè)session中發(fā)出兩次iterate查詢實(shí)體對象String name = (String)session.createQuery("select s.name from Student s where s.id=1").iterate().next();System.out.println("student.name=" + name);//iterate查詢普通屬性,一級緩存不會緩存,所以發(fā)出sql//一級緩存是緩存實(shí)體對象的name = (String)session.createQuery("select s.name from Student s where s.id=1").iterate().next();System.out.println("student.name=" + name);//開啟兩個(gè)session中發(fā)出load查詢try {session = HibernateSessionFactory.getSession();session.beginTransaction();Student student = (Student)session.load(Student.class, 1);System.out.println("student.name=" + student.getName());session.getTransaction().commit();}catch(Exception e) {e.printStackTrace();session.getTransaction().rollback();}finally {HibernateSessionFactory.closeSession(session);}try {session = HibernateSessionFactory.getSession();session.beginTransaction();//會發(fā)出查詢語句,session間不能共享一級緩存的數(shù)據(jù)//因?yàn)樗鼤殡Ssession的生命周期存在和消亡Student student = (Student)session.load(Student.class, 1);System.out.println("student.name=" + student.getName());//在同一個(gè)session中先save,在發(fā)出load查詢save過的數(shù)據(jù)Student stu = new Student();stu.setName("王五");Serializable id = session.save(stu);//不會發(fā)出sql,因?yàn)閟ave是使用緩存的Student student = (Student)session.load(Student.class, id);System.out.println("student.name=" + student.getName());//向數(shù)據(jù)庫中批量加入1000條數(shù)據(jù)for (int i=0; i<1000; i++) {Student student = new Student();student.setName("s_" + i);session.save(student);//每20條數(shù)據(jù)就強(qiáng)制session將數(shù)據(jù)持久化//同時(shí)清除緩存,避免大量數(shù)據(jù)造成內(nèi)存溢出if ( i % 20 == 0) {session.flush();session.clear();}}
hibernate二級緩存
二級緩存也稱進(jìn)程級的緩存或SessionFactory級的緩存,二級緩存可以被所有的session共享
二級緩存的生命周期和SessionFactory的生命周期一致,SessionFactory可以管理二級緩存
二級緩存的配置和使用:
* 將echcache.xml文件拷貝到src下
* 開啟二級緩存,修改hibernate.cfg.xml文件
<property name="hibernate.cache.use_second_level_cache">true</property>
* 指定緩存產(chǎn)品提供商,修改hibernate.cfg.xml文件
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
* 指定那些實(shí)體類使用二級緩存(兩種方法)
* 在映射文件中采用<cache>標(biāo)簽
* 在hibernate.cfg.xml文件中,采用<class-cache>標(biāo)簽
二級緩存是緩存實(shí)體對象的
了解一級緩存和二級緩存的交互
//開啟兩次session,使用load和get方法家在數(shù)據(jù)都在第二次加載數(shù)據(jù)不會出現(xiàn)hql語句,因?yàn)閟ession共享二級緩存Student student = (Student)session.get(Student.class, 1);System.out.println("student.name=" + student.getName());//關(guān)了,又開了session//不會發(fā)出sql,因?yàn)殚_啟了二級緩存,session是共享二級緩存的Student student = (Student)session.get(Student.class, 1);System.out.println("student.name=" + student.getName());// 開啟兩個(gè)session,分別調(diào)用load,在使用SessionFactory清除二級緩存Student student = (Student)session.load(Student.class, 1);System.out.println("student.name=" + student.getName());//管理二級緩存SessionFactory factory = HibernateSessionFactory.getSessionFactory();factory.evict(Student.class, 1);//關(guān)了,又開了session//會發(fā)出查詢sql,因?yàn)槎壘彺嬷械臄?shù)據(jù)被清除了Student student = (Student)session.load(Student.class, 1);System.out.println("student.name=" + student.getName());//一級緩存和二級緩存的交互//僅向二級緩存讀數(shù)據(jù),而不向二級緩存寫數(shù)據(jù)session.setCacheMode(CacheMode.GET);Student student = (Student)session.load(Student.class, 1);System.out.println("student.name=" + student.getName());//關(guān)了,又開了session//發(fā)出sql語句,因?yàn)閟ession設(shè)置了CacheMode為GET,所以二級緩存中沒有數(shù)據(jù)Student student = (Student)session.load(Student.class, 1);System.out.println("student.name=" + student.getName());//關(guān)了,又開了session//只向二級緩存寫數(shù)據(jù),而不從二級緩存讀數(shù)據(jù)session.setCacheMode(CacheMode.PUT);//會發(fā)出查詢sql,因?yàn)閟ession將CacheMode設(shè)置成了PUTStudent student = (Student)session.load(Student.class, 1);System.out.println("student.name=" + student.getName());
hibernate查詢緩存
查詢緩存是針對普通屬性結(jié)果集的緩存
對實(shí)體對象的結(jié)果集只緩存id
查詢緩存的生命周期,當(dāng)前關(guān)聯(lián)的表發(fā)生修改,那么查詢緩存生命周期結(jié)束
查詢緩存的配置和使用:
* 在hibernate.cfg.xml文件中啟用查詢緩存,如:
<property name="hibernate.cache.use_query_cache">true</property>
* 在程序中必須手動啟用查詢緩存,如:
query.setCacheable(true);