持久化对象的声明周期
1、Hibernate管理的持久化对象(PO persistence object )的生命周期有四种状态,分别是transient、persistent、detached和removed,如图所示:
- 瞬时状态:new出来的对象仅仅存在虚拟机的内存中,虚拟机关闭数据丢失
- 持久化状态:通过save方法保存到数据库中,即使虚拟机关闭也可以中数据库中读取到想要的数据。通过get load find从数据库加载到数据并没有抛出异常,就立即进入持久化状态,并不是非要提交事务才进入持久化状态,执行完save操作就已经是持久化状态了
- 游离态:把session关闭或者将对象驱除或者清除了就是游离的状态
- 移除状态:通过delete方法之后,数据库中没有数据了,但数据加载到了jvm所管理内存中,对象对应的内存中是有数据的,类似于瞬时状态
2、测试案例
创建表sql
--MysqlDROP TABLE IF EXISTS t_customer ;CREATE TABLE t_customer ( id INT(5) PRIMARY KEY , email VARCHAR(60) UNIQUE NOT NULL, password VARCHAR(32) NOT NULL , nickname VARCHAR(150) , gender VARCHAR(3) , birthdate DATE , married CHAR(1));--OracleCREATE TABLE t_customer ( id NUMBER(5) PRIMARY KEY , email VARCHAR2(60) UNIQUE NOT NULL, password VARCHAR2(32) NOT NULL , nickname VARCHAR2(150) , gender VARCHAR2(3) , birthdate DATE , married CHAR(1));
持久化对象类
package ecut.session.entity;import java.util.Date;/** * 实体类 Customer <================> 数据库表: t_customer * 属性 <================> 列 * id <================> id * emial <================> email * password <================> password * nickname <================> nickname * gender <================> gender * birthdate <================> birthdate * married <================> married * * new Customer(); <==========> 一条记录 (关系) * */public class Customer { // 对象标识符 ( Object Identifier ) 属性 ( 对应数据库主键 ) 使用包装类型,才会有null值,才可以执行saveOrUpdate private Integer id; // 属性的值 被称作 对象标识符 private String email; private String password; private String nickname; private char gender; private Date birthdate; private boolean married; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getNickname() { return nickname; } public void setNickname(String nickname) { this.nickname = nickname; } public char getGender() { return gender; } public void setGender(char gender) { this.gender = gender; } public Date getBirthdate() { return birthdate; } public void setBirthdate(Date birthdate) { this.birthdate = birthdate; } public boolean isMarried() { return married; } public void setMarried(boolean married) { this.married = married; }}
映射文件
hibernate配置文件
com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF8 root 123456 1 false org.hibernate.dialect.MySQLDialect true true
配置文件中的核心配置说明
java.sql.Connection 中定义的事务隔离级别:
- public static final int TRANSACTION_NONE : 0
- public static final int TRANSACTION_READ_UNCOMMITTED : 1
- public static final int TRANSACTION_READ_COMMITTED : 2
- public static final int TRANSACTION_REPEATABLE_READ : 4
- public static final int TRANSACTION_SERIALIZABLE : 8
测试类:
package ecut.session.test;import java.util.Calendar;import java.util.Date;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;import org.junit.After;import org.junit.Before;import org.junit.Test;import ecut.session.entity.Customer;public class TestLifecycle { private SessionFactory factory ; private Session session ; public @Before void init() { // 创建一个 Configuration 对象,用来读取配置文件 ( 默认位置、默认名称 ) Configuration config = new Configuration(); // 读取配置文件 config.configure("ecut/session/hibernate.cfg.xml"); //config.configure(); // 读取 默认位置 ( 当前 classpath ) 的 默认名称 ( hibernate.cfg.xml ) 的配置文件 // 使用 Configuration 创建 SessionFactory factory = config.buildSessionFactory(); // 创建 Session 对象 ( 这里的 Session 是 Java 程序 跟 数据库 之间的 会话 ) session = factory.openSession(); } public @Test void state() throws InterruptedException { Calendar calendar = Calendar.getInstance(); Customer c = new Customer(); // Transient ( 瞬时状态 ) c.setEmail( "zhangsanfeng@wudang.com" ); c.setPassword( "hello2017" ); calendar.set( 1345 , 5 , 10 ); Date birthdate = calendar.getTime() ; c.setBirthdate( birthdate ); c.setGender( '男' ); c.setNickname( "张三丰" ); c.setMarried( false ); System.out.println( session.contains( c ) ); // false Transaction tran = session.beginTransaction(); // session.getTransaction().begin(); session.save( c ); // Persistent ( 持久化状态 ) System.out.println( "~~~1~~~~~~~~~~~~~~~~~~" ); session.flush(); // 将当前尚未执行的 SQL 语句立即执行 System.out.println( "~~~2~~~~~~~~~~~~~~~~~~" ); Thread.sleep( 1 ); System.out.println( "~~~3~~~~~~~~~~~~~~~~~~" ); tran.commit(); // 提交事务 ( 如果还有没有执行的 SQL 语句就执行它们 ) System.out.println( session.contains( c ) ); // true session.evict( c ); // Detached ( 游离状态 ) System.out.println( session.contains( c ) ); // false,是否被session所管理,session中已经没有这个数据了 System.out.println( c.getEmail() );//虚拟机中依然有数据 } public @Test void removed() { Customer c = session.get( Customer.class , 4 ); // 持久化状态 if( c != null ) { System.out.println( session.contains( c ) ); System.out.println( c.getEmail() ); Transaction tran = session.getTransaction(); tran.begin(); session.delete(c); // 删除对象 System.out.println( "~~~1~~~~~~~~~~~~~~~~~~" ); session.flush(); // 将当前尚未执行的 SQL 语句立即执行 System.out.println( "~~~2~~~~~~~~~~~~~~~~~~" ); tran.commit(); System.out.println( session.contains( c ) ); System.out.println( c.getEmail() ); } } public @After void destory(){ session.close(); factory.close(); } }
若没有flush操作则insert语句在提交事务之后输出执行,若有flush操作则将当前尚未执行的 SQL 语句立即执行即在提交事务之前输出insert语句。在save方法执行之后就已经是出于持久化状态无论sql语句是否执行。若处于游离态则对象已经不再被session所管理即contains方法返回false。
测试类中的方法说明:
- 判断指定的对象是否 被 Session 对象所管理: boolean contains( Object po )
- 将尚未执行的SQL语句执行: void flush()
- 将 一个 被 Session 管理的对象驱逐: void evict( Object po )
- 将 整个 Session 所管理的所有的对象全部清理: void clear()
- 如果 一个 Session 对象执行了 close() 方法,则该 Session 对象将无效,一次 曾经被它管理的对象也将进入游离状态
3、四种状态的比较
Persistent 和 Detached区别在于是否被session所管理
核心: 处于 持久化状态的 对象 的 OID 与 数据库中的 某条记录的 主键 一定是 相等的。Hibernate中的核心类和接口
1、org.hibernate.cfg.Configuration:Configuration类表示配置对象,用来读取并解析 hibernate 配置文件
- 注意:Configuration类的configure实例方法负责读取配置文件(hibernate.cfg.xml)
2、org.hibernate.SessionFactory:SessionFactory接口实例专门用来创建连接到指定数据库的会话对象
3、org.hibernate.Session:Session接口的实例是hibernate应用的核心对象,提供了大量的对持久化对象进行操作的方法- 注意:这里的会话指的是当前的Java应用程序和数据库服务器之间的会话(绝对不是HttpSession)
4、org.hibernate.Transaction:Transaction接口的实例表示事务对应的对象,用来对事务进行控制
5、org.hibernate.query.Query:Query接口的实例是hibernate应用中查询时的核心对象- 注意:Hibernate早期(5.x之前)版本中使用query接口是org.hibernate.Query
Session接口只要方法
1、session接口中定义的用来操作持久化对象的方法
- Serializable save(Object object) 保存一个对象到数据库中并返回与之对应的对象标识符(主键的值)
- void persist(Object object) 标准的JPA(Java Persistence API 应用程序编程接口(application program interface))提供的方法,用来持久化一个对象,javax.persistence.EntityManager中的方法
- void saveOrUpdate(Object object) 用来更新一个持久化对象(需要根据对象标识符来实现),默认是根据对象标识符是否为null 来判断应该执行保存操作还是更新操作
- void update(Object object) 用来持久化或更新一个对象
- void delete(Object object) 用来删除一个持久化的对象
- <T> T get(Class<T> entityType,Serializable id) 从数据库汇总查询一条记录并封装成一个相应类型的Java对象,默认不支持延迟加载,当id对应的数据不存在时返回null
- <T> T load(Class<T> theClass,Serializable id) 从数据库汇总查询一条记录并封装成一个相应类型的Java对象,默认支持延迟加载,当id对应的数据不存在时抛出ObjectNotFoundException
- <T> T find(Class<T> entityClass, Object primaryKey) 从数据库汇总查询一条记录并封装成一个相应类型的Java对象 javax.persistence.EntityManager中的方法,默认不支持延迟加载,当id对应的数据不存在时返回null
- Query createQuery(String queryString) 根据给定的 queryString 来创建一个查询器(基于HQL实现的)
- void evict(Object arg0) 将指定的对象从关联的session对象中驱逐
2、保存操作的测试案例
package ecut.session.test;import java.io.Serializable;import java.util.List;import org.hibernate.HibernateException;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;import org.hibernate.query.Query;import org.junit.After;import org.junit.Before;import org.junit.Test;import ecut.session.entity.Customer;public class TestSessionMethod { private SessionFactory factory ; private Session session ; public @Before void init() { // 创建一个 Configuration 对象,用来读取配置文件 ( 默认位置、默认名称 ) Configuration config = new Configuration(); // 读取配置文件 config.configure("ecut/session/hibernate.cfg.xml"); //config.configure(); // 读取 默认位置 ( 当前 classpath ) 的 默认名称 ( hibernate.cfg.xml ) 的配置文件 // 使用 Configuration 创建 SessionFactory factory = config.buildSessionFactory(); // 创建 Session 对象 ( 这里的 Session 是 Java 程序 跟 数据库 之间的 会话 ) session = factory.openSession(); } public @Test void testSave() { Customer c = new Customer(); c.setEmail( "zhangcuishan@wudang.com" ); c.setPassword( "hello2017" ); Transaction tran = session.getTransaction(); try{ tran.begin(); // dynamic-insert="false" : // insert into t_customer (email, password, nickname, gender, birthdate, married, id) values (?, ?, ?, ?, ?, ?, ?) // dynamic-insert="true" // insert into t_customer (email, password, gender , married ,id) values (?, ?, ?,?, ?) System.out.println( "customer.id : " + c.getId() ); Serializable id = session.save( c ); System.out.println( "id : " + id ); System.out.println( "customer.id : " + c.getId() ); tran.commit(); } catch ( HibernateException e) { tran.rollback(); } } public @Test void testPersist() { Customer c = new Customer(); c.setEmail( "moshenggu@wudang.com" ); c.setPassword( "hello2017" ); Transaction tran = session.getTransaction(); try{ tran.begin(); System.out.println( "customer.id : " + c.getId() ); session.persist( c ); System.out.println( "customer.id : " + c.getId() ); tran.commit(); } catch ( HibernateException e) { tran.rollback(); } } public @After void destory(){ session.close(); factory.close(); }}
save方法是持久化对象之后并返回这个对象的主键,persist没有返回值,是标准JPA(Java Persistence API )提供的方法,来自 javax.persistence.EntityManager接口。另外执行插入操作时,不想对所有的字段执行insert操作可以在映射配置文件中的class标签中指定动态插入
3、删除测试案例
package ecut.session.test;import java.io.Serializable;import java.util.List;import org.hibernate.HibernateException;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;import org.hibernate.query.Query;import org.junit.After;import org.junit.Before;import org.junit.Test;import ecut.session.entity.Customer;public class TestSessionMethod { private SessionFactory factory ; private Session session ; public @Before void init() { // 创建一个 Configuration 对象,用来读取配置文件 ( 默认位置、默认名称 ) Configuration config = new Configuration(); // 读取配置文件 config.configure("ecut/session/hibernate.cfg.xml"); //config.configure(); // 读取 默认位置 ( 当前 classpath ) 的 默认名称 ( hibernate.cfg.xml ) 的配置文件 // 使用 Configuration 创建 SessionFactory factory = config.buildSessionFactory(); // 创建 Session 对象 ( 这里的 Session 是 Java 程序 跟 数据库 之间的 会话 ) session = factory.openSession(); }public @Test void testDelete1() { // 先尝试从数据库中获取某条记录对应的一个 Java 对象 Customer c = session.get( Customer.class , 3 ); // 如果指定 id 对应的 对象存在 ( 数据库中有相应的记录 ) if( c != null ) { Transaction tran = session.getTransaction(); try{ tran.begin(); session.delete( c ); // 删除对象 tran.commit(); System.out.println(c.getId()); } catch ( HibernateException e) { tran.rollback(); } } } public @Test void testDelete2() { // 自己创建一个对象并指定 id Customer c = new Customer(); c.setId(2); // 如果 id 是 2 的记录在数据库中存在 Transaction tran = session.getTransaction(); try { tran.begin(); session.delete( c ); // 删除对象 tran.commit(); } catch (HibernateException e) { tran.rollback(); } } public @After void destory(){ session.close(); factory.close(); }}
两种删除,第一种先查询,如果存在这个对象就执行删除操作,第二种直接根据id删除。
4、查询测试案例
package ecut.session.test;import org.hibernate.ObjectNotFoundException;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration;import org.junit.After;import org.junit.Before;import org.junit.Test;import ecut.session.entity.Customer;public class TestLoadData { private SessionFactory factory ; private Session session ; public @Before void init() { // 创建一个 Configuration 对象,用来读取配置文件 ( 默认位置、默认名称 ) Configuration config = new Configuration(); // 读取配置文件 config.configure("ecut/session/hibernate.cfg.xml"); //config.configure(); // 读取 默认位置 ( 当前 classpath ) 的 默认名称 ( hibernate.cfg.xml ) 的配置文件 // 使用 Configuration 创建 SessionFactory factory = config.buildSessionFactory(); // 创建 Session 对象 ( 这里的 Session 是 Java 程序 跟 数据库 之间的 会话 ) session = factory.openSession(); } public @Test void testGet1() { Customer c = session.get( Customer.class , 2 ); if( c != null ){ System.out.println( c.getEmail() ); } else { System.out.println( "数据库中没有对应的数据" ); } } public @Test void testGet2() { System.out.println( "准备查询数据库" ); Customer c = session.get( Customer.class , 1 ); // 立即查询并返回数据 if( c != null ){ System.out.println( "获取到的数据是" ); System.out.println( c.getEmail() ); } } public @Test void testLoad1() { Customer c = null ; try{ c = session.load( Customer.class , 2 ); System.out.println( c.getEmail() ); } catch ( ObjectNotFoundException e) { System.out.println( "数据库中没有对应的数据 , " + e.getMessage() ); } } /** 延迟加载 ( 懒加载 ) * 关闭对 Customer 的延迟加载:* 启用对 Customer 的延迟加载: * */ public @Test void testLoad2() { System.out.println( "准备查询数据库" ); Customer c = session.load( Customer.class , 1 ); // 默认并不立即查询,如果不存在会在最后面才抛出异常 System.out.println( "获取到的数据是 Id" ); System.out.println( c.getId() ); // 因为 id 是 load 方法中指定的,因此不需要查询数据库 System.out.println( "获取到的数据是 Email" ); System.out.println( c.getEmail() ); // 获取 id 之外的 其它 数据时,不得不查询数据库 } public @Test void testFind1() { Customer c = session.find( Customer.class , 2 ); if( c != null ){ System.out.println( c.getEmail() ); } else { System.out.println( "数据库中没有对应的数据" ); } } public @Test void testFind2() { System.out.println( "准备查询数据库" ); Customer c = session.find( Customer.class , 1); // 立即查询并返回数据 if( c != null ){ System.out.println( "获取到的数据是 " ); System.out.println( c.getEmail() ); } } public @After void destory(){ session.close(); factory.close(); }}
get 、load 、find三种查询方法的比较:
- get 、load 、find 都是用来从数据库中加载一条记录并包装成指定类型的对象
- get( Class<?> c , Serializable id )
a、当 id 对应的数据在 数据库中不存在时,get 返回 null
b、get 方法会立即查询数据库 并返回数据
- load( Class<?> c , Serializable id )
a、当 id 对应的数据在 数据库中不存在时,load 方法会抛出 ObjectNotFoundException
b、load 方法 "默认" 不会立即查询数据库,而是等到要使用除了id之外的其它数据时才执行查询操作并返回数据 关闭对 Customer 的延迟加载:启用对 Customer 的延迟加载:
- find( Class<?> c , Serializable id ) 属于 JPA 规范中定义的方法 ( javax.persistence.EntityManager )
a、当 id 对应的数据在 数据库中不存在时,find 返回 null
b、find 方法会立即查询数据库 并返回数据5、查询多条数据测试案例
package ecut.session.test;import java.io.Serializable;import java.util.List;import org.hibernate.HibernateException;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;import org.hibernate.query.Query;import org.junit.After;import org.junit.Before;import org.junit.Test;import ecut.session.entity.Customer;public class TestSessionMethod { private SessionFactory factory ; private Session session ; public @Before void init() { // 创建一个 Configuration 对象,用来读取配置文件 ( 默认位置、默认名称 ) Configuration config = new Configuration(); // 读取配置文件 config.configure("ecut/session/hibernate.cfg.xml"); //config.configure(); // 读取 默认位置 ( 当前 classpath ) 的 默认名称 ( hibernate.cfg.xml ) 的配置文件 // 使用 Configuration 创建 SessionFactory factory = config.buildSessionFactory(); // 创建 Session 对象 ( 这里的 Session 是 Java 程序 跟 数据库 之间的 会话 ) session = factory.openSession(); }public @Test void query() { // Hibernate 3.x : org.hibernate.Query // HQL : Hibernate Query Language FROM之后跟的是实体类的类名 SELECT c FROM Customer AS c String HQL = "FROM Customer AS c ORDER BY c.id DESC" ; // SQL : SELECT * FROM t_customer // 创建 查询器 //Query query = session.createQuery( HQL); Queryquery = session.createQuery( HQL , Customer.class ); System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); // 使用 查询器 进行查询 List list = query.list(); System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); for( Customer c : list ){ System.out.println( c.getId() + " , " + c.getEmail() ); } } public @After void destory(){ session.close(); factory.close(); }}
HQL : Hibernate Query Language FROM之后跟的是实体类的类名 SELECT c FROM Customer AS c,调用list方法可以指明具体的返回类型也可以用?代替。
6、更新测试案例
package ecut.session.test;import java.util.Date;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;import org.junit.After;import org.junit.Before;import org.junit.Test;import ecut.session.entity.Customer;public class TestUpdate { private SessionFactory factory ; public @Before void init() { // 创建一个 Configuration 对象,用来读取配置文件 ( 默认位置、默认名称 ) Configuration config = new Configuration(); // 读取配置文件 config.configure("ecut/session/hibernate.cfg.xml"); //config.configure(); // 读取 默认位置 ( 当前 classpath ) 的 默认名称 ( hibernate.cfg.xml ) 的配置文件 // 使用 Configuration 创建 SessionFactory factory = config.buildSessionFactory(); } /** 更新一个持久化状态的对象中的数据 后 同步到数据库中 ,但是不用 update 方法 */ public @Test void testUpdate1() throws InterruptedException { Session session = factory.openSession(); // 执行查询操作获取数据 Customer c = session.find( Customer.class , 1 ); // 持久化状态 if(c != null){ System.out.println( c.getNickname() + " : " + c.getEmail() ); Transaction tran = session.beginTransaction(); // 开启一个事务并返回该事务的引用 //c.setEmail( "sanfeng@wudang.com" ); //可以在映射配置文件中设置动态插入和动态更新,只更新所更改的数值 c.setNickname( "三丰".equals( c.getNickname() ) ? "君宝" : "三丰" );//如果数据值更改了(只有数据更改了才会执行update语句),提交事务的时候更改的值会同步到数据库 Thread.sleep( 1 ); tran.commit(); // 提交事务 } session.close(); } /** 使用 update 方法将 游离状态 的对象 还原到 持久化状态*/ public @Test void testUpdate2() { Session firstSession = factory.openSession(); Customer c = firstSession.find( Customer.class , 1 ); // 持久化状态 firstSession.close(); // 游离状态 String nickname = c.getNickname() ; //可以在映射配置文件中设置动态插入和动态更新,只更新所更改的数值 c.setNickname( "三丰".equals( nickname ) ? "君宝" : "三丰" ); Session secondSession = factory.openSession() ; secondSession.getTransaction().begin(); secondSession.update( c ); // 将一个 游离状态 的对象重新转换到 持久化状态,无法动态更新,动态更新是针对持久化对象的,只有是持久化对象才知道数据是什么样的。 secondSession.getTransaction().commit(); // 提交事务后,事务即结束 System.out.println( "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" ); secondSession.getTransaction().begin(); String email = c.getEmail() ; //已经是持久化对象因此可以动态对象 c.setEmail( "sanfeng@wudang.com".equals( email ) ? "junbao@qq.com" :"zsf@qq.com" ); secondSession.getTransaction().commit(); } /** 使用 merge 方法 将一个 游离状态的 对象的 数据 合并到 与其id相等的持久化状态的对象中去*/ public @Test void testUpdate3() { Session session = factory.openSession(); Customer c1 = session.find( Customer.class , 1 ); // c1 处于持久化状态 session.evict( c1 ); // c1 开始进入到 游离状态 String nickname = c1.getNickname() ; c1.setNickname( "三丰".equals( nickname ) ? "君宝" : "三丰" ); Customer c2 = session.find( Customer.class , 1 ) ; // 持久化状态 // 根据 c1.id 来在 session 管理的对象中寻找 与它id 相同的对象 // 如果找到 id 相同的对象,就将 c1 中的数据 合并到 相应的持久化状态的对象中去 // 最后 merge 方法返回 那个持久化状态的对象 Object o = session.merge( c1 ); // c1.id == c2.id id是一样的将两个对象的数据进行合并 session.getTransaction().begin(); session.getTransaction().commit();//只要事务开启之后提交就好了,代码位置没有要求 System.out.println( o == c1 ); // false System.out.println( o == c2 ); // true c1合并到c2中了,输出日志中动态更新起了作用,因此是持久化对象C2 System.out.println( session.contains( c1 ) ); // false System.out.println( session.contains( c2 ) ); // true } /** 使用 saveOrUpdate 方法执行 更新操作,saveOrUpdate的操作条件 取决于映射文件中的unsaved-value属性的属性值*/ public @Test void testUpdate4() { Session session = factory.openSession(); Customer c = session.find( Customer.class , 1 ); // 持久化状态 session.close(); // 游离状态 System.out.println( "id : " + c.getId() ); String nickname = c.getNickname() ; c.setNickname( "三丰".equals( nickname ) ? "君宝" : "三丰" ); session = factory.openSession();//重新开启一个session session.getTransaction().begin(); //// 取决于 c.id 是否是 null ,如果 id 是 null 就执行 insert ,否则执行 update session.saveOrUpdate( c ); // 执行 update 操作,将 游离状态的对象 转换到 持久化状态 session.getTransaction().commit(); } /** 使用 saveOrUpdate 方法执行 保存操作 */ public @Test void testSave() { /* Session session = factory.openSession(); Customer c = session.find( Customer.class , 1 ); // 持久化状态 session.close(); // 游离状态 c.setId( null ); //等价于new一个新的对象 c.setEmail( "zhangwuji@wudang.com" ); c.setNickname( "曾阿牛" ); */ Customer c = new Customer(); c.setEmail( "yinsusu@tianying.com" ); c.setPassword( "hello2017" ); Date birthdate = null ; c.setBirthdate( birthdate ); c.setGender( '女' ); c.setNickname( "素素" ); c.setMarried( false ); Session session = factory.openSession(); session.getTransaction().begin(); // // 取决于 c.id 是否是 null ,如果 id 是 null 就执行 insert ,否则执行 update session.saveOrUpdate( c ); // 执行 insert 操作,对象 进入 持久化状态 session.getTransaction().commit(); } public @After void destory(){ factory.close(); }}
更新操作有四种方法
- 更新一个持久化状态的对象中的数据 后 同步到数据库中 ,但是不用 update 方法
- 使用 update 方法将 游离状态 的对象 还原到 持久化状态
- 使用 merge 方法 将一个 游离状态的 对象的 数据 合并到 与其id相等的持久化状态的对象中去
- 使用 saveOrUpdate 方法执行 更新操作,saveOrUpdate的操作条件 取决于映射文件中的unsaved-value属性的属性值
可以在映射文件中配置dynamic-update属性来实现动态更新
saveOrUpdate也可以完成插入操作
在映射文件中需要在id标签中指定unsaved-value属性的属性值,来决定什么时候执行插入操作什么时候执行更新操作
转载请于明显处标明出处: