การลบด้วยวิธี remove()
สุดท้าย มาดูการลบวัตถุกัน โดยหลักการแล้ว การลบออบเจกต์ออกจากฐานข้อมูลนั้นง่ายมาก แต่อย่างที่บอกว่ามีความแตกต่าง และมีหกความแตกต่างดังกล่าว:
- การลบด้วย วิธี remove()
- การกำจัดสำหรับ บริษัท
- การกำจัดโดย Orphan
- ลบด้วย JPQL
- การลบผ่าน NativeQuery
- ซอฟต์ลบ ()
และเราจะเริ่มต้นด้วยวิธี แก้ปัญหาที่ชัดเจนที่สุด นั่นคือการเรียกใช้เมธอดremove()
User user = new User();
user.setName("Kolyan");
session.persist(user); // add an object to the database
session.flush();
session.clear(); // close the session
user = (User) session.find(User.class, user.getId() ); //receive the object from the database
session.remove(user);
session.flush();
session.clear(); // close the session
//here the object is actually deleted.
การดำเนินการจริงในฐานข้อมูลจะดำเนินการหลังจาก เมธอด flush() ถูกเรียก หรือธุรกรรมถูกปิด
ลบซ้อน
คุณจำได้ไหมว่าเมื่อเราศึกษา SQL ตารางอ้างอิงสามารถเขียนด้วย CONSTRAINT และหนึ่งในนั้นดำเนินไปดังนี้:
CONSTRAINT ONDELETE REMOVE
ความหมายคือถ้าเรามีตารางที่มีเอนทิตีย่อย เมื่อจัดสรรเอนทิตีหลักแล้ว จะต้องลบรายการย่อยทั้งหมด
สมมติว่าเราเก็บข้อมูลส่วนตัวของผู้ใช้ไว้ที่ใดที่หนึ่ง และตั้งค่า CONSTRAINT ในฐานข้อมูล ดังนั้นเมื่อผู้ใช้ถูกลบ ข้อมูลนี้ก็จะถูกลบไปด้วย จากนั้นเราเพียงแค่ต้องลบวัตถุหลักและวัตถุย่อยทั้งหมดจะถูกลบที่ระดับพื้นฐาน:
User user = new User();
UserPrivateInfo info = new UserPrivateInfo();
user.setPrivateInfo(info);
session.persist(user); //add the object to the database, the info object will also be saved to the database
session.flush();
session.clear(); // close the session
user = (User) session.find(User.class, user.getId() ); //receive the object from the database
session.remove(user);
session.flush();
session.clear(); // close the session
// here the user and info objects are actually removed from the database.
การกำจัดโดย Orphan
นอกจากนี้ยังมีการกำจัดอีกประเภทหนึ่งที่เรียกว่าการกำจัดเด็กกำพร้า มันค่อนข้างคล้ายกับรุ่นก่อนหน้า เอนทิตีย่อยจะถูกลบเมื่อความสัมพันธ์กับเอนทิตีหลักเสียหาย ในกรณีนี้ เอนทิตีหลักจะไม่ถูกลบ
สมมติว่าเรามีผู้ใช้และเขามีรายการโพสต์:
User user = new User();
UserMessage message = new UserMessage();
user.getMessageList().add(message);
session.persist(user); //add the object to the database, the message object will also be saved to the database
session.flush();
session.clear(); // close the session
user = (User) session.find(User.class, user.getId() ); //receive the object from the database
UserMessage message2 = user.getMessageList().get(0); //get the user's message
user.getMessageList().remove(message2); //remove the message from the list
session.flush();
session.clear(); // close the session
// here the message2 object is actually removed from the database
นอกจากนี้ยังมีความแตกต่างเล็กน้อยที่สำคัญ หากเราต้องการให้ Hibernate ใช้ลักษณะการทำงานนี้ จะต้องระบุอย่างชัดเจนเมื่อเชื่อมโยงเอนทิตีสองรายการโดยใช้คำอธิบายประกอบ:
@Entity
public class User {
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
private List<UserMessage> messageList = new ArrayList<UserMessage>();
}
ลบผ่าน JPQL
อีกวิธีที่น่าสนใจในการลบออบเจกต์คือเขียนคิวรี HQL (หรือ JPQL) อย่าลืมเรียกเมธอด executeUpdate()ในตอนท้ายมิฉะนั้น Hibernate จะสร้างธุรกรรมแบบอ่านอย่างเดียว และคุณจะไม่ถูกลบใดๆ
ตัวอย่าง:
User user = new User();
session.persist(user); // add an object to the database
session.flush();
session.clear(); // close the session
session.createQuery("delete from User where id = :id")
.setParameter("id", user.getId())
.executeUpdate();
การเปลี่ยนฐานข้อมูลจะไม่เปลี่ยนวัตถุเอนทิตีที่มีอยู่ แต่อย่างใด
การลบผ่าน NativeQuery
ในทำนองเดียวกัน คุณสามารถลบและเรียกใช้ NativeQuery
ตัวอย่าง:
User user = new User();
session.persist(user); // add an object to the database
session.flush();
session.clear(); // close the session
session.createNativeQuery("DELETE FROM user WHERE id = :id")
.setParameter("id", user.getId())
.executeUpdate();
การเปลี่ยนแปลงในฐานข้อมูลจะไม่ส่งผลกระทบต่อวัตถุเอนทิตีที่มีอยู่ แต่อย่างใด
ลบอย่างนุ่มนวล
บางครั้ง แทนที่จะลบข้อมูลในฐานข้อมูล จะเป็นการสะดวกที่จะทำเครื่องหมายว่าลบแล้ว ข้อมูลดังกล่าวสามารถมีส่วนร่วมในสถานการณ์ต่างๆ ประการแรก การลบดังกล่าวสามารถย้อนกลับได้อย่างง่ายดาย - สามารถทำเครื่องหมายบรรทัดอีกครั้งว่าใช้งานได้
ประการที่สอง มีประโยชน์ในการ "เก็บถาวร" ข้อมูลระยะไกลดังกล่าว เนื่องจากมีหลายกรณีที่พฤติกรรมของเซิร์ฟเวอร์ถูกควบคุมโดยกฎหมายและอื่นๆ อย่างไรก็ตาม หากคุณทำเครื่องหมายข้อมูลของคุณว่าลบแล้ว จะมีเพียงคุณเท่านั้นที่รู้ว่าข้อมูลนั้นถูกลบไปแล้ว ไฮเบอร์เนตจะยังคงค้นหาข้อมูลนี้และใช้เมื่อทำการเรียงลำดับ
ดังนั้นผู้สร้าง Hibernate จึงมาพร้อมกับคำอธิบายประกอบพิเศษซึ่งจะทำให้สามารถทำเครื่องหมายวัตถุว่ามีชีวิตได้ ตัวอย่าง:
@Entity
@Where(clause = "DELETED = 0") //in all WHEREs "AND DELETED = 0" will be added
public class User {
// mapping fields
@Column(name = "DELETED") // if the value in the DELETED column == 0, then the record is alive, if 1 - dead
private Integer deleted = 0;
//getters and setters
public void softDeleted() {
this.deleted = 1; //mark the post as dead
}
}
ในการทำเครื่องหมายวัตถุว่าถูกลบ คุณเพียงแค่เรียกใช้เมธอด softDeleted()บนวัตถุนั้น:
User user = new User();
session.persist(user); // add an object to the database
session.flush();
session.clear(); // close the session
user = (User) session.find(User.class, user.getId() ); //receive the object from the database
user.softDeleted(); // mark the object as deleted
session.flush();
session.clear(); // close the session
//this object will no longer reside via Hibernate
GO TO FULL VERSION