Persistence and Serializable

1. Persistence
Bao gồm 3 lĩnh vực:
  • Các API của chính nó, được định nghĩa trong gói javax.persistence
  • Persistence: giá trị duy nhất được sử dụng bởi các container để map đối tượng entity tới các bản ghi tương ứng. Bạn có thể lưu các dữ liệu trong một tập tin mã hóa và giải mã thuật toán riêng của bạn.
  • Cấu hình Persistence Unit được định nghĩa ra file persistence.xml.
  • Mỗi Persistence Unit định nghĩa 1 hoặc nhiều thực thể quản lý mà các EntityManager của 1 ứng dụng có thể quản lý.
  • Mỗi Persistence Unit cung cấp 1 tập hợp các thuộc tính cho việc cấu hình Data Source.
  • Cùng với tất cả các chi tiết kết nối cần thiết, các Persistence Unit cũng chỉ rõ các nhà cung cấp JPA.
  • Có thể có các nhà cung cấp persistence khác nhau cho các persistence unit khác nhau.
  • Với JPA 1, mỗi nhà cung cấp định nghĩa tập các thuộc tính JDBC và nó đã rất khó khăn để quản lý chúng với các nhà cung cấp khác nhau trên khắp các đơn vị kiên trì khác nhau. JPA 2 loại bỏ vấn đề này bằng cách tiêu chuẩn hóa các tài sản. Đoạn mã sau đây cho thấy một mẫu persistence.xml tập tin định nghĩa các thuộc tính JDBC:
<persistence-unit name="JPAProject"
      transaction-type="RESOURCE_LOCAL">
  <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
  <!--Entity Classes -->
  <class>com.infosys.demo.Item</class>
  <class>com.infosys.demo.Employee</class>
  <properties>
 <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/JPA 2" />
    <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
    <property name="javax.persistence.jdbc.user" value="root" />
 <property name="javax.persistence.jdbc.password" value="infosys"/>
 <property name="javax.persistence.jdbc.show_sql" value="true" />
   </properties>
</persistence-unit>
  • Các <persistence-unit> chứa các thông tin về cấu hình Data Source. Các tên thuộc tính chỉ định tên mà Persistence Unit này được xác định, mà sẽ được cung cấp khi tạo ra các ví dụ EntityManagerFactory. Nó cũng có thể có các yếu tố phụ tùy chọn:
  • Các yếu tố cung cấp cho thấy đó thực hiện JPA nên được sử dụng. ObjectDB được đại diện bởi các com.objectdb.jpa.Provider chuỗi. Nếu không quy định, việc thực hiện JPA đầu tiên được tìm thấy đang được sử dụng.
  • Các yếu tố mapping-file chỉ định mapping-file XML được thêm vào mặc định META-INF / orm.xml mapping-file. Mỗi chú thích được mô tả trong sách hướng dẫn này có thể được thay thế bằng XML tương đương trong các mapping-file (như được giải thích dưới đây).
  • Các file jar yếu tố xác định tập tin JAR mà nên được tìm kiếm cho các lớp học persistable quản lý.
  • Các lớp yếu tố xác định tên của lớp persistable quản lý.
  • Các yếu tố property xác định tính chất chung. JPA 2 định nghĩa các thuộc tính tiêu chuẩn để xác định cơ sở dữ liệu địa chỉ, tên người dùng và mật khẩu, như trình bày ở trên.
  • Các Persistence Unit quy định các nhà cung cấp (EclipseLink thực hiện tham chiếu cho JPA) và các lớp thực thể khác nhau mà cần phải được quản lý trong persistence context. Nó cũng xác định các tính chất JDBC khác nhau như tên driver, URL cơ sở dữ liệu, tên người dùng, mật khẩu, ...
  • Persistence Context: kết hợp với quản lý entity, là một tập hợp các entity cho bất kỳ persistent identity

Hiện hành javax.persistence.EntityManagerFactory

protected void setUp() throws Exception {
    entityManagerFactory = Persistence.createEntityManagerFactory( "org.hibernate.tutorial.jpa" );
}
  • Các chức năng mở rông của Persistence Property, được phân loại theo chức năng:
  • Weaving 
  • Customizers 
  • Validation and Optimization 
  • Caching 
  • Mapping 
  • Schema generation 
  • JDBC configuration
  • Java Persistence Query Language (JPQL)
  • Các Java Persistence Query Language (JPQL) làm cho truy vấn đối với các đối tượng được lưu trữ trong một cơ sở dữ liệu quan hệ. Truy vấn giống SQL truy vấn trong cú pháp, nhưng hoạt động chống lại các đối tượng thực thể chứ không phải là trực tiếp với các bảng cơ sở dữ liệu.
  • Object/relational metadata
  • persistence entity là 1 lightweight Java class mà trạng thái thường được lưu vào 1 bảng trong CSDL quan hệ.
  • Các instance của 1 thực thể đó tương ứng với từng hàng trong bảng.
  • Các Entities thường có quan hệ với các Entities khác, và các mối quan hệ thường được thể hiện thông qua object/relational metadata.
  • Object/relational metadata có thể được chỉ định trực tiếp trong entity class bằng cách sử dụng các annotation , hoặc trong một file tập tin XML riêng biệt mô tả phân phối với các ứng dụng.
