การลบด้วยวิธี 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