三、持久化对象
1.持久化类的要求
(1)提供一个无参数的构造器;
(2)提供一个标识属性(用来映射数据库表的主键字段,并不要使用基本数据类型);
(3)为持久化类的每个成员添加setter、getter方法;
(4)使用非final的类;
(5)重写equals()方法和hashCode()方法。
2.持久化对象的状态
Hibernate持久化对象支持如下几种对象状态:
1)瞬态:
对象由new操作符创建,且尚未与Hibernate Session关联的对象被认为处于瞬态;
2)持久化:
持久化实例在数据库中有对应的记录,并拥有一个持久化标识(identifier);
3)脱管:
某个实例曾经处于持久化状态,但随着与之关联的Session被关闭,该对象就变成脱管状态。
3.改变持久化对象状态的方法
持久化类News:
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import ;
import javax.persistence.Table;
@Entity
@Table(name="news_a_inf")
public class News {
@Id //主键标识
@GeneratedValue(strategy=GenerationType.IDENTITY) //主键增长策略
private Integer id;
private String title;
private String content;
//setter getter方法
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}(1)持久化实体
示例:
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
public class Test {
public static void main(String[] args) {
//创建Configuration实例
Configuration cfg = new Configuration().configure();
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.applySettings(cfg.getProperties()).build();
//以Configuration创建SessionFactory
SessionFactory sf = cfg.buildSessionFactory(serviceRegistry);
//创建Session
Session session = sf.openSession();
//开启事务
Transaction tx = session.beginTransaction();
//新建一个持久化对象
News n1 = new News(); //对象处于瞬态
//设置news的属性值
n1.setTitle("news_a");
n1.setContent("this is test A!");
session.save(n1); //瞬态实体转变为持久化实体,把该实体对应记录插入到数据表中
//新建一个持久化对象
News n2 = new News(); //对象处于瞬态
n2.setTitle("news_b");
n2.setContent("this is test B!");
session.persist(n2); //瞬态实体转变为持久化实体,吧实体对应记录插入数据表中
//提交事务
tx.commit();
//关闭session
session.close();
sf.close();
}
}
save()方法和persist()方法的区别:
1)返回值,save()方法返回该持久化对象的标识属性值;persist()方法没有返回值;
2)程序执行save()方法将立即把持久化对象对应的记录插入到数据库中,而persist()方法则保证当它在一个事务外部时,并不立即转换成insert语句。
(2)根据主键加载持久化实体
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
public class Test2 {
public static void main(String[] args) {
Configuration cfg = new Configuration().configure();
ServiceRegistry serviceRegistry =
new StandardServiceRegistryBuilder()
.applySettings(cfg.getProperties()).build();
SessionFactory sf = cfg.buildSessionFactory(serviceRegistry);
Session session = sf.openSession();
Transaction t = session.beginTransaction();
//根据主键加载持久化实体 使用load()方法
News n1 = (News)session.load(News.class, 1);
System.out.println(n1.getTitle());
System.out.println(n1.getContent());
//根据主键加载持久化实体 使用get()方法
News n2 = (News)session.get(News.class, 2);
System.out.println(n2.getTitle());
System.out.println(n2.getContent());
}
}load()方法和get()方法的区别:
load()方法和get()方法的主要区别在于能否延迟加载,使用load()方法将具有延迟加载功能,load()方法不会立即访问数据库,当试图加载的记录不存在时,load()方法可能返回一个未初始化的代理对象;而get()方法总是立即访问数据库,如果数据库中并不存在查找内容,则直接返回null。
(3)更新持久化实体
一旦加载了该持久化实例后,该实体就处于持久化状态,在代码中对持久化实例所做的修改被保存到数据库。
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
public class Test3 {
public static void main(String[] args) {
Configuration cfg = new Configuration().configure();
ServiceRegistry serviceRegistry =
new StandardServiceRegistryBuilder()
.applySettings(cfg.getProperties())
.build();
SessionFactory sf = cfg.buildSessionFactory(serviceRegistry);
Session session = sf.openSession();
Transaction t = session.beginTransaction();
//根据实例标识属性加载持久化实例
News n = (News)session.load(News.class, 1);
//修改属性值
n.setTitle("news_c");
n.setContent("this is test C!");
//直接修改后不需要session.flush();或者update()方法,修改就会被自动保存
//这是修改记录最简单的方法
t.commit();
session.close();
sf.close();
}
}(4)更新脱管实体
当程序修改脱管对象的状态后,应该显式地使用Session来保存这些修改。
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
public class Test4 {
public static void main(String[] args) {
Configuration cfg = new Configuration().configure();
ServiceRegistry serviceRegistry =
new StandardServiceRegistryBuilder().applySettings(cfg.getProperties()).build();
SessionFactory sf = cfg.buildSessionFactory(serviceRegistry);
//第一个Session
Session s1 = sf.openSession();
//根据主键加载持久化实体
News n = (News)s1.load(News.class, 1);
System.out.println(n.getTitle());
System.out.println(n.getContent());
//关闭Session
s1.close();
//开启第二个Session
Session s2 = sf.openSession();
//n曾处于持久化状态,session关闭后处于脱管状态
n.setTitle("test_a");
n.setContent("this is test A!");
//保存脱管对象所做的修改
s2.update(n);
//也可以使用s2.merge(n)方法保存修改
}
}merge()方法和update()方法的区别:
当执行session.update(a)方法后,a对象将变成持久化状态;而执行session.merge(a)方法后,a对象任然不是持久化状态,a对象任然不会被关联到Session上,merge()方法返回的不是a对象,而是a对象的副本;
当程序使用merge()方法保存程序对脱管对象所做的修改时,如果Session中存在相同持久化标识的持久化对象,merge()方法里提供的对象状态将覆盖原有持久化实例的状态。如果Session中没有相应的持久化实例,则尝试从数据库中加载,或者创建新的持久化实例,最后返回该持久化实例。
(5)删除持久化实体
通过Session的delete()方法可以删除持久化实例,一旦删除了该持久化实例,该持久化实例对应的数据表记录也将会被删除。
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
public class Test5 {
public static void main(String[] args) {
Configuration cfg = new Configuration().configure();
ServiceRegistry serviceRegistry =
new StandardServiceRegistryBuilder()
.applySettings(cfg.getProperties())
.build();
SessionFactory sf = cfg.buildSessionFactory(serviceRegistry);
Session session = sf.openSession();
Transaction t = session.beginTransaction();
//加载持久化实体
News n = (News) session.load(News.class, 1);
//删除该实体
session.delete(n);
t.commit();
session.close();
sf.close();
}
}
















