1.一級緩存的作用域是一個session的范圍
2.使用二級緩存的步驟
··hibernate并沒有提供相應(yīng)的二級緩存的組件馒索,所以需要加入額外的二級緩存包曹体,常用的二級緩存包是ECHcache
在hibernate.cfg.xml中配置開啟二級緩存
<propertyname="hibernate.cache.use_second_level_cache">true</property>
設(shè)置二級緩存所提供的類
<propertyname="hibernate.cache.provider_class">
net.sf.ehcache.hibernate.EhCacheProvider</property>
在hibernate4.0之后需要設(shè)置facotory_class
<property name="hibernate.cache.region.factory_class">
org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
說明ehcache的配置文件路徑
<property name="hibernate.cache.provider_configuration_file_resource_path">
ehcache.xml</property>
應(yīng)用二級緩存:
在xml的配置文件中設(shè)置二級緩存
try {
//此時會發(fā)出一條sql取出所有的學(xué)生信息
session = HibernateUtil.openSession();
Student stu = (Student)session.load(Student.class, 1);
System.out.println(stu.getName()+",---");
} catch (Exception e) {
e.printStackTrace();
} finally {
HibernateUtil.close(session);}
try {
session = HibernateUtil.openSession();
session.beginTransaction();
//此時session已經(jīng)關(guān)閉了色瘩,但是Student在二級緩存中单绑,所以也不會發(fā)出SQL語句
Student stu = (Student)session.load(Student.class, 1);
//會報錯嘱函,因為二級緩存設(shè)置為read-only
// stu.setName("abc");
System.out.println(stu.getName()+",---");
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
HibernateUtil.close(session);}
二級緩存緩存的是對象币厕,它是把所有的對象緩存到內(nèi)存中列另,一定注意是基于對象的緩存
try {/** * 此時會發(fā)出一條sql取出所有的學(xué)生信息 */
session = HibernateUtil.openSession();
List<Object[]>ls = session.createQuery("select stu.id,stu.name from Student stu")
.setFirstResult(0).setMaxResults(50).list();
} catch (Exception e) {
e.printStackTrace();
} finally {
HibernateUtil.close(session);}
try {
session = HibernateUtil.openSession();
session.beginTransaction();
//以上代碼僅僅取了id和name,而二級緩存是緩存對象的旦装,所以上一段代碼不會將對象加入二級緩存
*此時就是發(fā)出相應(yīng)的sql
Student stu = (Student)session.load(Student.class, 1);
//會報錯页衙,因為二級緩存設(shè)置為read-only
// stu.setName("abc");
System.out.println(stu.getName()+",---");
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
HibernateUtil.close(session);}
try {
/** * 此時會發(fā)出一條sql取出所有的學(xué)生信息 */
session = HibernateUtil.openSession();
List<Student>ls = session.createQuery("select stu from Studentstu").setFirstResult(0).setMaxResults(50).list();}
catch (Exception e) {
e.printStackTrace();}
finally {HibernateUtil.close(session);}
try {
session = HibernateUtil.openSession();
/** * 由于學(xué)生的對象已經(jīng)緩存在二級緩存中了,此時再使用iterate來獲取對象的時候,首先會通過一條 取id的語句店乐,然后在獲取對象時去二級緩存中艰躺,如果發(fā)現(xiàn)就不會再發(fā)SQL,這樣也就解決了N+1問題? 而且內(nèi)存占用也不多 */
Iteratorstus = session.createQuery("from Student")
.setFirstResult(0).setMaxResults(50).iterate();
for(;stus.hasNext();) {
Student stu = stus.next();
System.out.println(stu.getName());}
} catch (Exception e) {
e.printStackTrace();
} finally {
HibernateUtil.close(session);}
try {
/** * 此時會發(fā)出一條sql取出所有的學(xué)生信息 */
session = HibernateUtil.openSession();
List<Student>ls = session.createQuery("select stu from Student stu").setFirstResult(0).setMaxResults(50).list();}
catch (Exception e) {e.printStackTrace();}
finally {HibernateUtil.close(session);}
try {session = HibernateUtil.openSession();
/** * 使用List會發(fā)出兩條一模一樣的sql眨八,此時如果希望不發(fā)sql就需要使用
查詢緩存 */
List<Student>ls = session.createQuery("select stu from Studentstu").setFirstResult(0).setMaxResults(50).list();
Iterator<Student>stus = ls.iterator();
for(;stus.hasNext();) {
Student stu = stus.next();
System.out.println(stu.getName());}
} catch (Exception e) {
e.printStackTrace();
} finally {
HibernateUtil.close(session);}
查詢緩存是針對HQL語句的緩存腺兴,查詢緩存僅僅只會緩存id而不會緩存對象,
查詢緩存未完待續(xù)....