ホームページ  >  記事  >  Java  >  Hibernate におけるオブジェクトの 3 つの状態とそれらの相互変換

Hibernate におけるオブジェクトの 3 つの状態とそれらの相互変換

黄舟
黄舟オリジナル
2017-03-02 11:22:571111ブラウズ

休止状態のオブジェクトには 3 つの状態があります: 一時状態 (一時的)、永続状態 (永続)、デタッチ状態 (分離)

1. 一時状態 (Transient)

Java の new キーワードを通じてエンティティ オブジェクトを生成すると、エンティティ オブジェクトは次のようにフリー状態になります:

 Customer customer=new Customer(“zx”,27,images);

この時点で、顧客オブジェクトはフリー状態にあり、 customer オブジェクトがフリー状態であると言われるのはなぜですか?これは、現時点では顧客は JVM を通じてメモリ領域の一部を取得しているだけであり、Session オブジェクトの save() メソッドを通じてデータベースに保存されていないためです。したがって、それはまだ Hibernate の中に含まれていません。キャッシュ管理。これは、顧客オブジェクトが Hibernate キャッシュ管理の外で自由にローミングできることを意味します。したがって、フリーオブジェクトの最大の特徴は、データベース内にそれに対応するレコードが存在しないことであることがわかります。

一時オブジェクトの特徴:

(1) セッションインスタンスに関連付けられていません

(2) データベース内に一時オブジェクトに関連付けられたレコードがありません

2。 Persistent (永続)

永続オブジェクトはデータベースに保存されたエンティティ オブジェクトであり、このエンティティ オブジェクトは依然として Hibernate のキャッシュ管理下にあります。このエンティティ オブジェクトに対する変更は、キャッシュがクリアされるときにデータベースに同期されます。以下に示すように:

Customer customer=new Customer(“zx”,27,images);
tx=session.beginTransaction();
session.save(customer);
customer=(Customer)session.load(Customer.class,”1”);
customer.setAge(28);
tx.commit();

この時点では、更新を保存するために session.update() メソッドを明示的に呼び出していませんが、エンティティ オブジェクトへの変更は引き続きデータベースに同期的に更新されます。オブジェクトは save メソッドによってデータベースに保存され、すでに永続オブジェクトになっていますが、load メソッドによって再度ロードされます。そのため、この時点ではまだ Hibernate キャッシュの管理下にあります。 tx.commit() メソッドが実行されると、Hibernate はキャッシュを自動的にクリーンアップし、永続オブジェクトのプロパティの変更をデータベースに自動的に同期します。

永続インスタンスはデータベース内に対応するレコードを持ち、永続オブジェクトは常にセッションとトランザクションに関連付けられます。セッションでは、永続オブジェクトへの変更はすぐには反映されません。データベースは変更される必要があります。また、トランザクションが終了した後、つまり commit() が実行された後、変更を加えるにはデータベース内で SQL を実際に実行する必要があり、永続オブジェクトの状態はデータベースと同期されます。同期前の永続オブジェクトはダーティ オブジェクトと呼ばれます。

一時オブジェクトを永続オブジェクトに変換します:

(1)

Session の save() および saveOrUpdate() メソッドを通じて一時オブジェクトをデータベースに関連付けると、この一時オブジェクトは永続オブジェクトになります。 (2)

fine()、get()、load()、および iterater() メソッドを使用してクエリされたデータ オブジェクトは永続オブジェクトになります。 永続オブジェクトの特徴:

(1)

はSessionインスタンス(2)

に関連付けられています

データベースには永続オブジェクトに関連付けられたレコードがあります

3。

デタッチ状態 (Detached) 永続オブジェクトが Hibernate のキャッシュ管理から離脱すると、フリー状態になります。 フリー オブジェクトとフリー オブジェクトの最大の違いは、フリー オブジェクトには別のパスが存在する可能性があることです。データベース内のそれに対応するレコードは、このフリー オブジェクトが Hibernate のキャッシュ管理の外にあるだけであり、フリー オブジェクトはデータベース内に対応するデータ レコードを持ちません。以下に示すように:

