- 浏览: 899964 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (537)
- Java SE (114)
- Struts (18)
- Hibernate (25)
- Spring (3)
- Page_Tech (41)
- Others (87)
- Database (29)
- Server (24)
- OpenSource_Tools (15)
- IDE_Tool (22)
- Algorithm (28)
- Interview (22)
- Test (28)
- Hardware (1)
- Mainframe (25)
- Web application (4)
- Linux (3)
- PHP (17)
- Android (1)
- Perl (6)
- ubuntu (1)
- Java EE (9)
- Web Analysis (5)
- Node.js (2)
- javascript (2)
最新评论
-
一键注册:
request.getRequestURL()和request.getRequestURI() -
SuperCustomer:
...
SED的暂存空间和模式空间 -
juyo_ch:
讲得挺好理解的,学习了
java 死锁及解决 -
chinaalex:
最后一题答案正确,但是分析有误.按照如下过程,上一行为瓶,下一 ...
zz智力题 -
liaowuxukong:
多谢博主啦,弱弱的了解了一点。
C++/Java 实现多态的方法(C++)
(2)session.merge ()方法
该方法将修改表中记录,其所需要的实体状态为脱管状态,但是注意,它并不影响调用方法前后的状态,也即该实体依然是脱管状,见例6.4。
例6.4:session.merge ()方法对状态的变化
public void run() {
//创建UserInfo实例
UserInfo userInfo = new UserInfo();
//使之成为脱管状态
userInfo.setId(11112);
userInfo.setName("RW3");
userInfo.setSex("M");
//创建UserInfo实例
UserInfo userInfo2 = new UserInfo();
//使之成为脱管状态
userInfo2.setId(11112);
userInfo2.setName("RW4");
userInfo2.setSex("F");
//启动Session
Session session = HibernateSessionFactory.currentSession();
//启动事务
Transaction tx = session.beginTransaction();
//调用merge方法,此时UserInfo实体状态并没有被持久化
session.merge(userInfo);
//调用merge方法,此时UserInfo实体状态并没有被持久化
//但是数据库中的记录被更新了
①session.merge(userInfo2);
//merge方法与update方法的差别在于针对同样的操作update方法会报错
//原因在于update方法使得实体状态成为了持久化状态,而Session中不允许两个持久化实体有同样的持久化标识
②//session.update(userInfo);
//session.update(userInfo2);
//以下两句不会发送SQL,因为userInfo2不是持久化状态的实体
③userInfo2.setName("RW5");
userInfo2.setSex("M");
//提交事务
tx.commit();
//关闭Hibernate Session
HibernateSessionFactory.closeSession();
}
针对该段代码将执行如下SQL语句:
Hibernate:
/* ①session.merge(userInfo2)的动作 */
select
userinfo0_.id as id0_0_,
userinfo0_.NAME as NAME0_0_,
userinfo0_.SEX as SEX0_0_,
userinfo0_.roomid as roomid0_0_
from
userinfo userinfo0_
where
userinfo0_.id=?
Hibernate:
/* ①session.merge(userInfo2)的动作 */
update
userinfo
set
NAME=?,
SEX=?,
roomid=?
where
id=?
session.merge()方法会首先发送一句select语句,去数据库端获取UserInfo持久化标识所对应的表记录;然后自动生成一个持久化状态的UserInfo实体,与脱管状态的UserInfo实体做比较是否有所改变;一旦发生了改变,才会发送update语句执行更新。而按执行顺序,若两句session.merge()方法针对同一个脱管状态的UserInfo实体,那其结果只会执行最后一个session.merge()方法所发出的update语句。即使执行了session.merge()方法,UserInfo实体依然是脱管状态,因此③userInfo2. setName("RW5")的语句不会同步数据库中的表。
(3)session.lock()方法
他为了解决事务处理而使用,它会将实体从脱管状态转变为持久化状态。但是值得注意的是,调用session.lock()方法后,脱管状态的实体信息不会同步到数据库,而是会从数据库中返回该持久化状态。即使在脱管状态对实体属性进行了修改,一旦调用了session.lock()方法,这种修改就成了无效,见例6.5。
例6.5:session.lock()方法对状态的变化
public void run() {
//创建UserInfo实例
UserInfo userInfo = new UserInfo();
//使之成为脱管状态
userInfo.setId(11112);
userInfo.setName("RW3");
userInfo.setSex("M");
//启动Session
Session session = HibernateSessionFactory.currentSession();
//启动事务
Transaction tx = session.beginTransaction();
//发送select获取数据库中的当前记录(执行的SQL根据LockMode不同有不同的方式)
//UserInfo实体将从脱管状态转变为持久化状态
①session.lock(userInfo,LockMode.UPGRADE_NOWAIT);
//对当前UserInfo实体进行更新将同步数据库中的记录
②userInfo.setName("RW8");
//提交事务
tx.commit();
//关闭Hibernate Session
HibernateSessionFactory.closeSession();
}
针对该段代码将执行如下SQL语句:
Hibernate:
/* ①session.lock(userInfo,LockMode.UPGRADE_NOWAIT)的动作 */
select
id
from
userinfo
where
id =? for update
nowait
Hibernate:
/*②userInfo.setName("RW8")的动作 */
update
userinfo
set
NAME=?,
SEX=?,
roomid=?
where
id=?
session.lock()方法并不是为了将脱管状态的对象转变为持久化状态,而是为了事务处理。
(4)session.saveOrUpdate()方法
它是Hibernate提供的既可以新增也可以更新的方法,该方法使实体状态从脱管或瞬时直接变成持久化。session.saveOrUpdate()方法对实体的持久化标识非常敏感。当实体持久化标识存在,就会发送update SQL,当持久化标识不存在,就会发送insert SQL,见例6.6。
例6.6:session.saveOrUpdate()方法对状态的变化
public void run() {
//创建UserInfo实例
UserInfo userInfo = new UserInfo();
//使之成为脱管状态
userInfo.setId(11112);
userInfo.setName("RW3");
userInfo.setSex("M");
//创建UserInfo实例,其为瞬时状态
UserInfo userInfo2 = new UserInfo();
userInfo2.setName("RW3");
userInfo2.setSex("M");
//启动Session
Session session = HibernateSessionFactory.currentSession();
//启动事务
Transaction tx = session.beginTransaction();
//UserInfo存在持久化标识,因此为新增,从瞬时状态成为持久化状态
①session.saveOrUpdate(userInfo2);
//同步数据库表记录
②userInfo2.setName("RW9");
//UserInfo存在持久化标识,因此为修改,从脱管状态成为持久化状态
③session.saveOrUpdate(userInfo);
//同步数据库表记录
④userInfo.setName("RW10");
//提交事务
tx.commit();
//关闭Hibernate Session
HibernateSessionFactory.closeSession();
}
针对该段代码将执行如下SQL语句:
Hibernate:
/* ①session.saveOrUpdate(userInfo2)的动作 */
insert
into
userinfo
(NAME, SEX, roomid, id)
values
(?, ?, ?, ?)
Hibernate:
/* ②session.saveOrUpdate(userInfo)的动作 */
update
userinfo
set
NAME=?,
SEX=?,
roomid=?
where
id=?
Hibernate:
/* ③session.saveOrUpdate(userInfo)的动作 */
update
userinfo
set
NAME=?,
SEX=?,
roomid=?
where
id=?
根据代码的执行,对同一持久化UserInfo属性需要改变多次,那只会以最后的属性为准,因此③session.saveOrUpdate(userInfo)和④userInfo.setName("RW10")虽然从理论上需要发送两句update SQL到数据库,但其实只会产生一句。
(5)session.createQuery()方法
它为HQL语句调用,HQL(HibernateQusery Language)是Hibernate框架自定义的一种面向对象的语言,类似SQL语言,用以与数据库进行交互。Hibernate将HQL解析成SQL语句与数据库交互。HQL被执行后,其所关系到的实体对象将从瞬时状态转变为脱管状态,见例6.7。
例6.7:session.createQuery()方法对状态的变化
//一个内部类,作为SQL查询的参数传递
class RoomDTO {
Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
public void run() {
// 创建一个JavaBean作为参数传递
RoomDTO roomDTO = new RoomDTO();
//设置id属性的值
roomDTO.setId(1L);
// 启动Session
Session session = HibernateSessionFactory.currentSession();
// 启动事务
Transaction tx = session.beginTransaction();
//session.createQuery方法作为HQL查询的执行
//其中setProperties方法作为":id"的参数传递,要求roomDTO实例中必须包含id
//属性和getId、setId方法
//由于SQL中包含有3个实体:room、room.id、userinfo,因此返回的结果将是对象数组
①Iterator i = session
.createQuery(
"select room, room.id, userinfo from Room room, UserInfo userinfo where room.id = userinfo.room.id and room.id = :id")
.setProperties(roomDTO).iterate();
//通过迭代将3个实体对象转型,得到最终结果
//其中Room实体和UserInfo实体对应的实体状态为脱管,roomid则为一个Long类型
while (i.hasNext()) {
//获取对象数组转型
Object[] object = (Object[]) i.next();
//获取脱管状态的Room实体
②Room roomr = (Room) object[0];
System.out.println(roomr.getName());
System.out.println(roomr.getRoomnumber());
//获取roomid
③Long roomid = (Long) object[1];
System.out.println(roomid);
//获取脱管状态的UserInfo实体
④UserInfo userinfor = (UserInfo) object[2];
System.out.println(userinfor.getName());
System.out.println(userinfor.getSex());
}
// 提交事务
tx.commit();
// 关闭Hibernate Session
HibernateSessionFactory.closeSession();
}
针对该段代码将执行如下SQL语句:
Hibernate:
/* 执行
①select
room,
room.id,
userinfo
from
Room room,
UserInfo userinfo
where
room.id = userinfo.room.id
and room.id = :id
的HQL语句 */
select
room0_.id as col_0_0_,
room0_.id as col_1_0_,
userinfo1_.id as col_2_0_
from
room room0_,
userinfo userinfo1_
where
room0_.id=userinfo1_.roomid
and room0_.id=?
Hibernate:
/* ②Room roomr = (Room) object[0]的动作(数据库中有一条记录,取第一条) */
select
room0_.id as id1_0_,
room0_.NAME as NAME1_0_,
room0_.roomnumber as roomnumber1_0_
from
room room0_
where
room0_.id=?
Hibernate:
/* ④UserInfo userinfor = (UserInfo) object[2]的动作(数据库中有两条记录,取第一条) */
select
userinfo0_.id as id0_0_,
userinfo0_.NAME as NAME0_0_,
userinfo0_.SEX as SEX0_0_,
userinfo0_.roomid as roomid0_0_
from
userinfo userinfo0_
where
userinfo0_.id=?
Hibernate:
/* ④UserInfo userinfor=(UserInfo)object[2]的动作(数据库中有两条记录,取第二条)*/
select
userinfo0_.id as id0_0_,
userinfo0_.NAME as NAME0_0_,
userinfo0_.SEX as SEX0_0_,
userinfo0_.roomid as roomid0_0_
from
userinfo userinfo0_
where
userinfo0_.id=?
可以看到,Hibernate在执行这段代码的HQL时,并不会一次性把所有的room表和userinfo表的字段都捞取出来,而是先获取其主键。在之后真正要使用这两个表所对应的实体对象(Room和UserInfo)时,才会调用select语句去获取其所有字段,这是“延时求值”的机制在起作用。session.createQuery()方法不会使实体成为持久化状态,因此对Room和UserInfo的实体属性进行改变不会同步数据库。
调用createQuery()方法执行HQL时,有多种方式可以传递参数,本例提供了一种常见的方式——setProperties()。
说明 除了createQuery()方法外,Hibernate还提供了外置命名查询(getNameQuery()方法)、结果集过滤(createFilter()方法)、条件查询(createCriteria()方法)、原生SQL查询(createSQLQuery()方法)来实现抓取数据。
6.1.6 结语
在本小节中,将对Hibernate中的持久化方法做一个总结,也作为本问题的结语。
(1)瞬时—脱管状态的方法有以下几种。
· 直接将实体的持久化标识进行改变。
· 调用session.createQuery()方法。
· 调用session.getNameQuery()方法。
· 调用session.createFilter()方法。
· 调用session.createCriteria()方法。
· 调用session.createSQLQuery()方法。
(2)瞬时—持久化状态的方法有以下几种。
· 调用session.save()方法。
· 调用session.saveOrUpdate()方法。
(3)脱管—持久化状态的方法有以下几种。
· 调用session.load()方法。
· 调用session.lock()方法。
· 调用session.update()方法。
· 调用session.saveOrUpdate()方法。
(4)脱管—瞬时状态的方法有以下几种。
· 直接将实体的持久化标识清除。
· 调用session.delete()方法。
(5)持久化—脱管状态的方法:关闭Hibernate Session。
(6)持久化—瞬时状态的方法。调用session.delete()方法。
(7)脱管状态-脱管状态但影响数据库记录的方法:调用session.merger()方法。
发表评论
-
hibernate n+1问题
2010-10-21 11:05 899Hibernate中常会用到set,bag等集合表示1对多的关 ... -
Hibernate 关联关系 总结
2010-09-09 15:27 9381.一对多的单向关联关系 配置单向的一对多关系是 ... -
Hibernate 关联
2010-09-09 15:24 9651、hibernate多对一关联映 ... -
Hibernate一对多(单向)
2010-09-09 14:31 570[正文]: Hibernate一对多关联,例如一个用户有 ... -
Hibernate中No row with the given identifier exists问题的原因及解决
2010-06-23 09:54 910产生此问题的原因: ... -
Hibernate使用count(*)取得表中记录总数(跨Hibernate3.x版本问题)
2010-06-22 17:13 1506Java代码 /** * @T ... -
hibernate继承关系映射
2010-06-13 16:58 888hbn 的继承映射关系有这 ... -
Hibernate集合映射
2010-06-13 12:49 892准备找工作,重新整理一下Hibernate,今天做了集合映射 ... -
高并发网站的架构
2010-05-07 11:07 697我在CERNET做过拨号接入平台的搭建,而后在Yaho ... -
Hibernate事务和并发控制
2010-05-07 10:21 8881. 事务介绍:1.1. 事务的定义:事务就 ... -
hibernate中lazy的使用
2009-12-18 22:00 754lazy,延迟加载 Lazy的 ... -
Hibernate中代码自动生成功能小结
2009-12-06 15:10 1005Hibernate中需要class和mapping file, ... -
hibernate工具箱—根据映射文件自动建表
2009-12-04 12:08 960public class ExportDB { ... -
关联加载对象时的报错-----a different object with the same identifier value
2009-11-18 16:13 852因为在hibernate中同一个session里面有了两个相同 ... -
update/saveOrUpdate/merge
2009-11-18 15:28 1124通常下面的场景会使用update()或saveOrUpdate ... -
写得很不错的-Hibernate中的实体状态(一)
2009-11-18 15:04 1122持久层的解决方案有许 ... -
Hibernate3.x总结
2009-11-18 14:29 729Hibernate不是盏省油的灯 ... -
Hibernate Annotation几种关联映射
2009-11-02 17:01 1054Hibernate Annotation几种关联映射 一对一 ... -
hibernate3的注解映射学习
2009-11-02 16:41 1322注解映射必须满足两大条件:Hibernate3.2以上版本和J ... -
Hibernate 中级联操作 cascade 选项
2009-11-02 16:35 908none :在保存、更新或删除对象时,忽略其他关联的对象。他是 ...
相关推荐
Hibernate 实体状态 瞬态(transient) 持久化(persistent) 脱管(detached) 转换
10.1. Hibernate对象状态(object states) 10.2. 使对象持久化 10.3. 装载对象 10.4. 查询 10.4.1. 执行查询 10.4.2. 过滤集合 10.4.3. 条件查询(Criteria queries) 10.4.4. 使用原生SQL的查询 10.5. 修改...
HIBERNATE - 符合Java习惯的关系数据库持久化 Hibernate参考文档 3.2 -------------------------------------------------------------------------------- 目录 前言 1. 翻译说明 2. 版权声明 1. Hibernate...
hibernate概述,hibernate入门Demo,hibernate配置文件详解(全局配置,实体类映射配置),配置实体规则,核心API详解(Configuration,sessionFactory,session,Transaction),hibernate中的对象状态以及刷新能缓存机制 ...
虽然持久化实体的状态在ORM中是一个老生常谈的问题,但是说实在的,我们在开发过程中真的不太在意实体的状态。在Web一般情况下也都是交给Spring去管理实体管理器(EntityManager),所以我们还是有必要啰嗦一下,...
10.1. Hibernate对象状态(object states) 10.2. 使对象持久化 10.3. 装载对象 10.4. 查询 10.4.1. 执行查询 10.4.2. 过滤集合 10.4.3. 条件查询(Criteria queries) 10.4.4. 使用原生SQL的查询 10.5. 修改...
HIBERNATE - 符合Java习惯的关系数据库持久化 Hibernate参考文档 3.2 -------------------------------------------------------------------------------- 目录 前言 1. 翻译说明 2. 版权声明 1. Hibernate...
10.1. Hibernate对象状态(object states) 10.2. 使对象持久化 10.3. 装载对象 10.4. 查询 10.4.1. 执行查询 10.4.1.1. 迭代式获取结果(Iterating results) 10.4.1.2. 返回元组(tuples)的查询 10.4.1.3. 标量(Scalar)...
8.3 Java对象在Hibernate持久化层的状态 8.3.1 临时对象的特征 8.3.2 持久化对象的特征 8.3.3 被删除对象的特征 8.3.4 游离对象的特征 8.4 Session接口的详细用法 8.4.1 Session的save()和persist()...
05_传智播客hibernate教程_实体对象的三种状态与saveOrUpdate方法
hibernate实体有三个状态 1、瞬时状态 对象由new操作符创建,尚未与Session关联的对象被认为处于瞬态.瞬态对象不会持久化到数据库中,也不会被赋予持久化标识.而这个时候只在内存中存在,与数据库无关 2、持久状态 ...
第一部分 从Hibernate和EJB 3.0开始 第1章 理解对象/关系持久化 1.1 什么是持久化 1.1.1 关系数据库 1.1.2 理解SQL 1.1.3 在Java中使用SQL 1.1.4 面向对象应用程序中的持久化 1.2 范式不...
Alura-Java和JPA课程:使用JPA2和Hibernate持久化对象 这是我在课程之后开发的代码。 我已经对原始版本进行了一些更改。 内容 JPA和Hibernate简介 使用数据库 面向对象范式 在Java代码中避免使用SQL JDBC和SQL维护...
通过Hibernate ORM会话修改的实体进行,以始终使索引保持最新状态。 ,可轻松构建全文本搜索查询并以Hibernate ORM实体的形式检索匹配。 以及更多: Search DSL中的许多不同和, 。 搜索查询返回的是而不是实体,...
05_实体对象的三种状态与saveOrUpdate方法 06_完善HibernateUtil类及hql查询入门 07_实体类或属性名与数据库关键字冲突问题 10_使用Hibernate完成CRUD实验的步骤说明 11_完成CRUD实验并回顾和补充细节知识(上)...
本章站在持久化层的角度,Java对象在生命周期中可处于临时状态、持久化状态、删除状态和游离状态。处于持久化状态的Java对象位于一个Session实例的缓存中,Session能根据这个对象的属性变化来同步更新数据库。 8.1 ...
HIBERNATE - 符合Java习惯的关系数据库持久化 Hibernate参考文档 3.2 -------------------------------------------------------------------------------- 目录 前言 1. 翻译说明 2. 版权声明 1. Hibernate...
1. 在Tomcat中快速上手 1.1. 开始Hibernate之旅 1.2. 第一个持久化类 1.3. 映射cat 1.4. 与Cat同乐 1.5. 结语 2. 架构(Architecture) 2.1. 概况(Overview) 2.2. 实例状态 2.3. JMX整合 2.4. 对JCA的支持 3. 配置 ...
上述实体映射到数据库中的时候对应 Order 实体Bean, 其具有 id, lastUpdate, lastUpdater 三个属性。如果没有@MappedSuperclass 注解,则父类中属性忽略,这是 Order 实体 Bean 只有 id 一个属性。 映射实体Bean的...
1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...