Một số các tương tác. Nhấn vào đây để phóng to mỗi ảnh.

Trong Java Persistence API, một entity có thể có truy cập field-based hoặc property-based. Trong việc tiếp cận field-based, cung cấp persistence truy cập trạng thái của entity trực tiếp thông qua các biến cá thể của nó. Trong truy cập property-based, nhà cung cấp persistence sử dụng JavaBeans kiểu get / phương pháp accessor thiết lập để truy cập tài sản persistent của đơn vị. Tất cả các trường và thuộc tính trong entity đang tồn tại. Tuy nhiên, ghi đè lên một lĩnh vực hoặc property's default persistence  bằng cách đánh dấu nó với các @Transient chú thích hoặc từ khóa Java transient.
Các Java Persistence API đơn giản hoá mô hình lập trình cho các thực thể kiên trì và thêm khả năng mà không có trong EJB 2.1. Dưới đây là danh sách những đơn giản hóa và bổ sung của nó:
  • Yêu cầu các lớp và các giao diện ít
  • Hầu như loại bỏ mô tả triển khai kéo dài qua các chú thích
  • Địa chỉ số kỹ thuật tiêu biểu nhất qua mặc định chú thích
  • Cung cấp bản đồ sạch hơn, dễ dàng hơn, tiêu chuẩn đối tượng quan hệ
  • Loại bỏ sự cần thiết cho mã tra cứu
  • Thêm hỗ trợ cho các thừa kế, đa hình, và các truy vấn đa hình.
  • Thêm hỗ trợ cho tên (tĩnh) và truy vấn động.
  • Cung cấp một ngôn ngữ truy vấn Java Persistence - một nâng cao EJB QL
  • Làm cho nó dễ dàng hơn để kiểm tra các đơn vị bên ngoài của EJB container
  • Có thể được sử dụng bên ngoài của container
  • Có thể được sử dụng với các nhà cung cấp bền bỉ của bên thứ ba pluggable
2. Serializable 
  • 1 cách để đại diện cho một đối tượng trong một hình thức nối tiếp cho phép nó được lưu trữ để phục hồi sau đó.
  • Một đối tượng có thể được biểu diễn như là một chuỗi các byte bao gồm dữ liệu của đối tượng cũng như thông tin về kiểu của đối tượng và các loại dữ liệu được lưu trữ trong đối tượng.
  • Hầu hết các lớp kiên trì dựa trên serialization đối tượng và deserialization và không quá nhiều cung cấp bãi nhị phân và khôi phục các đối tượng. 
  • Điều thú vị là hầu hết các nhà phát triển thấy việc thực hiện các quy trình của de /serialization như một nhiệm vụ khá nhàm chán trong khi phát triển một lớp persistent là hơn một phần quan tâm.
  • Mỗi lớp serializable (người dùng định hoặc hệ thống định nghĩa) cũng là persistable, nhưng dựa vào serialization trong persistable data có một nhược điểm nghiêm trọng trong việc thiếu tính di động. Các định dạng tuần tự hóa Java nội bộ sẽ không thể tiếp cận với các phiên bản furture của ObjectDB trên các nền tảng khác (ví dụ .NET). Do đó, nó được khuyến khích để chỉ sử dụng các loại persistable quy định một cách rõ ràng.
  • Có thể lưu đối tượng vào 1 file và đọc lại nó.
  • Để serializable, 1 class phải implement Serializable interface.

  • Một đối tượng serializable có thể chứa dữ liệu mà không serializable. Những dữ liệu này sẽ không được tuần tự và phải được gắn thẻ với các từ khóa transient.
  • Sử dụng serialization, bạn có thể lưu và lấy của bạn dữ liệu đảm bảo persistence của dữ liệu của bạn giữa chạy 2 ứng dụng
  • Class ObjectInputStream và ObjectOutputStream là dòng cao cấp có chứa các phương pháp serializing và deserializing một đối tượng.
