Hibernate对象的三种状态
一、状态介绍
hibernate 规定三种状态:
瞬时态(临时态)、持久态、脱管态(游离态)
状态
瞬时态/临时态:transient,session没有缓存对象,数据库也没有对应记录。
1.没有与Hibernate产生关联. 2.没有与数据库中的记录产生关联(有关联就是与数据库中的id有对应).
OID特点:没有值
持久态:persistent,session缓存对象,数据库最终会有记录。(事务没有提交)
1.session 有关联 2. 对象有Id
OID特点:有值
脱管态/游离态:detached,session没有缓存对象,数据库有记录。
1.没有与Hibernate产生关联 2.对象有ID
二、转换
1、瞬时态/临时态
l 获得:一般都只直接创建(new)
l 瞬时态 转换 持久态
一般操作:save方法、saveOrUpdate
l 瞬时态 转换 脱管态
一般操作:通过setId方法设置数据
例如:
Useruser = new User(); //瞬时态
user.setUid(1); //脱管态
2、持久态
获得:
查询操作:get、loat、createQuery、createCriteria 等 获得都是持久态【】
执行save之后持久态
执行update之后持久态
持久态 转换 瞬时态
官方规定执行delete() --民间:删除态
持久态 转换 脱管态
session没有记录
session.close () 关闭
session.clear() 清除所有
session.evict(obj) 清除指定的PO对象
3、脱管态/游离态
获得:
创建、并设置OID的
通过api获得
脱管态 转换 瞬时态
手动去除OID,设置成默认值
脱管态 转换 持久态
一般操作:update()、saveOrUpdate
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123456</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/Day02</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="hbm2ddl.auto">update</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.current_session_context_class">thread</property>
<mapping resource="domain/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>>
package domain;
public class User {
private Integer id;
private String name;
private String password;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", password=" + password
+ "]";
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="domain">
<class name="User" table="t_user">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="name" column="name"></property>
<property name="password" column="password"></property>
</class>
</hibernate-mapping>
package utils;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
public class HibernateUtils {
private static SessionFactory sf;
static{
//加载配置
Configuration conf = new Configuration().configure();
//根据configuration配置信息创建SessionFactory
sf = conf.buildSessionFactory();
//关闭虚拟机时,释放SessionFactory
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
sf.close();
}
}));
}
//获得session
//方式一:获得一个全新的session对象
public static org.hibernate.Session openSession(){
Session session = sf.openSession();
return session;
}
//方式二:获得与当前线程绑定的session对象(调用getCurrentSession 需要加上一个配置: (在hibernate.cfg.xml中) )
// <property name="hibernate.current_session_context_class">thread</property>
public static org.hibernate.Session getCurrentSession(){
Session session = sf.getCurrentSession();
return session;
}
}
package com.hcx.a_state;
import org.hibernate.Session;
import org.junit.Test;
import com.hcx.domain.User;
import com.hcx.utils.HibernateUtils;
//对象的三种状态
public class Demo1 {
@Test
//演示三种状态
public void fun1(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
//------------------------------------------------
User u = new User(); // 瞬时状态
u.setName("tom"); // 瞬时状态
u.setPassword("1234"); // 瞬时状态
session.save(u); // 持久状态
//问题: 调用完save方法,数据库中有没有对应记录?
// 没有对应记录, 但是最终会被同步到数据库中.仍然是持久状态.
//------------------------------------------------
session.getTransaction().commit(); // 持久状态
session.close(); // 游离状态
}
@Test
//三种状态的转换
// 瞬时 => 持久
//瞬时:没有关联,没有id
//持久: 有关联,有id
public void fun2(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
//------------------------------------------------
User u = new User(); // 瞬时状态
u.setName("tom"); // 瞬时状态
u.setPassword("1234"); // 瞬时状态
session.save(u); // 持久状态 save方法会使用主键生成策略,为User指定id. =>
//主键自增 => 打印 insert语句
//--------------------------// increment=> select max(id) ....
//assigned => 需要手动指定主键,不指定将会报错
session.getTransaction().commit(); // 持久状态
//事务提交时,会把持久化状态对象同步到数据库中
session.close(); // 游离状态
}
// 瞬时=> 游离
// 瞬时: 没有关联,没有id
// 游离: 没有关联,有id(与数据库中对应的id)
@Test
public void fun3(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
//------------------------------------------------
User u = new User(); // 瞬时状态
u.setId(1); //游离
//----------------------------------------------------
session.getTransaction().commit(); // 持久状态
//事务提交时,会把持久化状态对象同步到数据库中
session.close(); // 游离状态
}
@Test
// 持久=> 瞬时
// 持久: 有关联,有id
// 瞬时: 无关联,无id
public void fun4(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
//------------------------------------------------
//通过get方法,得到持久状态对象
User u= (User) session.get(User.class, 1); // 持久状态
//----------------------------------------------------
session.getTransaction().commit(); // 持久状态
//事务提交时,会把持久化状态对象同步到数据库中
session.close(); // 游离状态
u.setId(null);//瞬时状态
}
@Test
// 持久=> 瞬时
// 持久: 有关联,有id
// 瞬时: 无关联,无id
public void fun5(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
//------------------------------------------------
//通过get方法,得到持久状态对象
User u= (User) session.get(User.class, 1); // 持久状态
session.evict(u);//将User对象与session的关联移除
u.setId(null);//瞬时状态
session.save(u);//持久状态
//----------------------------------------------------
session.getTransaction().commit(); // 持久状态
//事务提交时,会把持久化状态对象同步到数据库中
session.close(); // 游离状态
}
// 持久=> 游离
@Test
// 持久=> 游离
//持久:有关联,有id
//游离:没有关联,有id(与数据库中对应的id)
// 只需要将session的关联取消
public void fun6(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
//------------------------------------------------
//通过get方法,得到持久状态对象
User u= (User) session.get(User.class, 1); // 持久状态
session.evict(u);//游离
//----------------------------------------------------
session.getTransaction().commit(); // 游离状态
session.close(); // 游离状态
}
@Test
// 游离=> 瞬时
//游离:没有关联,有id(与数据库中对应的id)
//瞬时:无关联,无id
// 移除ID
public void fun7(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
//------------------------------------------------
//通过get方法,得到持久状态对象
User u= (User) session.get(User.class, 1); // 持久状态
session.evict(u);//游离
u.setId(null);// 瞬时
//----------------------------------------------------
session.getTransaction().commit(); // 瞬时状态
session.close(); // 瞬时状态
}
@Test
// 游离=> 持久
//游离:没有关联,有id(与数据库中对应的id)
//持久:有关联,有id
// 是否与Session关联
public void fun8(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
//------------------------------------------------
//通过get方法,得到持久状态对象
User u= (User) session.get(User.class, 1); // 持久状态
session.evict(u);//游离
session.update(u);//持久
//----------------------------------------------------
session.getTransaction().commit(); // 持久状态 -> 打印update语句
session.close(); // 瞬时状态
}
//三种状态有什么用?
// 持久状态,我们使用Hibernate主要是为了持久化我们的数据.
// 对于对象的状态,我们期望我们需要同步到数据库的数据,都被转换成持久状态
//持久化状态特点: Hibernate会自动将持久化状态对象的变化同步到数据库中.
@Test
public void fun9(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
//------------------------------------------------
//通过get方法,得到持久状态对象
User u= (User) session.get(User.class, 1); // 持久状态
u.setName("jerry");//持久状态
// u.setId(3);//与session建立关联的对象的ID,不允许修改.
session.update(u);// 多余=> 因为Hibernate会自动将持久化状态对象的变化同步到数据库中.
//----------------------------------------------------
session.getTransaction().commit(); // 持久状态 -> 打印update语句
session.close(); // 瞬时状态
}
}