它是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的更多相关文章

  1. Hibernate 对象的三种状态

    hibernate对象的三种状态: (一) 瞬时(临时)状态:   对象被创建时的状态,数据库里面没有与之对应的记录! (二) 持久状态:   处于session的管理中,并且数据库里面存在与之对应的 ...

  2. Hibernate对象的状态和映射

    一. Hibernate对象的状态 实体对象的三种状态: 1) 暂态(瞬时态)(Transient)---实体在内存中的自由存在,它与数据库的记录无关. po在DB中无记录(无副本),po和sessi ...

  3. Hibernate学习(4)- Hibernate对象的生命周期

    1.Hibernate对象的生命周期(瞬时状态.持久化状态.游离状态) 1.瞬时状态(Transient): 使用new操作符初始化的对象就是瞬时状态,没有跟任何数据库数据相关联:2.持久化状态(Pa ...

  4. Hibernate之OID

    在关系数据库中,主键用来识别记录,并保证每天记录的唯一性.在Java语言中,通过比较两个变量所引用对象的内存地址是否相同,或者比较两变量引用的对象是否相等.Hibernate为了解决两者之间的不同,使 ...

  5. Hibernate(3)——实例总结Hibernate对象的状态和ThreadLoacl封闭的session

    俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及的知识点总结如下: Hibernate的内部执行过程(CRUD) 对象的状态及其转换图和例子 使用JUnit测试 使用getCur ...

  6. hibernate对象的三种状态

    对于hibernate,我想不在这里讲解了,我们就直接进入主题 在这里我将要说的是"hibernate对象的三种状态",对象是我们十分熟悉的,对吧!而对于对象它有三种状态 分别是瞬 ...

  7. hibernate 对象三态(瞬态、持久态、脱管态)之我见

    刚开始学习hibernate时,对其对象的三种状态理解的模模糊糊,一直停留在一知半解的状态,前两天又回顾了一下,顿时醒悟,原来三种状态理解起来是很容易的. 先看一下对Hibernate对象状态的解释: ...

  8. 菜鸟学SSH(八)——Hibernate对象的三种状态

    前面写了几篇关于SSH的博客,但不是Struts就是Spring,Hibernate还从来没写过呢.说好是SSH的,怎么可以光写那两个,而不写Hibernate呢对吧.今天就先说说Hibernate对 ...

  9. hibernate对象的三种状态及转换

    一.hibernate对象三种状态 Transient(瞬时状态):没有session管理,同时数据库没有对应记录 举例:new 出来的对象还没有被session管理,此时该对象处于Transient ...

随机推荐

  1. Python学习之路day4-列表生成式、生成器、Iterable和Iterator

    一.列表生成式 顾名思义,列表生成式就是用于生成列表的特殊语法形式的表达式. 1.1 语法格式 [exp for iter_var in iterable] 工作过程: 1.通过iter_var迭代i ...

  2. application.yml配置log日志

    #日志文件的配置logging: pattern: console: "%d - %msg%n" file: /var/log/sell.log 注解@Slf4j

  3. Java web应用开发技术

    Java web应用程序供用户通过浏览器发送请求,程序通过执行产生web页面,并将页面传递给客户机器上的浏览器,将得到的web页面呈现给用户. 一个完整的Java web应用程序通常由许多组件构成的, ...

  4. Django 基础 模板系统

    Django模板系统 官方文档 常用语法 只需要记两种特殊符号: {% %} 'b', 'c', 'd']的话,就显示4. filesizeformat 将值格式化为一个 “人类可读的” 文件尺寸 ( ...

  5. Git_学习_09_指定某些文件不上传

    一.前言 在git提交文件到远程分支时,可能有些文件我们并不想上传. 这时可以使用如下命令来将这些文件从暂存区移除 git rm --cached "文件路径" 注:git add ...

  6. 201621123014《Java程序设计》第十一周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多线程 1. 源代码阅读:多线程程序BounceThread 1.1 BallR ...

  7. InnoDB参数详解

    1.查询5.5版本的InnoDB参数并注释:[root@localhost etc]# grep -i innodb my.cnf; t_innodb; otherwise, slaves may d ...

  8. 机器学习敲门砖:任何人都能看懂的TensorFlow介绍

    机器学习敲门砖:任何人都能看懂的TensorFlow介绍 http://www.jiqizhixin.com/article/1440

  9. python数据类型,int,str,bool

    一,python中的int() int在python中主要用来运算,对字符串的转化,用int(str)表示,并且需要str.isdigit为真. 在int()中二进制的转换如下: #bit_lengt ...

  10. SQL Sever 学习系列之三

    SQL Sever 学习系列之三 SQL Server 学习系列之一(薪酬方案+基础) SQL Server 学习系列之二(日期格式问题)         五.经理今天刚谈到with的用法(with的 ...