性能分析

抓取策略

研究对象

研究怎么样提取集合的,该策略应该作用与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();
}

一对多

案例一

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

案例二  左外连接

结构不是很好,数据为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语句查询

Hibernate(二)的更多相关文章

  1. Hibernate二次学习一----------Hibernate简单搭建

    因为博客园自带的markdown不太好用,因此所有markdown笔记都使用cmd_markdown发布 Hibernate二次学习一----------Hibernate简单搭建: https:// ...

  2. hibernate(二)一级缓存和三种状态解析

    序言 前一篇文章知道了什么是hibernate,并且创建了第一个hibernate工程,今天就来先谈谈hibernate的一级缓存和它的三种状态,先要对着两个有一个深刻的了解,才能对后面我要讲解的一对 ...

  3. Hibernate(二)——POJO对象的操作

    POJO对象其实就是我们的实体,这篇博客总结一下框架对POJO对象对应数据库主键的生成策略,和一些对POJO对象的简单增删改查的操作.  一,Hibernate框架中主键的生成策略有三种方式: 1,数 ...

  4. Spring整合Hibernate 二 - 声明式的事务管理

    Spring大战Hibernate之声明式的事务管理 Spring配置文件: 添加事务管理类的bean: <bean id="txManager" class="o ...

  5. Hibernate(二)__简单实例入门

    首先我们进一步理解什么是对象关系映射模型? 它将对数据库中数据的处理转化为对对象的处理.如下图所示: 入门简单实例: hiberante 可以用在 j2se 项目,也可以用在 j2ee (web项目中 ...

  6. Hibernate二 映射 注解 一级缓存

    Hibernate映射1.@Entity 被该注解修饰的POJO类是一个实体,可以用name属性指定该实体类的名称,系统默认以该类的类名作为实体类的名称.2.@Table 指定持久化类所映射的表,它的 ...

  7. Hibernate 二(一级缓存,多表设计之一对多)

    1       对象状态与一级缓存 1.1   状态介绍 l  hibernate 规定三种状态:瞬时态.持久态.脱管态 l  状态 瞬时态:transient,session没有缓存对象,数据库也没 ...

  8. ssh架构之hibernate(二)进阶学习

    1.JPA入门 JPA的认识:JPA全称Java Persistence API.JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中Java持久层AP ...

  9. Hibernate(二)持久化对象的状态

    简介 以前学习Hibernate的笔记,整理一下便发出来了,防止弄丢.有错误的话麻烦各位留言评论,感激不尽. 持久化类 Hibernate完成了从面向对象模型表示的对象至关系模型表示的数据结构的映射, ...

随机推荐

  1. javascript进阶笔记(1)

    学习js已经有一段时间了,大大小小还是能够做出一些东西来.不过觉得可惜的是,还是对js本身这门语言不是很熟悉,总有一点雾里看花的感觉,看得见,但是看不清楚.最近发现有一本关于js的叫做<忍者秘籍 ...

  2. jQuery操错题积累

    1: 解析: onBlur:焦点移除事件. onfocus:定义和用法 onfocus 事件在对象获得焦点时发生 onchange:定义和用法 onchange 事件会在域的内容改变时发生 nclic ...

  3. html 经验之谈

  4. POJ - 2635 E - The Embarrassed Cryptographer

    The young and very promising cryptographer Odd Even has implemented the security module of a large s ...

  5. 牛客多校第四场 G Maximum Mode

    链接:https://www.nowcoder.com/acm/contest/142/G来源:牛客网 The mode of an integer sequence is the value tha ...

  6. leetcode第11题:盛水最多的容器

    给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) .在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0).找出其中的两条线, ...

  7. Android修行之路------List view无法获取监听方法

    注意: 1.在list view自定义布局中如果添加滚动布局,会导致自定义布局无法获取监听. 2.如果ListView的每项布局里有像Button,ImageButton之类View的控键时,这些Vi ...

  8. django本身提供了runserver,为什么不能用来部署(runserver与uWSGI的区别)

    runserver方法是调试django时经常用到的运行方式,它使用django自带的. WSGI Server 运行,主要在测试和开发使用,并且runserver 开启的方式也是单线程. uWSGI ...

  9. winform 点击控件拖动窗体

    private Point mPoint = new Point(); private void 选择控件_MouseDown(object sender, MouseEventArgs e) { m ...

  10. L2-002. 链表去重(数组模拟)

    L2-002. 链表去重 因为数值比较小,所以直接用数组来模拟 #include<cstdio> #include<cstring> #include<iostream& ...