您的位置:首页 > 其它

hibernate缓存机制(二)-一级缓存解决n+1问题

2016-06-20 15:11 381 查看
前面已经提到了n+1问题,想了解n+1问题请访问hibernate缓存机制(一)-n+1问题

此篇文章我们瞎扯一下hibernate的一级缓存、hibernate的一级缓存是怎么解决n+1的问题以及存在的弊端。

一、hibernate一级缓存:

1.Session 级别的缓存,它同session邦定。它的生命周期和session相同。Session消毁,它也同时消毁;管理一级缓存,一级缓存无法取消,用两个方法管理,clear(),evict()

2.两个session 不能共享一级缓存,因它会伴随session的生命周期的创建和消毁;

3.Session缓存是实体级别的缓存,就是只有在查询对象级别的时候才使用,如果使用HQL和SQL是查询属性级别的,是不使用一级缓存的!切记!!!!

我们来看看hibernate提供的一级缓存:
/**

             * 此时会发出一条sql,将所有学生全部查询出来,并放到session的一级缓存当中

             * 当再次查询学生信息时,会首先去缓存中看是否存在,如果不存在,再去数据库中查询

             * 这就是hibernate的一级缓存(session缓存)

             */

            List<Student> stus = (List<Student>)session.createQuery("from Student")

                                    .setFirstResult(0).setMaxResults(30).list();

            Student stu = (Student)session.load(Student.class, 1);

我们来看看控制台输出:

Hibernate: select student0_.id as id2_, student0_.name as name2_, student0_.rid as rid2_, student0_.sex as sex2_ from t_student student0_ limit ?

我们看到此时hibernate仅仅只会发出一条 sql 语句,因为第一行代码就会将整个的对象查询出来,放到session的一级缓存中去,当需要再次查询学生对象时,此时首先会去缓存中看是否存在该对象,如果存在,则直接从缓存中取出,就不会再发sql了,但是要注意一点:hibernate的一级缓存是session级别的,所以如果session关闭后,缓存就没了,此时就会再次发sql去查数据库

try

        {

            session = HibernateUtil.openSession();

           

            /**

             * 此时会发出一条sql,将所有学生全部查询出来,并放到session的一级缓存当中

             * 当再次查询学生信息时,会首先去缓存中看是否存在,如果不存在,再去数据库中查询

             * 这就是hibernate的一级缓存(session缓存)

             */

            List<Student> stus = (List<Student>)session.createQuery("from Student")

                                    .setFirstResult(0).setMaxResults(30).list();

            Student stu = (Student)session.load(Student.class, 1);

            System.out.println(stu.getName() + "-----------");

        }

        catch (Exception e)

        {

            e.printStackTrace();

        }

        finally

        {

            HibernateUtil.close(session);

        }

        /**

         * 当session关闭以后,session的一级缓存也就没有了,这时就又会去数据库中查询

         */

        session = HibernateUtil.openSession();

        Student stu = (Student)session.load(Student.class, 1);

        System.out.println(stu.getName() + "-----------");

 

Hibernate: select student0_.id as id2_, student0_.name as name2_, student0_.sex as sex2_, student0_.rid as rid2_ from t_student student0_ limit ?

 

Hibernate: select student0_.id as id2_2_, student0_.name as name2_2_, student0_.sex as sex2_2_, student0_.rid as rid2_2_, classroom1_.id as id1_0_, classroom1_.name as name1_0_, classroom1_.sid as sid1_0_, special2_.id as id0_1_, special2_.name as name0_1_,
special2_.type as type0_1_ from t_student student0_ left outer join t_classroom classroom1_ on student0_.rid=classroom1_.id left outer join t_special special2_ on classroom1_.sid=special2_.id where student0_.id=?

我们看到此时会发出两条sql语句,因为session关闭以后,一级缓存就不存在了,所以如果再查询的时候,就会再发sql。要解决这种问题,我们应该怎么做呢?这就要我们来配置hibernate的二级缓存了,也就是sessionFactory级别的缓存。
请参加下一篇文章,hibernate缓存机制(三)-二级缓存
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: