hibernate一级缓存

为什么要用缓存?

         目的:减少对数据库的访问次数!从而提升hibernate的执行效率!

Hibernate中缓存分类:

         一级缓存

         二级缓存


概念

1)Hibenate中一级缓存,也叫做session的缓存,它可以在session范围内减少数据库的访问次数!  只在session范围有效! Session关闭,一级缓存失效!

2)当调用session的save/saveOrUpdate/get/load/list/iterator方法的时候,都会把对象放入session的缓存中。

3)Session的缓存由hibernate维护, 用户不能操作缓存内容; 如果想操作缓存内容,必须通过hibernate提供的evit/clear方法操作。

特点:

         只在(当前)session范围有效,作用时间短,效果不是特别明显!

         在短时间内多次操作数据库,效果比较明显!


缓存相关几个方法的作用

session.flush();       让一级缓存与数据库同步

                   session.evict(arg0);    清空一级缓存中指定的对象

                   session.clear();       清空一级缓存中缓存的所有对象

在什么情况用上面方法?

                   批量操作使用使用:

                             Session.flush();   // 先与数据库同步

                             Session.clear();   // 再清空一级缓存内容


面试题1: 不同的session是否会共享缓存数据?

不会。

User1  u1 = Session1.get(User.class,1);   把u1对象放入session1的缓存

Session2.update(u1);     把u1放入session2的缓存

U1.setName(‘new Name’);

如果生成2条update sql, 说明不同的session使用不同的缓存区,不能共享。

面试题2: list与iterator查询的区别?

list()

一次把所有的记录都查询出来,

会放入缓存,但不会从缓存中获取数据

         Iterator

                   N+1查询; N表示所有的记录总数

                   即会先发送一条语句查询所有记录的主键(1),

再根据每一个主键再去数据库查询(N)!

会放入缓存,也会从缓存中取数据!


package loaderman.a_status;


import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import org.junit.Test;

public class App2_cache {

    private static SessionFactory sf;
    static {
        sf = new Configuration()
                .configure()
                .addClass(User.class)   // 测试时候使用
                .buildSessionFactory();
    }

    @Test
    public void testCache() throws Exception {
        Session session = sf.openSession();
        session.beginTransaction();
        User user = null;
        // 查询
        user = (User) session.get(User.class, 5);// 先检查缓存中是否有数据,如果有不查询数据库,直接从缓存中获取
        user = (User) session.get(User.class, 5);// 先检查缓存中是否有数据,如果有不查询数据库,直接从缓存中获取

        session.getTransaction().commit();
        session.close();
    }



    @Test
    public void flush() throws Exception {
        Session session = sf.openSession();
        session.beginTransaction();

        User user = null;
        user = (User) session.get(User.class, 5);
        user.setUserName("Jack");
        // 缓存数据与数据库同步
        session.flush();

        user.setUserName("Jack_new");

        session.getTransaction().commit();  // session.flush();
        session.close();
    }

    @Test
    public void clear() throws Exception {
        Session session = sf.openSession();
        session.beginTransaction();

        User user = null;
        // 查询
        user = (User) session.get(User.class, 5);
        // 清空缓存内容
//        session.clear(); // 清空所有
        session.evict(user);// 清除指定

        user = (User) session.get(User.class, 5);


        session.getTransaction().commit();  // session.flush();
        session.close();
    }

    @Test
    public void sessionTest() throws Exception {
        Session session1 = sf.openSession();
        session1.beginTransaction();
        Session session2 = sf.openSession();
        session2.beginTransaction();

        // user放入session1的缓存区
        User user = (User) session1.get(User.class, 1);
        // user放入session2的缓存区
        session2.update(user);

        // 修改对象
        user.setUserName("New Name");  // 2条update



        session1.getTransaction().commit();  // session1.flush();
        session1.close();
        session2.getTransaction().commit();  // session2.flush();
        session2.close();
    }
}
package loaderman.a_status;

import java.util.Iterator;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import org.junit.Test;

public class App3_list_iterator {

    private static SessionFactory sf;
    static {
        sf = new Configuration()
                .configure()
                .addClass(User.class)   // 测试时候使用
                .buildSessionFactory();
    }
    /**
     * list与iterator区别
     * 1. list 方法
     * 2. iterator 方法
     * 3. 缓存
     * @throws Exception
     */
    //1.  list 方法
    @Test
    public void list() throws Exception {
        Session session = sf.openSession();
        session.beginTransaction();
        // HQL查询
        Query q = session.createQuery("from User ");
        // list()方法
        List<User> list = q.list();

        for (int i=0; i<list.size(); i++){
            System.out.println(list.get(i));
        }

        session.getTransaction().commit();
        session.close();
    }

    //2. iterator 方法
    @Test
    public void iterator() throws Exception {
        Session session = sf.openSession();
        session.beginTransaction();
        // HQL查询
        Query q = session.createQuery("from User ");
        // iterator()方法
        Iterator<User> it = q.iterate();
        while(it.hasNext()){
            // 得到当前迭代的每一个对象
            User user = it.next();
            System.out.println(user);
        }



        session.getTransaction().commit();
        session.close();
    }


    //3. 缓存
    @Test
    public void cache() throws Exception {
        Session session = sf.openSession();
        session.beginTransaction();

        /**************执行2次list*****************
         Query q = session.createQuery("from User");
         List<User> list = q.list();      // 【会放入?】
         for (int i=0; i<list.size(); i++){
         System.out.println(list.get(i));
         }
         System.out.println("=========list===========");
         list = q.list();                // 【会放入?】
         for (int i=0; i<list.size(); i++){
         System.out.println(list.get(i));
         }

         /**************执行2次iteator******************/
        Query q = session.createQuery("from User ");
        Iterator<User> it = q.iterate();        // 【放入缓存】
        while(it.hasNext()){
            User user = it.next();
            System.out.println(user);
        }
        System.out.println("==========iterate===========");
        it = q.iterate();                        // 【也会从缓存中取】
        while(it.hasNext()){
            User user = it.next();
            System.out.println(user);
        }

        session.getTransaction().commit();
        session.close();
    }

    // 测试list方法会放入缓存
    @Test
    public void list_iterator() throws Exception {
        Session session = sf.openSession();
        session.beginTransaction();

        // 得到Query接口的引用
        Query q = session.createQuery("from User ");

        // 先list  【会放入缓存,但不会从缓存中获取数据】
        List<User> list = q.list();
        for (int i=0; i<list.size(); i++){
            System.out.println(list.get(i));
        }

        // 再iteraotr  (会从缓存中取)
        Iterator<User> it = q.iterate();
        while(it.hasNext()){
            User user = it.next();
            System.out.println(user);
        }

        session.getTransaction().commit();
        session.close();
    }
}
package loaderman.a_status;


public class User {

    private int userId;
    private String userName;
    public int getUserId() {
        return userId;
    }
    public void setUserId(int userId) {
        this.userId = userId;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    @Override
    public String toString() {
        return "User [userId=" + userId + ", userName=" + userName + "]";
    }
    
    
}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="loaderman.a_status">
    
    <class name="User" table="t_user">
        <id name="userId" column="id">
            <generator class="native"></generator>
        </id>    
        <property name="userName"></property>
    </class>
    

</hibernate-mapping>
原文地址:https://www.cnblogs.com/loaderman/p/10037858.html