Customer customer=new Customer(“zx”,27,images);
tx=session.beginTransaction();
session.save(customer);
customer=(Customer)session.load(Customer.class,”1”);
customer.setAge(28);
tx.commit();
session.close();

セッションが閉じられると、顧客オブジェクトは Hibernate のキャッシュ管理から外れますが、この時点ではデータベース内に顧客オブジェクトに対応するデータ レコードがまだ存在するため、顧客オブジェクトはこの時点ではフリー状態です

永続オブジェクトに関連付けられたセッションが閉じられると、オブジェクトは切り離されたオブジェクトになります。切り離されたオブジェクトへの参照は有効なままであり、オブジェクトは引き続き変更できます。

分離されたオブジェクトの特徴:

(1)

本質的には一時オブジェクトと同じ

(2) 只是比爱瞬时对象多了一个数据库记录标识值 id.

持久对象转为脱管对象:

当执行 close() 或 clear(),evict() 之后,持久对象会变为脱管对象。

瞬时对象转为持久对象:

通过 Session 的 update(),saveOrUpdate() 和 lock() 等方法,把脱管对象变为持久对象。

三种状态相互转化的状态图如下:

Hibernate におけるオブジェクトの 3 つの状態とそれらの相互変換

4 .结合 save(),update(),saveOrUpdate() 方法说明对象的状态

(1)Save() 方法将瞬时对象保存到数据库,对象的临时状态将变为持久化状态。当对象在持久化状态时,它一直位于 Session 的缓存中,对它的任何操作在事务提交时都将同步到数据库,因此,对一个已经持久的对象调用 save()或 update() 方法是没有意义的。如:

Student stu = new Strudnet();
stu.setCarId(“200234567”);
stu.setId(“100”);
// 打开 Session, 开启事务
session.save(stu);
stu.setCardId(“20076548”);
session.save(stu); // 无效
session.update(stu); // 无效
// 提交事务,关闭 Session


(2)update() 方法两种用途重新关联脱管对象为持久化状态对象,显示调用 update() 以更新对象。调用 update() 只为了关联一个脱管对象到持久状态,当对象已经是持久状态时,调用 update() 就没有多大意义了。如:

// 打开 session ,开启事务 
stu = (Student)session.get(Student.class,”123456”);
stu.setName(“Body”);
session.update(stu); // 由于 stu 是持久对象,必然位于 Session 缓冲中,
对 stu 所做的变更将 // 被同步到数据库中。所以 update() 是没有意义的,可以不要这句效果一样的。
// 提交事务,关闭 Session


Hibernate 总是执行 update 语句,不管这个脱管对象在离开 Session 之后有没有更改过,在清理缓存时 Hibernate总是发送一条 update 语句,以确保脱管对象和数据库记录的数据一致,如:

Student stu = new Strudnet();
stu.setCarId(“1234”);
// 打开 Session1, 开启事务
session1.save(stu);
// 提交事务,关闭 Session1
stu.set(“4567”); // 对脱管对象进行更改
// 打开 Session2, 开启事务
session2.update(stu);
// 提交事务,关闭 Session2


注:即使把 session2.update(stu); 这句去掉,提交事务时仍然会执行一条 update() 语句。

如果希望只有脱管对象改变了, Hibernate 才生成 update 语句,可以把映射文件中  标签的 select-before-update 设为 true, 这种会先发送一条 select 语句取得数据库中的值,判断值是否相同,如果相同就不执行 update语句。不过这种做法有一定的缺点,每次 update 语句之前总是要发送一条多余的 select 语句,影响性能。对于偶尔更改的类,设置才是有效的,对于经常要更改的类这样做是影响效率的。

(3)saveOrUpdate() 方法兼具 save() 和 update() 方法的功能,对于传入的对象, saveOrUpdate() 首先判断其是脱管对象还是临时对象,然后调用合适的方法。

 以上就是Hibernate中对象的三种状态及相互转化的内容,更多相关内容请关注PHP中文网(www.php.cn)!


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。