• 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>
  • 相关阅读:
    SuperSocket 1.4系列文档(16) 在SuperSocket中启用传输层加密(TLS/SSL)
    SuperSocket 1.4系列文档(10) SuperSocket中的日志功能
    UIPageControl实现自定义按钮
    ios 某些代码网址,app打包成ipa
    笔记隐藏状态栏,播放音乐,获取文件路径,nsthread,文件文件夹操作,plist 时间
    使用NSTimer实现倒计时,Iphone幻灯片效果+背景音乐,
    如何让你的iPhone程序支持多语言环境(本地化)
    iPhone电子书toolbar的实现
    iphone界面如何实现下拉列表
    使用NSTimer与iphone的简单动画,实现飘雪效果
  • 原文地址:https://www.cnblogs.com/loaderman/p/10037858.html
Copyright © 2020-2023  润新知