Xóa bằng phương thức remove()

Cuối cùng, hãy xem xét việc xóa một đối tượng. Về nguyên tắc, việc xóa các đối tượng khỏi cơ sở dữ liệu rất đơn giản, nhưng như họ nói, có những sắc thái. Và có sáu sắc thái như vậy:

  • Xóa bằng phương thức remove()
  • Diệt mối cho công ty
  • Loại bỏ bởi trẻ mồ côi
  • Xóa bằng JPQL
  • Xóa qua NativeQuery
  • softDeleted()

Và chúng ta sẽ bắt đầu với giải pháp rõ ràng nhất - gọi phương thức 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.

Hoạt động thực tế trong cơ sở dữ liệu sẽ được thực thi sau khi phương thức flush() được gọi hoặc giao dịch được đóng lại.

Xếp tầng xóa

Bạn có nhớ khi chúng ta học SQL, các bảng phụ thuộc có thể được viết bằng CONSTRAINT. Và một trong số họ đã đi như thế này:

CONSTRAINT ONDELETE REMOVE

Ý nghĩa của nó là nếu chúng ta có một bảng chứa các thực thể con, thì khi thực thể mẹ được cấp phát, tất cả các con của nó phải bị xóa.

Giả sử chúng ta lưu trữ thông tin cá nhân của người dùng ở đâu đó và thiết lập CONSTRAINT trong cơ sở dữ liệu để khi người dùng bị xóa thì dữ liệu này cũng bị xóa theo. Khi đó chúng ta chỉ cần xóa đối tượng cha và tất cả các đối tượng con sẽ bị xóa ở mức cơ sở:

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.

Loại bỏ bởi trẻ mồ côi

Ngoài ra còn có một loại loại bỏ khác được gọi là Loại bỏ mồ côi. Nó hơi giống với phiên bản trước. Một thực thể con bị xóa khi mối quan hệ của nó với thực thể mẹ bị phá vỡ. Trong trường hợp này, thực thể mẹ thường không bị xóa.

Giả sử chúng ta có một người dùng và anh ta có một danh sách các bài viết:

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

Ngoài ra còn có một sắc thái quan trọng, nếu chúng ta muốn Hibernate thực hiện hành vi này, nó phải được chỉ định rõ ràng khi liên kết hai thực thể bằng chú thích:

@Entity
public class User {

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    private List<UserMessage> messageList = new ArrayList<UserMessage>();

}

Xóa qua JPQL

Một cách thú vị khác để xóa một đối tượng là viết truy vấn HQL (hoặc JPQL). Chỉ cần đừng quên gọi phương thức execUpdate() ở cuối , nếu không, Hibernate sẽ tạo giao dịch chỉ đọc và bạn sẽ không bị xóa.

Ví dụ:

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();

Việc thay đổi cơ sở dữ liệu sẽ không thay đổi các đối tượng Thực thể hiện có theo bất kỳ cách nào.

Xóa qua NativeQuery

Tương tự, bạn có thể xóa và gọi NativeQuery.

Ví dụ:

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();

Thay đổi trong cơ sở dữ liệu sẽ không ảnh hưởng đến các đối tượng Thực thể hiện có theo bất kỳ cách nào.

xóa mềm

Đôi khi, thay vì xóa dữ liệu trong cơ sở dữ liệu, sẽ thuận tiện hơn nếu chỉ cần đánh dấu dữ liệu đó là đã xóa. Dữ liệu như vậy sau đó có thể tham gia vào các tình huống khác nhau. Đầu tiên, việc xóa như vậy có thể dễ dàng đảo ngược - các dòng có thể được đánh dấu lại là đang hoạt động.

Thứ hai, rất hữu ích khi "lưu trữ" dữ liệu từ xa như vậy, bởi vì có những trường hợp khi hành vi của máy chủ được quy định bởi luật pháp và những thứ tương tự. Tuy nhiên, nếu bạn đánh dấu dữ liệu của mình là đã xóa, thì chỉ bạn mới biết rằng dữ liệu đó đã bị xóa. Hibernate sẽ vẫn tìm thấy dữ liệu này và cũng sử dụng nó khi sắp xếp.

Do đó, những người tạo ra Hibernate đã đưa ra một chú thích đặc biệt để có thể đánh dấu các đối tượng còn sống. Ví dụ:

@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
    }
}

Để đánh dấu một đối tượng là đã xóa, bạn chỉ cần gọi phương thức softDeleted() trên đó :

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