hibernate一級緩存
一級緩存很短和session的生命周期一致,一級緩存也叫session級的緩存或事務(wù)級緩存
那些方法支持一級緩存:
* get()
* load()
* iterate(查詢(xún)實(shí)體對象)
如何管理一級緩存:
* session.clear(),session.evict()
如何避免一次性大量的實(shí)體數據入庫導致內存溢出
* 先f(wàn)lush,再clear
如果數據量特別大,考慮采用jdbc實(shí)現,如果jdbc也不能滿(mǎn)足要求可以考慮采用數據本身的特定導入工具
//在同一個(gè)session中發(fā)出兩次load查詢(xún)Student student = (Student)session.load(Student.class, 1);System.out.println("student.name=" + student.getName());//不會(huì )發(fā)出sql,因為load使用緩存student = (Student)session.load(Student.class, 1);System.out.println("student.name=" + student.getName());//在同一個(gè)session中發(fā)出兩次get查詢(xún)Student student = (Student)session.get(Student.class, 1);System.out.println("student.name=" + student.getName());//不會(huì )發(fā)出sql,因為get使用緩存student = (Student)session.get(Student.class, 1);System.out.println("student.name=" + student.getName());//在同一個(gè)session中發(fā)出兩次iterate查詢(xún)實(shí)體對象Student student = (Student)session.createQuery("from Student s where s.id=1").iterate().next();System.out.println("student.name=" + student.getName());//會(huì )發(fā)出查詢(xún)id的sql,不會(huì )發(fā)出查詢(xún)實(shí)體對象的sql,因為iterate使用緩存student = (Student)session.createQuery("from Student s where s.id=1").iterate().next();System.out.println("student.name=" + student.getName());//在同一個(gè)session中發(fā)出兩次iterate查詢(xún)實(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查詢(xún)普通屬性,一級緩存不會(huì )緩存,所以發(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);//開(kāi)啟兩個(gè)session中發(fā)出load查詢(xún)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();//會(huì )發(fā)出查詢(xún)語(yǔ)句,session間不能共享一級緩存的數據//因為它會(huì )伴隨session的生命周期存在和消亡Student student = (Student)session.load(Student.class, 1);System.out.println("student.name=" + student.getName());//在同一個(gè)session中先save,在發(fā)出load查詢(xún)save過(guò)的數據Student stu = new Student();stu.setName("王五");Serializable id = session.save(stu);//不會(huì )發(fā)出sql,因為save是使用緩存的Student student = (Student)session.load(Student.class, id);System.out.println("student.name=" + student.getName());//向數據庫中批量加入1000條數據for (int i=0; i<1000; i++) {Student student = new Student();student.setName("s_" + i);session.save(student);//每20條數據就強制session將數據持久化//同時(shí)清除緩存,避免大量數據造成內存溢出if ( i % 20 == 0) {session.flush();session.clear();}}hibernate二級緩存
二級緩存也稱(chēng)進(jìn)程級的緩存或SessionFactory級的緩存,二級緩存可以被所有的session共享
二級緩存的生命周期和SessionFactory的生命周期一致,SessionFactory可以管理二級緩存
二級緩存的配置和使用:
* 將echcache.xml文件拷貝到src下
* 開(kāi)啟二級緩存,修改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í)體類(lèi)使用二級緩存(兩種方法)
* 在映射文件中采用<cache>標簽
* 在hibernate.cfg.xml文件中,采用<class-cache>標簽
二級緩存是緩存實(shí)體對象的
了解一級緩存和二級緩存的交互
//開(kāi)啟兩次session,使用load和get方法家在數據都在第二次加載數據不會(huì )出現hql語(yǔ)句,因為session共享二級緩存Student student = (Student)session.get(Student.class, 1);System.out.println("student.name=" + student.getName());//關(guān)了,又開(kāi)了session//不會(huì )發(fā)出sql,因為開(kāi)啟了二級緩存,session是共享二級緩存的Student student = (Student)session.get(Student.class, 1);System.out.println("student.name=" + student.getName());// 開(kāi)啟兩個(gè)session,分別調用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)了,又開(kāi)了session//會(huì )發(fā)出查詢(xún)sql,因為二級緩存中的數據被清除了Student student = (Student)session.load(Student.class, 1);System.out.println("student.name=" + student.getName());//一級緩存和二級緩存的交互//僅向二級緩存讀數據,而不向二級緩存寫(xiě)數據session.setCacheMode(CacheMode.GET);Student student = (Student)session.load(Student.class, 1);System.out.println("student.name=" + student.getName());//關(guān)了,又開(kāi)了session//發(fā)出sql語(yǔ)句,因為session設置了CacheMode為GET,所以二級緩存中沒(méi)有數據Student student = (Student)session.load(Student.class, 1);System.out.println("student.name=" + student.getName());//關(guān)了,又開(kāi)了session//只向二級緩存寫(xiě)數據,而不從二級緩存讀數據session.setCacheMode(CacheMode.PUT);//會(huì )發(fā)出查詢(xún)sql,因為session將CacheMode設置成了PUTStudent student = (Student)session.load(Student.class, 1);System.out.println("student.name=" + student.getName());hibernate查詢(xún)緩存
查詢(xún)緩存是針對普通屬性結果集的緩存
對實(shí)體對象的結果集只緩存id
查詢(xún)緩存的生命周期,當前關(guān)聯(lián)的表發(fā)生修改,那么查詢(xún)緩存生命周期結束
查詢(xún)緩存的配置和使用:
* 在hibernate.cfg.xml文件中啟用查詢(xún)緩存,如:
<property name="hibernate.cache.use_query_cache">true</property>
* 在程序中必須手動(dòng)啟用查詢(xún)緩存,如:
query.setCacheable(true);
聯(lián)系客服