Hibernate对象的CRUD操作

1.  Hibernate对象的CRUD操作

1.1.  对象的三种状态

瞬时(Transient) - 由new操作符创建,且尚未与HibernateSession 关联的对象被认定为瞬时(Transient)的。瞬时(Transient)对象不会被持久化到数据库中,也不会被赋予持久化标识(identifier)。如果瞬时(Transient)对象在程序中没有被引用,它会被垃圾回收器(garbage collector)销毁。使用Hibernate Session可以将其变为持久(Persistent)状态。(Hibernate会自动执行必要的SQL语句)

持久(Persistent) - 持久(Persistent)的实例在数据库中有对应的记录,并拥有一个持久化标识(identifier)。持久(Persistent)的实例可能是刚被保存的,或刚被加载的,无论哪一种,按定义,它存在于相关联的Session作用范围内。 Hibernate会检测到处于持久(Persistent)状态的对象的任何改动,在当前操作单元(unit of work)执行完毕时将对象数据(state)与数据库同步(synchronize)。开发者不需要手动执行UPDATE。将对象从持久(Persistent)状态变成瞬时(Transient)状态同样也不需要手动执行DELETE语句。

脱管(Detached) – 与持久(Persistent)对象关联的Session被关闭后,对象就变为脱管(Detached)的。 对脱管(Detached)对象的引用依然有效,对象可继续被修改。脱管(Detached)对象如果重新关联到某个新的Session上,会再次转变为持久(Persistent)的(在Detached其间的改动将被持久化到数据库)。这个功能使得一种编程模型,即中间会给用户思考时间(user think-time)的长时间运行的操作单元(unit of work)的编程模型成为可能。我们称之为应用程序事务,即从用户观点看是一个操作单元(unit
of work)。


// 读取配置文件,得到Configuration对象

Configuration config =
new
Configuration().configure();

// 获得会话工厂

SessionFactory sf =
config.buildSessionFactory();

Session session =
sf.openSession();

sf.getCurrentSession();

// session.

Transaction tx =
null
;

try {

// 开始事务

tx =
session.beginTransaction();

UserModel userModel =
new UserModel("003",
"morris", 22);

// 此时userModel为瞬时态

// 保存对象

session.save(userModel);

// 此时userModel持久态

// 提交事务

tx.commit();

} catch (Exception
e) {

e.printStackTrace();

if (tx !=
null) {

tx.rollback();

}

} finally {

session.close();

}

// 此时userModel脱管态

1.2.  增加持久对象

?  persist() 使一个临时实例持久化。然而,它不保证立即把标识符值分配给持久性实例,这会发生在flush的时候。persist() 也保证它在事务边界外调用时不会执行 INSERT 语句。这对于长期运行的带有扩展会话/持久化上下文的会话是很有用的。

?  save() 保证返回一个标识符。如果需要运行 INSERT 来获取标识符(如 "identity" 而非"sequence" 生成器),这个 INSERT 将立即执行,不管你是否在事务内部还是外部。这对于长期运行的带有扩展会话/持久化上下文的会话来说会出现问题。

1.3.  删除持久对象

?  delete() 用来删除一个对象,参数为一个对象,并不是一个主键,执行delete方法的时候首先会去数据库中查找有有没有对象的主键所对应的记录,如果有就会执行删除操作;

如果没有,不会报错。


Hibernate: select usermodel_.userId, usermodel_.userName as userName2_0_, usermodel_.userAge as userAge3_0_ from userInfo usermodel_ where usermodel_.userId=?

Hibernate: delete from userInfo where userId=?

1.4.  修改持久对象

?  update


Hibernate: update userInfo set userName=?, userAge=? where userId=?

?  merger

l  如果数据库中的数据与对象的数据一致,执行下面的sql语句


Hibernate: select usermodel0_.userId as userId1_0_0_, usermodel0_.userName as userName2_0_0_, usermodel0_.userAge as userAge3_0_0_ from userInfo usermodel0_ where usermodel0_.userId=?

l  如果数据库的数据与对象的数据不一致,就会执行下面的sql语句


Hibernate: select usermodel0_.userId as userId1_0_0_, usermodel0_.userName as userName2_0_0_, usermodel0_.userAge as userAge3_0_0_ from userInfo usermodel0_ where usermodel0_.userId=?

Hibernate: update userInfo set userName=?, userAge=? where userId=?

l  如果数据库中不存在这条记录,则添加


Hibernate: select usermodel0_.userId as userId1_0_0_, usermodel0_.userName as userName2_0_0_, usermodel0_.userAge as userAge3_0_0_ from userInfo usermodel0_ where usermodel0_.userId=?

Hibernate: insert into userInfo (userName, userAge, userId) values (?, ?, ?)

1)        如果session中存在相同持久化标识的实例,用用户给出的对象的状态覆盖旧有的持久实例

2)        如果session中没有相应的持久实例,则尝试从数据库中加载,或创建新的持久化实例

3)        最后返回该持久实例

4)        用户给出的这个对象没有被关联到 session 上,它依旧是脱管的

?  saveOrUpdate 自动检测,如果是新的记录就添加,如果是修改记录,就修改

1)        如果对象已经在本session中持久化了,不做任何事

2)        如果另一个与本session关联的对象拥有相同的持久化标识,抛出一个异常

3)        如果对象没有持久化标识属性,对其调用save()

4)        如果对象的持久标识表明其是一个新实例化的对象,对其调用save()。

1.4.1.  update和merge方法的区别

