hibernate3学习笔记(二十二)|Query缓存机制

接前面的例子:http://blog.csdn.net/kunshan_shenbin/archive/2008/09/03/2874375.aspx

测试代码如下:

1.package com.hb3.pack_22;<br />2.<br />3.import java.io.IOException;<br />4.import java.sql.SQLException;<br />5.import java.util.List;<br />6.7.import org.hibernate.Query;<br />8.import org.hibernate.Session;<br />9.import org.hibernate.SessionFactory;<br />10.import org.hibernate.cfg.Configuration;<br />11.12.import com.hb3.pack_22.model.User;<br />13.14.public class BusinessService {<br />15.16.    public static void main(String[] args) throws IOException, SQLException {<br />17.<br />18.        Configuration config = new Configuration().configure();<br />19.        SessionFactory sessionFactory = config.buildSessionFactory();      <br />20.        Session session = sessionFactory.openSession();<br />21.22.<br />23.        String hql = "from com.hb3.pack_22.model.User";<br />24.<br />25.        Query query = session.createQuery(hql);<br />26.        List<?> users = query.list();<br />27.<br />28.        for(int i = 0; i < users.size(); i++) {<br />29.            User user = (User) users.get(i);<br />30.            System.out.println(user.getName());<br />31.        }<br />32.<br />33.        query = session.createQuery(hql);<br />34.        users = query.list();<br />35.<br />36.        for(int i = 0; i < users.size(); i++) {<br />37.            User user = (User) users.get(i);<br />38.            System.out.println(user.getName());<br />39.        }<br />40.41.42.        session.close();<br />43.        sessionFactory.close();<br />44.    }<br />45.}

执行的结果为:

Hibernate: select user0_.id as id0_, user0_.name as name0_, user0_.room_id as room3_0_ from user user0_chenyanshenbinHibernate: select user0_.id as id0_, user0_.name as name0_, user0_.room_id as room3_0_ from user user0_chenyanshenbin

可见,没有启用Query的快取功能。

如果打算打开Query的快取功能,首先在hibernate.cfg.xml中设定hibernate.cache.use_query_cache属性:

1.<?xml version="1.0" encoding="utf-8"?> <br />2.<!DOCTYPE hibernate-configuration PUBLIC<br />3.    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"<br />4.    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"><br />5.<br />6.<hibernate-configuration> <br />7.8.    <session-factory> <br />9.        ....<br />10.11.        <property name="hibernate.cache.use_query_cache">true</property> <br />12.        ....<br />13.<br />14.    </session-factory> <br />15.16.</hibernate-configuration>

然后在每次简历Query时,执行setCacheable(true):

