zoukankan      html  css  js  c++  java
  • Hibernate(二)

    性能分析

    抓取策略

    研究对象

    研究怎么样提取集合的,该策略应该作用与set元素上

    研究从一的一方加载多的一方

    案例

    查询cid为1的班级的所有的学生

    明:通过一条sql语句:左外链接,把classes与student表的数据全部提取出来

    查询所有的班级的所有的学生

    该需求翻译过来含有子查询

    如果含有子查询,必须用subselect

    查询班级为1,2,3,4的所有的学生

    抓取策略总结

    1、  研究对象是集合

    2、  经过分析,如果sql语句中含有了子查询,则用subselect效率比较高

    3、  如果页面上需要一次性把两张表的数据全部提取出来,用join效率比较高

    因为采用”join”为左外链接

    4、  如果用select,先查询班级,后查询学生,如果查询班级的个数超过1个,会导致n+1条sql语句

    5、  抓取策略是hibernate提供的一种优化方式而已

    延迟加载

    概念

           需要用到该数据的时候才要加载

    种类

    类的延迟加载

    案例

    说明:

    1、  执行22行代码的时候,不发出sql语句,说明类的延迟加载和主键没有关系

    2、  执行23行代码的时候,发出sql语句,说明只有在得到具体属性的时候才要发出sql语句。

    3、  Session.load方法返回的对象是

    而该对象是由javassist的jar包生成的,从代码结构可以看出该代理对象是持久化类的子类。

    4、  在Classes.hbm.xml文件中

    Lazy的属性默认为true

         5、如果把上述的lazy改成false,则类的延迟加载不起作用了,默认为延迟加载。

    集合的延迟加载

    案例一

    值说明

     默认情况是true,当遍历集合的时候发出sql语句

      Lazy的值为false,当加载classes的时候就把student加载出来了

      Extra是更进一步的延迟加载策略,如果求大小、平均数、和等

    案例二

    案例三

    manytoone的延迟加载

    No-proxy 延迟加载   默认值

    Proxy是加强版的延迟加载

    因为是通过多的一方加载一的一方,所以对效率影响不大,所以一般情况下用默认值即可

    延迟加载总结:

      延迟加载是通过什么时候发出sql语句来优化性能的。

    抓取策略和延迟加载的结合

    Set集合

    1、  当fetch为join时,lazy失效

    2、  当fetch为select时

    如果lazy为true/extra

            当遍历集合的时候,发出加载集合的sql语句

    如果lazy为false

            当获取班级的时候,发出加载集合的sql语句

    3、  当fetch为subselect时和上面的情况一致。

    二级缓存

    概念:是sessionFactory级别的缓存

    存放的是共有数据 共享数据

    生命周期随着hibernate容器启动就开始了,hibernate销毁结束

    hibernate本身对二级缓存没有实现,是借助第三方插件实现的

    公有数据的特征

    1.一般情况下保持不变

    所有的人都能访问

    访问的频率比较高

    安全性不是特别高的数据

    配置

    1.  hibernate.cfg.xml

    2.src 下的ehcache.xml文件

    3.class映射文件

    案例一

    案例二

    说明:session.save方法不进二级缓存

     案例三

    案例四

    说明:

         执行55行代码的时候,把classes表中的所有的对象进入到了二级缓存中

            执行59行代码的时候,重新从数据库中查找记录

         所以createQuery(hql).list方法能把一个对象放入到二级缓存中,但是不利用二级缓存获取对象。

    案例五

    在classpath的根目录下放置一个ehcache.xml文件

    从上述的配置可以看出,classes对象在内存中存放的数量最多为5个,多余的对象将存在磁盘上。

    查找classes表中所有的对象,在内存中放置5个对象,剩余的对象将被存在磁盘上

    案例六

     

     相当于开启了classes类中的set集合的二级缓存

    把集合放入到了二级缓存中。

    读写策略

           Usage

                  Ready-only

                         只能把一个对象放入到二级缓存中不能修改

           Read-write

                能把一个对象放入到二级缓存中,也能修改

    查询缓存

     概念:就是数据缓存 按照需求加载数据

    一级缓存和二级缓存都是对象缓存  表中与多少个字段 就会加载多少个数据

    配置

    1建立在二级缓存基础上

    2开启查询缓存

     案例一

    说明:

           当执行24行代码的时候,发出sql语句

           当执行30行代码的时候,没有发出sql语句,因为利用了查询缓存

    案例二

    说明:

    1、  当两次query.list的时候,都会发出sql语句

    2、  原因是两次的查询hql语句不一样。

    3、  从这里可以看出查询缓存的命中率比较低

    案例三

    从list的内存快照中可以看出,list里存放的不是持久化对象,而是name属性的值。

     一级缓存和二级缓存存放的是持久化对象,如果集合中存放的不是持久化对象,则不能进入二级缓存中,但是能够进入查询缓存中。

    数据缓存和对象缓存

    1、  一级缓存和二级缓存是对象缓存,只能缓存持久化对象

    2、  对象缓存的特别就是要把数据库表中所有的字段全部查询出来

    3、  查询缓存是数据缓存,可以查询一个对象的部分属性,而且可以把部分属性放入到查询缓存中,查询缓存也支持对象。命中率低

    hibernate二级缓存和查询缓存用得比较少

    Hql语句

    单表

    案例一

    from Classes

    案例二

     

    说明:List中含有Object[],该数组中有两个元素,第一个元素为Long类型,第二个元素为String类型。

     案例三

     

    案例四

    案例五

    案例六

    案例七 动态参数

    @Test
        public void testQuery_Dynamic_Parameter(){
            /**
             * key代表持久化类中属性的名称 
             * value代表属性的值
             */
            Map<String, String> map = new HashMap<String, String>();
            map.put("name","aa");
            this.queryDynamic(map, Classes.class);
        }
        
        private void queryDynamic(Map<String, String> map,Class className){
            Session session = sessionFactory.openSession();
            StringBuffer buffer = new StringBuffer();
            /**
             * classes持久化类的元数据
             */
            ClassMetadata classMetadata = sessionFactory.getClassMetadata(className);
            //得到持久化类的名称
            buffer.append("from "+classMetadata.getEntityName());
            buffer.append(" where 1=1");
            //得到map中所有的key值
            Set<String> keys = map.keySet();
            //拼接hql语句:查询条件
            Iterator<String> iterator = keys.iterator();
            for(int i=0;i<keys.size();i++){
                String temp = iterator.next();
                buffer.append(" and "+temp+"=:"+temp);
            }
            Query query = session.createQuery(buffer.toString());
            /**
             * 给所有的查询条件赋值
             */
            for(Entry<String, String> entry:map.entrySet()){
                query.setString(entry.getKey(), entry.getValue());
            }
            List<Classes> classesList = query.list();
            System.out.println(classesList.size());
            session.close();
        }
        
    View Code

    一对多

    案例一

    数据结构不合适,一般不用

    案例二  左外连接

    结构不是很好,数据为object类型数组

    案例三 

    数据为Classes数组

     案例四  迫切内连接

    数据为classes数组

    案例五

    说明:如果用select,则不能用fetch,如果用fetch,则不能用select。

    多对多

    案例一

    案例二

    一对多和多对多 三表内连接

     案例一

     hibernate内部的list

    hibernate内的map

    分页

    public void testDispage(){
            Session session = sessionFactory.openSession();
            Query query = session.createQuery(" from Classes ");
            query.setFirstResult(0);//当前页第一行的在列表中的位置
            query.setMaxResults(2);//当前页有多少行
            List<Classes> classesList = query.list();
            for(Classes c:classesList){
                System.out.println(c.getCid());
            }
            session.close();
        }
    分页

     三种查询方式

    原生的查询方式

    条件查询

    hql语句查询

  • 相关阅读:
    使用golang访问kubebernetes
    使用 Rancher 管理现有 Kubernetes 集群
    Running powershell scripts during nuget package installation and removal
    How to Create, Use, and Debug .NET application Crash Dumps in 2019
    寻找写代码感觉(一)之使用 Spring Boot 快速搭建项目
    Selenium+Java之解决org.openqa.selenium.InvalidArgumentException: invalid argument报错问题
    Selenium环境搭建
    关于Xpath定位方法知道这些基本够用
    Web自动化之浏览器启动
    【翻译】编写代码注释的最佳实践
  • 原文地址:https://www.cnblogs.com/hellowq/p/9647956.html
Copyright © 2011-2022 走看看