1)        如果数据库里面存在你要修改的记录,update每次是直接执行修改语句;而merge是先在缓存中查找,缓存中没有相应数据,就到数据库去查询,然后再合并数据,如果数据是一样的,那么merge方法不会去做修改,如果数据有不一样的地方,merge才真正修改数据库。

2)        如果数据库中不存在你要修改的记录,update是报错;而merge方法是当作一条新增的值,向数据库中新增一条数据。

3)        update后,传入的TO对象就是PO的了,而merge还是TO的。

4)        如果你确定当前session没有包含与之具有相同持久化标识的持久实例,使用update()。如果想随时合并改动而不考虑session的状态,使用 merge()。换句话说,在一个新 session中通常第一个调用的是update()方法,以保证重新关联脱管对象的操作首先被执行。

5)        请注意:使用update来把一个TO变成PO,那么不管是否修改了对象,都是要执行update sql语句的。

1.4.2.  使用update() 或saveOrUpdate()的场景

1)        程序在第一个 session 中加载对象

2)        该对象被传递到表现层

3)        对象发生了一些改动

4)        该对象被返回到业务逻辑层

5)        程序调用第二个session的update()方法持久这些改动

1.5.  按主键查询持久对象

1)        load方法:load的时候首先查询一级缓存,没有就创建并返回一个代理对象,等到使用的时候,才查二级缓存,如果二级缓存中没有数据就查数据库,如果数据库中没有,就抛例外

2)        get方法:先查缓存,如果缓存中没有这条具体的数据,就查数据库,如果数据库没有值,就返回null,总之get方法不管用不用,都要拿到真实的数据

1.5.1.  get和load的区别

1)        get()方法直接返回实体类,如果查不到数据则返回null。load()会返回一个实体代理对象(当前这个对象可以自动转化为实体对象),但当代理对象被调用时,如果没有数据不存在,就会抛出个org.hibernate.ObjectNotFoundException异常

2)        load先到缓存(session缓存/二级缓存)中去查,如果没有则返回一个代理对象(不马上到DB中去找),等后面使用这个代理对象操作的时候,才到DB中查询,这就是我们常说的 load在默认情况下支持延迟加载(lazy)

3. get先到缓存(session缓存/二级缓存)中去查,如果没有就到DB中去查(即马上发出sql)。总之,如果你确定DB中有这个对象就用load(),不确定就用get()(这样效率高)

时间: 11-06

Hibernate对象的CRUD操作的相关文章

用dbutils和hibernate分别实现CRUD操作

=====================用dbutils实现CRUD操作======================== 1.bean: Teacher.java package beans; public class Teacher { String id; String tname; String tage; //setter.getter @Override public String toString() { return "Teacher [id=" + id + &quo

Spring+Jersey+JPA+Hibernate+MySQL实现CRUD操作案例

本文承接我的另一篇博文:Spring+Jersey+Hibernate+MySQL+HTML实现用户信息增删改查案例(附Jersey单元测试),主要更改内容如下: Spring配置文件applicationContext中原先使用的是Hibernate,现在改为Hibernate对JPA的支持: 增加了C3P0连接池: 修改了Dao操作实现,改为Spring接管的JPA实现. 如果读者想详细查看Spring整合Jersey与前端交互可以点击上述连接.本文主要介绍以上三处修改内容,并且使用Jers

hibernate入门(1) - CRUD操作

第一步:hibernate的配置文件 hibernate.cfg.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate

Hibernate中的CRUD操作

1.添加数据操作 插入数据使用session对象的save()方法完成.   插入代码: @Test public void Test1(){ SessionFactory sessionFactory = HibernateUtils.getFactory(); Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction(); UserEntity user = new Us

Hibernate对象持久化框架

JDBC:(Java Data Base Connectivity)java数据库连接 java.sql包提供JDBC API,可通过它编写訪问数据库的程序代码.当中经常使用的接口和类包含以下内容: DriverManager:驱动程序管理器,负责创建数据库连接 Connection:代表数据库连接 Statement:负责运行SQL语句 PreparedStatement:负责运行SQL语句,具有提前定义SQL语句的功能 ResultSet:代表SQL查询语句的查询结果集 Hibernate(

javascript对象定义和操作

//js对象定义有三种方式//js方法定义有三种方式 function fn(){} var fun = function(){} var fun = new function() {} //******** *********************************//<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <titl

Spring MVC + Hibernate + Maven: Crud操作示例

Alexey是一个在使用Java,TestNG 和Selenium的自动化WEB应用程序中有丰富经验的测试开发者.他如此的喜欢QA以至于在下班后他为初级QA工程师提供培训课程. 在这篇文章中我想介绍一个Spring MVC + Hibernate + Maven例子.这组技术主要涉及一些基础知识,我想在每一个必要的地方详细解释它.本篇话题范围以外的更多资源,我会提供链接方便你阅读.在文章的最后,我将发布一个GitHub的链接. 目标 示例web应用程序是基于Spring MVC, Hiberna

hibernate的CRUD操作

本文简单总结一下hibernate的具有映射关系CRUD操作,主要使用到了cascade和fetch,其中cascade针对的是CUD操作,表示级联关系,fetch针对的是R操作,表示级联加载方式. 1.先看下javaEE的API中关于cascade的描述 javax.persistence Enum CascadeType java.lang.Object java.lang.Enum<CascadeType> javax.persistence.CascadeType All Implem

Hibernate系列(五):利用Hibernate完成简单的CRUD操作

这里利用Hibernate操作数据库完成简单的CRUD操作. 首先,我们需要先写一个javabean: package cn.itcast.domain; import java.util.Date; public class User { private int id; private String name; private Date birthday; public int getId() { return id; } public void setId(int id) { this.id