Example: Saving an object


  • Các lớp ObjectOutputStream chứa nhiều phương pháp ghi để viết các kiểu dữ liệu khác nhau, nhưng một trong những phương pháp đặc biệt nổi bật
  • Các phương pháp writeObject chịu trách nhiệm cho việc viết các trạng thái của các đối tượng cho class đặc biệt của nó để các phương pháp readObject tương ứng có thể khôi phục lại nó. 
  • Các cơ chế mặc định để lưu các lĩnh vực của đối tượng có thể được gọi bằng cách gọi out.defaultWriteObject. Phương pháp này không cần phải quan tâm chính nó với trạng thái thuộc superclasses hoặc lớp con của nó. 
  • Trạng thái được lưu bằng cách viết các lĩnh vực cá nhân để ObjectOutputStream sử dụng phương pháp writeObject hoặc bằng cách sử dụng các phương pháp cho các kiểu dữ liệu nguyên thủy được hỗ trợ bởi DataOutput.
public final void writeObject(Object x) throws IOException
  • Các phương pháp trên serializes một đối tượng và gửi nó vào dòng đầu ra.Tương tự như vậy, các lớp ObjectInputStream chứa các phương pháp sau đây cho deserializing một đối tượng
  • Phương pháp readObject có trách nhiệm đọc từ dòng và khôi phục lại các classes field. Nó có thể gọi in.defaultReadObject để gọi các cơ chế mặc định cho việc khôi phục các field non-static và non-transient của đối tượng. 
  • Phương pháp defaultReadObject sử dụng thông tin trong dòng để phân định các field của đối tượng lưu trong luồng với các lĩnh vực tương ứng có tên trong các đối tượng hiện hành. 
public final Object readObject() throws IOException, ClassNotFoundException
  • Phương pháp này lấy đối tượng tiếp theo ra khỏi dòng và deserializes nó. Giá trị trả về là Object, vì vậy bạn sẽ cần phải bỏ nó vào kiểu dữ liệu thích hợp của nó.
  • Phương pháp readObjectNoData chịu trách nhiệm khởi tạo trạng thái của đối tượng cho class đặc biệt của nó trong sự kiện rằng các dòng serialization không liệt kê các lớp được coi là một lớp cha của đối tượng đang được deserialized.
  • Điều này có thể xảy ra trong trường hợp bên nhận sử dụng một phiên bản khác nhau của lớp  deserialized hơn là bên gửi, và phiên bản của người nhận mở rộng các class không được mở rộng bằng phiên bản của người gửi. 
  • Điều này cũng có thể xảy ra nếu dòng serialization đã bị giả mạo; do đó, readObjectNoData là hữu ích cho việc khởi đối tượng deserialized đúng mặc dù một dòng nguồn "hostile" hoặc incomplete source.
private void readObjectNoData() throws ObjectStreamException;

Example: Tôi sẽ sử dụng lớp Employee để thực hiện Serializable

public class Employee implements java.io.Serializable {
  
public String name;
  
public String address;
  
public transient int SSN;
  
public int number;
  
  
public void mailCheck() {
     
System.out.println("Mailing a check to " + name + " " + address);
  
}
}
Serializing 1 đối tượng

import java.io.*;
public class SerializeDemo {
public static void main(String [] args) {
     
Employee e = new Employee();
      e
.name = "Reyan Ali";
      e
.address = "Phokka Kuan, Ambehta Peer";
      e
.SSN = 11122333;
      e
.number = 101;
     
     
try {
        
FileOutputStream fileOut =
        
new FileOutputStream("/tmp/employee.ser");
        
ObjectOutputStream out = new ObjectOutputStream(fileOut);
        
out.writeObject(e);
        
out.close();
         fileOut
.close();
        
System.out.printf("Serialized data is saved in /tmp/employee.ser");
     
}catch(IOException i) {
         i
.printStackTrace();
     
}
  
}
}
Deserializing một đối tượng
import java.io.*;
public class DeserializeDemo {
public static void main(String [] args) {
     
Employee e = null;
     
try {
        
FileInputStream fileIn = new FileInputStream("/tmp/employee.ser");
        
ObjectInputStream in = new ObjectInputStream(fileIn);
         e
= (Employee) in.readObject();
        
in.close();
         fileIn
.close();
     
}catch(IOException i) {
         i
.printStackTrace();
        
return;
     
}catch(ClassNotFoundException c) {
        
System.out.println("Employee class not found");
         c
.printStackTrace();
        
return;
     
}
     
     
System.out.println("Deserialized Employee...");
     
System.out.println("Name: " + e.name);
     
System.out.println("Address: " + e.address);
     
System.out.println("SSN: " + e.SSN);
     
System.out.println("Number: " + e.number);
  
}
}
Output

Deserialized Employee...
Name: Reyan Ali
Address:Phokka Kuan, Ambehta Peer
SSN: 0
Number:101

Comments

Popular Posts