hibernate 对象OID
它是hibernate用于区分两个对象是否是同一个对象的标识。
我们都知道,虚拟机内存区分两个对象看的是内存的地址是否一致。数据库区分两个对象,靠的是表的主键。hibernate负责把内存中的对象持久化到数据库表中,靠的就是对象标识符来区分两个对象是否是同一个。实体类中映射主键的字段就是OID 在映射文件中对应数据库主键的属性
自然主键:把具有业务含义的字段作为主键,称之为自然主键。
代理主键:把不具备业务含义的字段作为主键,称之为代理主键。该字段一般取名为“ID”,通常为整数类型,因为整数类型比字符串类型要节省更多的数据库空间。在上面例子中,显然更合理的方式是使用代理主键
1.1.1 hibernate中的一级缓存:
Hibernate的一级缓存就是指Session缓存,Session缓存是一块内存空间,用来存放相互管理的java对象,在使用Hibernate查询对象的时候,首先会使用对象属性的OID值在Hibernate的一级缓存中进行查找,如果找到匹配OID值的对象,就直接将该对象从一级缓存中取出使用,不会再查询数据库;如果没有找到相同OID值的对象,则会去数据库中查找相应数据。当从数据库中查询到所需数据时,该数据信息也会放置到一级缓存中。Hibernate的一级缓存的作用就是减少对数据库的访问次数。
Hibernate的一级缓存有如下特点:
当应用程序调用Session接口的save()、update()、saveOrUpdate时,如果Session缓存中没有相应的对象,Hibernate就会自动的把从数据库中查询到的相应对象信息加入到一级缓存中去。
当调用Session接口的load()、get()方法,以及Query接口的list()、iterator()方法时,会判断缓存中是否存在该对象,有则返回,不会查询数据库,如果缓存中没有要查询对象,再去数据库中查询对应对象,并添加到一级缓存中。
当调用Session的close()方法时,Session缓存会被清空。
1.1.1 快照机制:
Hibernate 向一级缓存放入数据时,同时复制一份数据放入到Hibernate快照中,当使用commit()方法提交事务时,同时会清理Session的一级缓存,这时会使用OID判断一级缓存中的对象和快照中的对象是否一致,如果两个对象中的属性发生变化,则执行update语句,将缓存的内容同步到数据库,并更新快照;如果一致,则不执行update语句。Hibernate快照的作用就是确保一级缓存
中的数据和数据库中的数据一致。
1、 瞬时态(transient)
瞬时态也称为临时态或者自由态,瞬时态的实例是由new命令创建、开辟内存空间的对象,不存在持久化标识OID(相当于主键值),尚未与Hibernate Session关联,在数据库中也没有记录,失去引用后将被JVM回收。瞬时状态的对象在内存中是孤立存在的,与数据库中的数据无任何关联,仅是
一个信息携带的载体。
2、 持久态(persistent)
持久态的对象存在持久化标识OID ,加入到了Session缓存中,并且相关联的Session没有关闭,在数据库中有对应的记录,每条记录只对应唯一的持久化对象,需要注意的是,持久态对象是在事务还未提交前变成持久态的。
3、 脱管态(detached)
脱管态也称离线态或者游离态,当某个持久化状态的实例与Session的关联被关闭时就变成了脱管态。脱管态对象存在持久化标识OID,并且仍然与数据库中的数据存在关联,只是失去了与当前Session的关联,脱管状态对象发生改变时Hibernate不能检测到。
、区分状态只有两个标识
一是否有OID
二是否和Session建立的关系
临时状态:
没有OID,和Session没有关系。
持久化状态:
有OID,和Session有关系。
脱管状态:
有OID,和Session没有关系。
其实最主要的是如何保证在Service中开启的事务时使用的Session对象和DAO中多个操作使用的是同一个Session对象。
其实有两种办法可以实现:
可以在业务层获取到Session,并将Session作为参数传递给DAO。
可以使用ThreadLocal将业务层获取的Session绑定到当前线程中,然后在DAO中获取Session的时候,都从当前线程中获取。
1.1.1.1 统计查询
/**
* HQL使用聚合函数:
* 统计查询
* 聚合函数:
* count sum max min avg
*
* sql语句使用聚合函数时,在不使用group by子句的情况下,返回的结果,永远只有一行一列的情况。
*
* 在SQL语句时:
* select count(*) from table 它是统计所有字段,效率没有只统计主键字段高
* select count(主键) from table 它和第一个的结果是一样的,但是效率更高
* select count(非主键) from table 只统计不为null的字段
*/
@Test
public void test1(){
Session s = HibernateUtil.getCurrentSession();
Transaction tx = s.beginTransaction();
Query query = s.createQuery("select count(lkmId) from LinkMan");//它最终仍然换转成SQL语句
// List list = query.list();
// for(Object o : list){;
// System.out.println(o);
// }
Long total = (Long)query.uniqueResult();//返回的是一个唯一的结果集。 只有确定结果集唯一时,才能使用
System.out.println(total);
tx.commit();
}
1.1.1.1 分页查询
/**
* mysql的分页关键字
* limit
* limit的参数含义
* 第一个:查询的开始记录索引
* 第二个:每次查询的条数
* hibernate中针对分页提供了两个方法
* setFirstResult(int firstResult);设置开始记录索引
* setMaxResults(int maxResults);设置每次查询的记录条数
*/
@Test
public void test4(){
Session s = HibernateUtil.getCurrentSession();
Transaction tx = s.beginTransaction();
//1.获取Query对象
Query query = s.createQuery("from Customer");
//2.设置分页的方法
query.setFirstResult(2);
query.setMaxResults(2);
//3.执行对象的方法,获取结果集
List list = query.list();
for(Object o : list){
System.out.println(o);
}
tx.commit();
}
在Hibernate中Criterion对象的创建通常是通过Restrictions 工厂类完成的,它提供了条件查询方法。
通常,使用Criteria对象查询数据的主要步骤,具体如下:
(1)获得Hibernate的Session对象。
(2)通过Session获得Criteria对象。
(3)使用Restrictions的静态方法创建Criterion条件对象。Restrictions类中提供了一系列用于设定查询条件的静态方法,这些静态方法都返回Criterion实例,每个Criterion实例代表一个查询条件。
(4)向Criteria对象中添加Criterion 查询条件。Criteria的add()方法用于加入查询条件。
(5)执行Criterita的 list() 或uniqueResult() 获得结果。
细节:
HQL能查的,QBC都能查,反之亦然。
了解了Criteria对象的使用步骤后,接下来,通过具体示例来演示Criteria对象的查询操作。
1.1.1.1 离线查询
/**
* 离线条件查询
* 离线:
* 它是和在线对应的。
* Criteria对象是一个在线对象,它是由一个可用的(活动的)Session对象获取的出来的。
* 当session失效时,就无法再获取该对象了。
* 有一个对象,它也可以用于设置条件,但是获取的时候并不需要Session对象。
* 该对象就叫做离线对象:
* DetachedCriteria对象
* 使用该对象进行的查询就叫做:离线查询
*
* 如何获取该对象
* DetachedCriteria dCriteria = DetachedCriteria.forClass(要查询的实体类字节码);
*
*/
@Test
public void test3(){
//模拟一次web操作: 浏览器发送请求——调用servlet——调用service——调用dao——拿到结果到jsp上展示
List list = servletFindAllCustomer();
for(Object o : list){
System.out.println(o);
}
}
//模拟servlet
public List<Customer> servletFindAllCustomer(){
//离线对象
DetachedCriteria dCriteria = DetachedCriteria.forClass(Customer.class);
//设置条件:和Criteria是一样的
dCriteria.add(Restrictions.like("custName","%集%"));
return serviceFindAllCustomer(dCriteria);
}
public List<Customer> serviceFindAllCustomer(DetachedCriteria dCriteria) {
return daoFindAllCustomer(dCriteria);
}
public List<Customer> daoFindAllCustomer(DetachedCriteria dCriteria) {
Session s = HibernateUtil.getCurrentSession();
Transaction tx = s.beginTransaction();
//把离线对象使用可用Session激活
Criteria c = dCriteria.getExecutableCriteria(s);
List<Customer> list = c.list();
tx.commit();
return list;
}
1.1.1.1 统计查询
/**
* QBC使用聚合函数
* 统计查询
* 涉及的对象:
* Criteria
* 涉及的方法:
* setProjection(Projection p);
* 参数的含义
* Projection:要添加的查询投影
*/
@Test
public void test2(){
Session s = HibernateUtil.getCurrentSession();
Transaction tx = s.beginTransaction();
//1.获取对象
Criteria c = s.createCriteria(Customer.class);//from Customer | select * from cst_customer
//2.想办法把select * 变成 select count(*)
// c.setProjection(Projections.rowCount());//select count(*)
c.setProjection(Projections.count("custId"));//select count(cust_id)
//3.获取结果集
// List list = c.list();
// for(Object o : list){
// System.out.println(o);
// }
Long total = (Long)c.uniqueResult();
System.out.println(total);
tx.commit();
}
hibernate 对象OID的更多相关文章
- Hibernate 对象的三种状态
hibernate对象的三种状态: (一) 瞬时(临时)状态: 对象被创建时的状态,数据库里面没有与之对应的记录! (二) 持久状态: 处于session的管理中,并且数据库里面存在与之对应的 ...
- Hibernate对象的状态和映射
一. Hibernate对象的状态 实体对象的三种状态: 1) 暂态(瞬时态)(Transient)---实体在内存中的自由存在,它与数据库的记录无关. po在DB中无记录(无副本),po和sessi ...
- Hibernate学习(4)- Hibernate对象的生命周期
1.Hibernate对象的生命周期(瞬时状态.持久化状态.游离状态) 1.瞬时状态(Transient): 使用new操作符初始化的对象就是瞬时状态,没有跟任何数据库数据相关联:2.持久化状态(Pa ...
- Hibernate之OID
在关系数据库中,主键用来识别记录,并保证每天记录的唯一性.在Java语言中,通过比较两个变量所引用对象的内存地址是否相同,或者比较两变量引用的对象是否相等.Hibernate为了解决两者之间的不同,使 ...
- Hibernate(3)——实例总结Hibernate对象的状态和ThreadLoacl封闭的session
俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及的知识点总结如下: Hibernate的内部执行过程(CRUD) 对象的状态及其转换图和例子 使用JUnit测试 使用getCur ...
- hibernate对象的三种状态
对于hibernate,我想不在这里讲解了,我们就直接进入主题 在这里我将要说的是"hibernate对象的三种状态",对象是我们十分熟悉的,对吧!而对于对象它有三种状态 分别是瞬 ...
- hibernate 对象三态(瞬态、持久态、脱管态)之我见
刚开始学习hibernate时,对其对象的三种状态理解的模模糊糊,一直停留在一知半解的状态,前两天又回顾了一下,顿时醒悟,原来三种状态理解起来是很容易的. 先看一下对Hibernate对象状态的解释: ...
- 菜鸟学SSH(八)——Hibernate对象的三种状态
前面写了几篇关于SSH的博客,但不是Struts就是Spring,Hibernate还从来没写过呢.说好是SSH的,怎么可以光写那两个,而不写Hibernate呢对吧.今天就先说说Hibernate对 ...
- hibernate对象的三种状态及转换
一.hibernate对象三种状态 Transient(瞬时状态):没有session管理,同时数据库没有对应记录 举例:new 出来的对象还没有被session管理,此时该对象处于Transient ...
随机推荐
- IDT 查询 hana SQL 聚合问题。
因为业务需要,用HANA的数据做成DASHBOARD.工厂运营概况.结果发现奇怪的问题.明明是一个类型的但是不会聚合.(数据量特别大,一个月的应该就一条,但是有几千条做不下去.) 比如车辆类型是 焊装 ...
- mac下用brew安装mongodb
分享到:QQ空间新浪微博腾讯微博人人网微信 mac 下安装mongoDB一般俩种方法. (1)下载源码,解压,编译,配置,启动 比较艰难的一种模式. (2)brew install mongodb , ...
- spring MVC HandlerInterceptorAdapter
SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理.比如通过它来进行权限验证,或者是来判断用户是否登陆,或者是像12306 那 ...
- GET请求与POST请求区别
GET请求与POST请求区别 a:语义: GET:客户端想获取服务器资源 POST:客户端想传递数据给服务器 b:安全级: GET:不安全 POST:不安全 c:数据长度 GET:客户端发送数据最长1 ...
- 寻找数组中第K大数
1.寻找数组中的第二大数 using System; using System.Collections.Generic; using System.Linq; using System.Text; u ...
- 学习动态性能表(9)--v$filestat
学习动态性能表 第九篇--V$FILESTAT 2007.6.5 本视图记录各文件物理I/O信息.如果瓶颈与I/O相关,可用于分析发生的活动I/O事件.V$FILESTAT显示出数据库I/O的下列信 ...
- 横向排列两个多个div盒子的方法(CSS浮动清除float-clear/inline)/办法
最近在做一个div css切割,昨晚发现了长期以来一直无记录下来的问题!关于兼容IE跟FF的float属性.趁现在还清醒赶紧记下笔记先:一.并排在一行的两个div样式有这种情况:ie或者ff下对于子d ...
- Python List reverse()方法
reverse() 函数用于反向列表中元素,参数 NA,该方法没有返回值,但是会对列表的元素进行反向排序,原来的列表被改变,生成新的列表. 例子:list1 = ['Google', 'Runoob' ...
- 7.Selenium+Python实现搜索百度的测试用例
1.导入测试用例需要的模块,unittest是python的内置模块,它提供了组织测试用例的框架 import unittest # 导入测试用例的模块 2.测试用例继承于unittest class ...
- Springboot正常启动,但是访问404报错
原因: 查看是否配置文件中有以下配置: server.context-path=/hellopath 我这里是以/hellopath为例,如果有该配置的话,只能通过该路径访问到. 其他原因