Hibernate查询缓存
博客专区 > markGao 的博客 > 博客详情
Hibernate查询缓存
markGao 发表于4年前
Hibernate查询缓存
  • 发表于 4年前
  • 阅读 1033
  • 收藏 1
  • 点赞 0
  • 评论 0

华为云·免费上云实践>>>   

摘要: 查询缓存是专门针对各种查询操作进行缓存。查询缓存会在整个SessionFactory的生命周期中起作用,存储的方式也是采用key-value的形式来进行存储的。

查询缓存中的key是根据查询的语句、查询的条件、查询的参数和查询的页数等信息组成的。而数据的存储则会使用两种方式,使用SELECT语句只查询实体 对象的某些列或者某些实体对象列的组合时,会直接缓存整个结果集。而对于查询结果为某个实体对象集合的情况则只会缓存实体对象的ID值,以达到缓存空间可 以共用,节省空间的目的。

在使用查询缓存时,除了需要设置hibernate.cache.provider_class参数来启动二级缓存外,还需要通过hibernate.cache.use_query_cache参数来启动对查询缓存的支持。

另外需要注意的是,查询缓存是在执行查询语句的时候指定缓存的方式以及是否需要对查询的结果进行缓存。

下面就来了解一下查询缓存的使用方法及作用。

       修改Hibernate配置文件

       首先需要修改Hibernate的配置文件,增加hibernate.cache.use_query_cache参数的配置。配置方法如下:

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

       Hibernate配置文件的详细内容请参考配套光盘中的hibernate\src\cn\hxex\ hibernate\cache\hibernate.cfg.xml文件。

编写主测试程序

       由于这是在前面二级缓存例子的基础上来开发的,所以,对于EHCache的配置以及视图对象的开发和映射文件的配置工作就都不需要再重新进行了。下面就来看一下主测试程序的实现方法,如清单14.11所示。

       清单14.11    主程序的实现

import java.util.Iterator;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class QueryCache extends Thread {

    public static final SessionFactory sessionFactory;

    static {
        try {
            // Create the SessionFactory from hibernate.cfg.xml
            sessionFactory = new Configuration().configure()
                    .buildSessionFactory();
        } catch (Throwable ex) {
            // Make sure you log the exception, as it might be swallowed
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public void run() {

        SessionFactory sf = QueryCache.sessionFactory;

        Session session = sf.getCurrentSession();

        session.beginTransaction();

        Query query = session.createQuery("from User");

        Iterator it = query.setCacheable(true).list().iterator();

        while (it.hasNext()) {

            System.out.println(it.next());

        }

        // User user = (User)session.get( User.class, "1" );

        // System.out.println(user);

        session.getTransaction().commit();

    }

    public static void main(String[] args) {

        QueryCache main1 = new QueryCache();

        main1.start();

        try {

            Thread.sleep(2000);

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

        QueryCache main2 = new QueryCache();

        main2.start();

    }

}

主程序在实现的时候采用了多线程的方式来运行。首先将“from User”查询结果进行缓存,然后再通过ID取得对象来检查是否对对象进行了缓存。另外,多个线程的执行可以看出对于进行了缓存的查询是不会执行第二次的。

       运行测试主程序

       接着就来运行测试主程序,其输出结果应该如下所示:

Hibernate: select user0_.userId as userId0_, user0_.name as name0_, user0_.age as age0_ from USERINFO user0_

ID: 1

Namge:   galaxy

Age:       32

ID: 1

Namge:   galaxy

Age:       32

ID: 1

Namge:   galaxy

Age:       32

ID: 1

Namge:   galaxy

Age:       32

       通过上面的执行结果可以看到,在两个线程执行中,只执行了一个SQL查询语句。这是因为根据ID所要获取的对象在前面的查询中已经得到了,并进行了缓存,所以没有再次执行查询语句。


共有 人打赏支持
粉丝 16
博文 151
码字总数 91352
×
markGao
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: