• Hibernate-缓存/懒加载/抓取策略


    懒加载测试:      
         /*类的延迟加载
          * * session.get * 1、方法加载出来的对象是class对象 * 2、在session.get方法执行的时候发出sql语句 * 3、class对象是有值的 * session.load * 1、方法加载出来的对象是class的代理对象 * 2、在加载其属性的时候发出sql语句(按照需求加载,延迟加载) * 3、获取标识符属性是不用延迟加载的,获取普通属性是需要发出sql语句的 * 标识符属性对于延迟加载不起作用
    */ 映射文件: Class.hbm.xml 实体类: Class Hibernate类的延迟加载测试: Configuration configuration = new Configuration(); configuration.configure("com/hibernate/lazy/hibernate.cfg.xml"); sessionFactory = configuration.buildSessionFactory(); ClassLazyTest: session.get(CLass.class,1L); session.close(); session.load(CLass.class,1L); session.close(); /* * session.get * 1、方法加载出来的对象是class对象 * 2、在session.get方法执行的时候发出sql语句 * 3、class对象是有值的 session.load * 1、方法加载出来的对象是class的代理对象 * 2、在加载其属性的时候发出sql语句(按照需求加载,延迟加载) * 3、获取标识符属性是不用延迟加载的,获取普通属性是需要发出sql语句的标识符属性对于延迟加载不起作用 */ ReferenceRelationTest: Class user =(Class)session.get(Class.class,1L); Set<Student> student = user.getStudents(); for(Student stu : student) { System.out.println(stu.getName()); } seesion.close(); 深入: /* * 当集合的lazy为true时 * Hibernate: select students0_.cid as cid0_1_, students0_.sid as sid1_, students0_.sid as sid1_0_, students0_.sname as sname1_0_, students0_.cid as cid1_0_ from student students0_ where students0_.cid=? * 当集合的lazy为extra时 extra为更进一步的延迟加载 * Hibernate: select count(sid) from student where cid =? */

      那什么时候使用懒加载? 处理大数据量时,为了减少对数据库的查询次数和对数据的取舍(有些没用到的关联数据夜查出来了),这时候就应当使用它。

    抓取策略:

    部分代码测试贴上:

    /*
     * 抓取策略
     *         例子:在加载class的时候怎么样去加载student
     *         应用范围:在加载一端对象的时候,去加载多的一端对象的时候的方式
     *      抓取策略和延迟加载----->研究对象是集合,这一点应该不难理解,懒加载是在一对多/多对多关联中,从的一方拿数据是否延迟加载多的那方。 抓取策略则是操作者本身已经明确了需要获取哪些数据,并且是在关联关系简单生成的SQL语句却很多,针对的也是一对多/多对多的关系
     *         lazy         fetch
     *         false         select   有作用
     *         true          join       延迟加载失效
     *         false        subselect  有作用
     * 
     *         总结:当fetch为join时,延迟加载失去作用
     *              当fetch为select时或者为subselect时,延迟加载能控制sql语句的发出时间
     *      
     */
    public class FetchTest {
        private static SessionFactory sessionFactory = null;
        static {
            Configuration configuration = new Configuration();
            configuration.configure("cn/heima5/hibernate/fetch/hibernate.cfg.xml");
            sessionFactory = configuration.buildSessionFactory();
        }
    
        /*
         * 先查询所有的class数据,再根据class查询student,其本身的查询符合子查询
         * 所以在这个例子中,可以用fetch="subselect"提高效率 1、如果用fetch="select"将导致n+1次查询
         * n代表class表中的行数 2、用fetch="join"不起作用
         * 3、应用fetch="subselect"或者fetch="select"与batch-size结合起来使用
         */
        @Test
        public void testQuery() {
            Session session = sessionFactory.openSession();
    
            List<Class> classList = session.createQuery("from Class").list();
    
            for (Class class1 : classList) {
                Set<Student> students = class1.getStudents();
                for (Student student : students) {
                    System.out.println(student.getSname());
                }
            }
    
            session.close();
        }
        /*
         * 说明
         *         1、如果fetch="select"发出两条sql语句
         *             第一条查询给定的ID的值的class对象
         *             第二条查询根据cid查询student
         *         2、如果fetch="join",发出一条sql语句  左外连接
         */
        @Test
        public void testQuery2() {
            Session session = sessionFactory.openSession();
    
            Class class1 = (Class)session.get(Class.class, 1L);
    
            Set<Student> students = class1.getStudents();
            for (Student student : students) {
                System.out.println(student.getSname());
            }
            
    
            session.close();
        }
        /*
         * 通过分析属于子查询的内容,所以抓取策略为fecth="subselect"
         */
        @Test
        public void testQuery3(){
            Session session = sessionFactory.openSession();
    
            List<Class> classList = session.createQuery("from Class where cid in(1,2,3,5,7)").list();
    
            for (Class class1 : classList) {
                Set<Student> students = class1.getStudents();
                for (Student student : students) {
                    System.out.println(student.getSname());
                }
            }
            
    
            session.close();
        }
    总结:当fetch为join时,延迟加载失去作用
       当fetch为select时或者为subselect时,延迟加载能控制sql语句的发出时间

         

    Session缓存:

     后续更新

  • 相关阅读:
    新浪微博采用Oauth发送图片和文字
    android proguard也有弱点
    POJ 2376
    POJ 3259
    POJ 2253
    POJ 1062
    POJ 2299
    POJ 2186
    POJ 1860
    POJ 2823
  • 原文地址:https://www.cnblogs.com/xmaomao/p/3267235.html
Copyright © 2020-2023  润新知