1.package com.hb3.pack_22;<br />2.<br />3.import java.io.IOException;<br />4.import java.sql.SQLException;<br />5.import java.util.List;<br />6.7.import org.hibernate.Query;<br />8.import org.hibernate.Session;<br />9.import org.hibernate.SessionFactory;<br />10.import org.hibernate.cfg.Configuration;<br />11.12.import com.hb3.pack_22.model.User;<br />13.14.public class BusinessService {<br />15.16.    public static void main(String[] args) throws IOException, SQLException {<br />17.<br />18.        Configuration config = new Configuration().configure();<br />19.        SessionFactory sessionFactory = config.buildSessionFactory();      <br />20.        Session session = sessionFactory.openSession();<br />21.22.<br />23.        String hql = "from com.hb3.pack_22.model.User";<br />24.<br />25.        Query query = session.createQuery(hql);<br />26.        //使用Query快取 27.        query.setCacheable(true);<br />28.        List<?> users = query.list();<br />29.<br />30.        for(int i = 0; i < users.size(); i++) {<br />31.            User user = (User) users.get(i);<br />32.            System.out.println(user.getName());<br />33.        }<br />34.<br />35.        query = session.createQuery(hql);<br />36.        //使用Query快取 37.        query.setCacheable(true);<br />38.        users = query.list();<br />39.<br />40.        for(int i = 0; i < users.size(); i++) {<br />41.            User user = (User) users.get(i);<br />42.            System.out.println(user.getName());<br />43.        }<br />44.45.46.        session.close();<br />47.        sessionFactory.close();<br />48.    }<br />49.}

执行结果为:

Hibernate: select user0_.id as id0_, user0_.name as name0_, user0_.room_id as room3_0_ from user user0_chenyanshenbinchenyanshenbin

其实,Hibernate在启用Query的缓存机制后,会保留执行过的查询SQL和查询结果,在下次查询后会看看SQL是否相同,并看看对应的资料库表格是否有变动(Update/Delete/Insert),如果SQL相同且且资料库也没有变动则将缓存中的结果直接返回。

值得一提的是,Query上有list()与iterator()2个方法用于结果集返回。他们的区别是,list()方法在读取数据库时不会使用缓存机制而直接向数据库发起查询,而iterator()则会将读取到的结果写到缓存中,以便于读取时再次利用。

1.Session session = sessionFactory.openSession();<br />2.<br />3.Query query = session.createQuery("from User");<br />4.List users = query.list();<br />5.users = query.list();<br />6.7.session.close();

执行结果:

Hibernate: select user0_.id as id, user0_.name as name0_, user0_.age as age0_ from user user0_<br />Hibernate: select user0_.id as id, user0_.name as name0_, user0_.age as age0_ from user user0_

1.Session session = sessionFactory.openSession();2.3.Query query = session.createQuery(“from User”);4.Iterator users = query.iterate();5.users = query.iterate();6.7.session.close();

执行结果:

Hibernate: select user0_.id as col_0_0_ from user user0_Hibernate: select user0_.id as col_0_0_ from user user0_

由于使用iterator()方法时会使用到Session level缓存,所以在查询大量记录时会好用大量的记忆体。必要时可以使用Session的evict()或clear()方法来清除缓存。

请参阅:http://blogger.org.cn/blog/more.asp?name=NaddyLee&id=31540

请注意,尽管iterator()方法时会使用到Session level缓存,但这不能就说在任何情况下都是最有效率的做法。

请看下面的测试:

1.package com.hb3.pack_22;<br />2.<br />3.import java.io.IOException;<br />4.import java.sql.SQLException;<br />5.import java.util.Iterator;<br />6.import java.util.List;<br />7.8.import org.hibernate.Query;<br />9.import org.hibernate.Session;<br />10.import org.hibernate.SessionFactory;<br />11.import org.hibernate.cfg.Configuration;<br />12.13.import com.hb3.pack_22.model.User;<br />14.15.public class BusinessService {<br />16.17.    public static void main(String[] args) throws IOException, SQLException {<br />18.<br />19.        Configuration config = new Configuration().configure();<br />20.        SessionFactory sessionFactory = config.buildSessionFactory();      <br />21.        Session session = sessionFactory.openSession();<br />22.23.<br />24.        String hql = "from com.hb3.pack_22.model.User";<br />25.<br />26.        Query query = session.createQuery(hql);<br />27.<br />28.//        List<?> list = query.list();29.//        Iterator<?> iterator = list.iterator();30.//        while (iterator.hasNext()) {31.//          User user = (User)iterator.next();32.//          System.out.println(user.getRoom().getAddress());33.//      }34.//        System.out.println("=====================================");35.//        list = query.list();36.//        iterator = list.iterator();37.//        while (iterator.hasNext()) {38.//          User user = (User)iterator.next();39.//          System.out.println(user.getRoom().getAddress());40.//      }41.//<br />42.//        System.out.println("++++++++++++++++++++++++++++++++++++++");43.<br />44.        query = session.createQuery(hql);<br />45.        Iterator<?> iterator = query.iterate();<br />46.        while (iterator.hasNext()) {<br />47.            User user = (User)iterator.next();<br />48.            System.out.println(user.getName());<br />49.        }<br />50.        System.out.println("=====================================");<br />51.        iterator = query.iterate();<br />52.        while (iterator.hasNext()) {<br />53.            User user = (User)iterator.next();<br />54.            System.out.println(user.getName());<br />55.        }<br />56.<br />57.        session.close();<br />58.        sessionFactory.close();<br />59.    }<br />60.}

执行结果:

Hibernate: select user0_.id as col_0_0_ from user user0_Hibernate: select user0_.id as id0_1_, user0_.name as name0_1_, user0_.room_id as room3_0_1_, room1_.id as id1_0_, room1_.address as address1_0_ from user user0_ left outer join room room1_ on user0_.room_id=room1_.id where user0_.id=?chenyanHibernate: select user0_.id as id0_1_, user0_.name as name0_1_, user0_.room_id as room3_0_1_, room1_.id as id1_0_, room1_.address as address1_0_ from user user0_ left outer join room room1_ on user0_.room_id=room1_.id where user0_.id=?shenbin=====================================Hibernate: select user0_.id as col_0_0_ from user user0_chenyanshenbin

看见,Iterator中的元素并不是一次性返回的,而是一条一条返回的。当数据量庞大时,特性就会下降。

再看下面的测试代码:

1.package com.hb3.pack_22;<br />2.<br />3.import java.io.IOException;<br />4.import java.sql.SQLException;<br />5.import java.util.Iterator;<br />6.import java.util.List;<br />7.8.import org.hibernate.Query;<br />9.import org.hibernate.Session;<br />10.import org.hibernate.SessionFactory;<br />11.import org.hibernate.cfg.Configuration;<br />12.13.import com.hb3.pack_22.model.User;<br />14.15.public class BusinessService {<br />16.17.    public static void main(String[] args) throws IOException, SQLException {<br />18.<br />19.        Configuration config = new Configuration().configure();<br />20.        SessionFactory sessionFactory = config.buildSessionFactory();      <br />21.        Session session = sessionFactory.openSession();<br />22.23.<br />24.        String hql = "from com.hb3.pack_22.model.User";<br />25.<br />26.        Query query = session.createQuery(hql);<br />27.<br />28.        List<?> list = query.list();<br />29.        Iterator<?> iterator = list.iterator();<br />30.        while (iterator.hasNext()) {<br />31.            User user = (User)iterator.next();<br />32.            System.out.println(user.getRoom().getAddress());<br />33.        }<br />34.//        System.out.println("=====================================");35.//        list = query.list();36.//        iterator = list.iterator(); <br />37.//        while (iterator.hasNext()) {38.//          User user = (User)iterator.next();39.//          System.out.println(user.getRoom().getAddress());40.//      } <br />41.//42.//        System.out.println("++++++++++++++++++++++++++++++++++++++");43.<br />44.        query = session.createQuery(hql);<br />45.//        Iterator<?> iterator = query.iterate();46.//        while (iterator.hasNext()) {47.//          User user = (User)iterator.next(); <br />48.//          System.out.println(user.getName());49.//      }50.        System.out.println("=====================================");<br />51.        iterator = query.iterate();<br />52.        while (iterator.hasNext()) {<br />53.            User user = (User)iterator.next();<br />54.            System.out.println(user.getName());<br />55.        }<br />56.<br />57.        session.close();<br />58.        sessionFactory.close();<br />59.    }<br />60.}

执行的结果为:

Hibernate: select user0_.id as id0_, user0_.name as name0_, user0_.room_id as room3_0_ from user user0_Hibernate: select room0_.id as id1_0_, room0_.address as address1_0_ from room room0_ where room0_.id=?NTU-M8-419NTU-M8-419=====================================Hibernate: select user0_.id as col_0_0_ from user user0_chenyanshenbin

这明显在性能上要优于刚才的做法。可见,首次查询使用query.list性能要优于query.iterate,之后再做相同的查询请求时,则借助缓存机制,使用query.iterate会大大提高性能。

快乐时,想想我的影子,我会在云上为你喝彩

hibernate3学习笔记(二十二)|Query缓存机制

相关文章:

你感兴趣的文章:

标签云: