Spring Data JPA 註解(一)

文章摘抄 Hibernate 官網(https://docs.jboss.org/hibernate/jpa/2.2/api/javax/persistence/Embeddable.html),目錄及部分源碼參考w3c 官網(https://www.w3cschool.cn/java/jpa-entitymanager.html)。主要是在自己的整理過程中,發現w3c梳理的東西過於簡潔,實在讓我無法準確理解,於是我就拿着w3c的目錄來整理文檔,但是力求於相對的準確,也就懶得力求於百度,直接ctrl cv 了。

特別聲明:本人英文翻譯較菜,怕譯議後不恰,況且現在的google翻譯是真的牛逼,但是還是寫了一部分,僅僅爲了自己日後方便閱讀。

JPA 介紹

JPA 全稱爲 JAVA Persistence API ,JPA 吸取了目前Java 持久化技術的有點,旨在規範、簡化Java對象的持久化技術工作。使用JPA持久化對象,並不是依賴於某一個ORM框架

JPA 註解使用

Column

Specifies the mapped column for a persistent property or field. If no Column annotation is specified, the default values apply.

    //Example 1: 
    @Column(name="DESC", nullable=false, length=512)
    public String getDescription() { return description; }

    // Example 2: 
    // columnDefinition 定義字段的類型 ,且不能爲空(也可以設置默認值,如:columnDefinition = "BIT default 0")
    //table 包含列的表的名稱
    @Column(name="DESC",
            columnDefinition="CLOB NOT NULL",
            table="EMP_DETAIL")
    @Lob
    public String getDescription() { return description; }

    // Example 3:
    // precision 精度(字段長度), scale 範圍(小數位數)
    @Column(name="ORDER_COST", updatable=false, insertable=false, precision=12, scale=2)
    public BigDecimal getCost() { return cost; }

Transient

Specifies that the property or field is not persistent. It is used to annotate a property or field of an entity class, mapped superclass, or embeddable class.

Id 、 IdClass 、GeneratedValue、GenerationType

	//官方上介紹了很多生成策略,這裏附上mysql的基本用法
    @Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long id;
	
	//SEQUENCE:根據底層數據庫的序列來生成主鍵,條件是數據庫支持序列。 
	//IDENTITY:主鍵由數據庫自動生成(主要是自動增長型) (mysql 這種方式也常用,但是主要是數據庫底層去自增長,移植性較差)
	//AUTO:主鍵由程序控制。
  • @IdClass
    Specifies a composite primary key class that is mapped to multiple fields or properties of the entity.
    The names of the fields or properties in the primary key class and the primary key fields or properties of the entity must correspond and their types must be the same.
    組合主鍵類,映射到實體的多個字段,且類型一致
   @IdClass(com.acme.EmployeePK.class)
   @Entity
   public class Employee {
      @Id String empName;
      @Id Date birthDay;
      ...
   }

Lob 、Basic

  • @Lob
    Specifies that a persistent property or field should be persisted as a large object to a database-supported large object type.
    Portable applications should use the Lob annotation when mapping to a database Lob type. The Lob annotation may be used in conjunction with the Basic annotation or the ElementCollection annotation when the element collection value is of basic type. A Lob may be either a binary or character type.
    The Lob type is inferred from the type of the persistent field or property, and except for string and character-based types defaults to Blob.
    Lob可以是二進制或字符類型
    Lob類型是根據持久性字段或屬性的類型推斷的,除了字符串和基於字符的類型以外,默認爲Blob。
    String 類的默認值 爲 longtext
    byte[] Image File 默認值 爲 longblob
   //Example 1:

   @Lob @Basic(fetch=LAZY)
   @Column(name="REPORT")
   protected String report;

   // Example 2:

   @Lob @Basic(fetch=LAZY)
   @Column(name="EMP_PIC", columnDefinition="BLOB NOT NULL")
   protected byte[] pic;

  • @Basic
    The simplest type of mapping to a database column. The Basic annotation can be applied to a persistent property or instance variable of any of the following types: Java primitive types, wrappers of the primitive types, String, java.math.BigInteger, java.math.BigDecimal, java.util.Date, java.util.Calendar, java.sql.Date, java.sql.Time, java.sql.Timestamp, byte[], Byte[], char[], Character[], enums, and any other type that implements java.io.Serializable.
    The use of the Basic annotation is optional for persistent fields and properties of these types. If the Basic annotation is not specified for such a field or property, the default values of the Basic annotation will apply.
    一般結合Lob註解一起使用,大類型字段懶加載。
    @Basic 註解不使用,其實默認jpa也會添加該註解,並使用默認值
	//Example 1:

    @Basic
    protected String name;

    //Example 2:

    @Basic(fetch=LAZY) 
    protected String getName() { return name; }

OneToOne

Specifies a single-valued association to another entity that has one-to-one multiplicity. It is not normally necessary to specify the associated target entity explicitly since it can usually be inferred from the type of the object being referenced. If the relationship is bidirectional, the non-owning side must use the mappedBy element of the OneToOne annotation to specify the relationship field or property of the owning side.

The OneToOne annotation may be used within an embeddable class to specify a relationship from the embeddable class to an entity class. If the relationship is bidirectional and the entity containing the embeddable class is on the owning side of the relationship, the non-owning side must use the mappedBy element of the OneToOne annotation to specify the relationship field or property of the embeddable class. The dot (".") notation syntax must be used in the mappedBy element to indicate the relationship attribute within the embedded attribute. The value of each identifier used with the dot notation is the name of the respective embedded field or property.

    //Example 1: One-to-one association that maps a foreign key column
    
    // On Customer class:

	// 單項關聯(也就是第一段英文的前半句)
    @OneToOne(optional=false)
    @JoinColumn(
        name="CUSTREC_ID", unique=true, nullable=false, updatable=false)
    public CustomerRecord getCustomerRecord() { return customerRecord; }

    // On CustomerRecord class:
    // 雙向關聯(這裏解釋一下non-owning side ,我翻譯成非控制一方:CustomerRecord 中是存在 Customer 的ID 的,故CustomerRecord 是可以改變CustomerID,所以CustomerRecord 是控制一方,而 Customer 是非控制一方 或叫做被控制一方。)
    // 那麼 在控制一方 裏關聯的被控制一方上 需要有 mappedBy ,當然mappedBy 關聯的可以使對象類型也可以是基本數據類型
    @OneToOne(optional=false, mappedBy="customerRecord")
    public Customer getCustomer() { return customer; }


    //Example 2: One-to-one association that assumes both the source and target share the same primary key values. 
    
    // On Employee class:

    @Entity
    public class Employee {
        @Id Integer id;
    
        @OneToOne @MapsId
        EmployeeInfo info;
        ...
    }

    // On EmployeeInfo class:

    @Entity
    public class EmployeeInfo {
        @Id Integer id;
        ...
    }


    Example 3: One-to-one association from an embeddable class to another entity.

    @Entity
    public class Employee {
       @Id int id;
       @Embedded LocationDetails location;
       ...
    }

    @Embeddable
    public class LocationDetails {
       int officeNumber;
       @OneToOne ParkingSpot parkingSpot;
       ...
    }

    @Entity
    public class ParkingSpot {
       @Id int id;
       String garage;
       @OneToOne(mappedBy="location.parkingSpot") Employee assignedTo;
        ... 
    } 

Embeddable 、Embedded、EmbeddedId

  • @Embeddable
    Specifies a class whose instances are stored as an intrinsic part of an owning entity and share the identity of the entity
    Each of the persistent properties or fields of the embedded object is mapped to the database table for the entity
    @Embeddable 表示可嵌入的類
    Note that the Transient annotation may be used to designate the non-persistent state of an embeddable class.
    如果標記@Transient 註解,那麼它將不被持久化
    //Example 1:

    @Embeddable public class EmploymentPeriod { 
       @Temporal(DATE) java.util.Date startDate;
       @Temporal(DATE) java.util.Date endDate;
      ... 
    }

    //Example 2:

    @Embeddable public class PhoneNumber {
        protected String areaCode;
        protected String localNumber;
        @ManyToOne PhoneServiceProvider provider;
        ...
     }

    @Entity public class PhoneServiceProvider {
        @Id protected String name;
         ...
     }

    // Example 3:

    @Embeddable public class Address {
       protected String street;
       protected String city;
       protected String state;
       @Embedded protected Zipcode zipcode;
    }

    @Embeddable public class Zipcode {
       protected String zip;
       protected String plusFour;
     }
  • @Embedded
    Specifies a persistent field or property of an entity whose value is an instance of an embeddable class. The embeddable class must be annotated as Embeddable.

The AttributeOverride, AttributeOverrides, AssociationOverride, and AssociationOverrides annotations may be used to override mappings declared or defaulted by the embeddable class.

   //Example:

   @Embedded
   @AttributeOverrides({
       @AttributeOverride(name="startDate", column=@Column("EMP_START")),
       @AttributeOverride(name="endDate", column=@Column("EMP_END"))
   })
   public EmploymentPeriod getEmploymentPeriod() { ... }
 
  • @EmbeddedId
    Applied to a persistent field or property of an entity class or mapped superclass to denote a composite primary key that is an embeddable class. The embeddable class must be annotated as Embeddable.
    There must be only one EmbeddedId annotation and no Id annotation when the EmbeddedId annotation is used.
    作爲複合主鍵,且不允許再有@Id註解
    The AttributeOverride annotation may be used to override the column mappings declared within the embeddable class.
    The MapsId annotation may be used in conjunction with the EmbeddedId annotation to specify a derived primary key.
    If the entity has a derived primary key, the AttributeOverride annotation may only be used to override those attributes of the embedded id that do not correspond to the relationship to the parent entity.
    Relationship mappings defined within an embedded id class are not supported.
    //Example 1:

    @EmbeddedId
    protected EmployeePK empPK;


    //Example 2:

    @Embeddable
    public class DependentId {
       String name;
       EmployeeId empPK;   // corresponds to primary key type of Employee
    }

    @Entity
    public class Dependent {
       // default column name for "name" attribute is overridden
       @AttributeOverride(name="name", @Column(name="dep_name"))
       @EmbeddedId DependentId id;
       ...
       @MapsId("empPK")
       @ManyToOne Employee emp;
    }

MapsId

Designates a ManyToOne or OneToOne relationship attribute that provides the mapping for an EmbeddedId primary key, an attribute within an EmbeddedId primary key, or a simple primary key of the parent entity.
The value element specifies the attribute within a composite key to which the relationship attribute corresponds. If the entity’s primary key is of the same Java type as the primary key of the entity referenced by the relationship, the value attribute is not specified

    //Example:

    // parent entity has simple primary key

    @Entity
    public class Employee {
       @Id long empId;
       String name;
       ...
    } 

    // dependent entity uses EmbeddedId for composite key

    @Embeddable
    public class DependentId {
       String name;
       long empid;   // corresponds to primary key type of Employee
    }

    @Entity
    public class Dependent {
       @EmbeddedId DependentId id;
        ...
       @MapsId("empid")  //  maps the empid attribute of embedded id
       @ManyToOne Employee emp;
    }

OneToMany

If the collection is defined using generics(泛型集合) to specify the element type, the associated target entity type need not be specified; otherwise the target entity class must be specified. If the relationship is bidirectional, the mappedBy element must be used to specify the relationship field or property of the entity that is the owner of the relationship.

The OneToMany annotation may be used within an embeddable class contained within an entity class to specify a relationship to a collection of entities. If the relationship is bidirectional, the mappedBy element must be used to specify the relationship field or property of the entity that is the owner of the relationship. When the collection is a java.util.Map, the cascade element and the orphanRemoval element apply to the map value.

	// Example 1: One-to-Many association using generics

    // In Customer class:
	// 顧客相對於訂單,一對多的關係 
    @OneToMany(cascade=ALL, mappedBy="customer")
    public Set<Order> getOrders() { return orders; }

    // In Order class:

    @ManyToOne
    @JoinColumn(name="CUST_ID", nullable=false)
    public Customer getCustomer() { return customer; }


    // Example 2: One-to-Many association without using generics

    // In Customer class:

    @OneToMany(targetEntity=com.acme.Order.class, cascade=ALL,
                mappedBy="customer")
    public Set getOrders() { return orders; }

    // In Order class:

    @ManyToOne
    @JoinColumn(name="CUST_ID", nullable=false)
    public Customer getCustomer() { return customer; }


    // Example 3: Unidirectional One-to-Many association using a foreign key mapping (暫未用到過該用法)

    // In Customer class:

    @OneToMany(orphanRemoval=true)
    @JoinColumn(name="CUST_ID") // join column is in table for Order
    public Set<Order> getOrders() {return orders;}

ManyToMany

Specifies a many-valued association with many-to-many multiplicity.

Every many-to-many association has two sides, the owning side and the non-owning, or inverse, side. The join table is specified on the owning side. If the association is bidirectional, either side may be designated as the owning side. If the relationship is bidirectional, the non-owning side must use the mappedBy element of the ManyToMany annotation to specify the relationship field or property of the owning side.
the association,任何一方都可以被指定爲擁有方
the relationship,非擁有方要使用mappedBy

The ManyToMany annotation may be used within an embeddable class contained within an entity class to specify a relationship to a collection of entities. If the relationship is bidirectional and the entity containing the embeddable class is the owner of the relationship, the non-owning side must use the mappedBy element of the ManyToMany annotation to specify the relationship field or property of the embeddable class. The dot (".") notation syntax must be used in the mappedBy element to indicate the relationship attribute within the embedded attribute. The value of each identifier used with the dot notation is the name of the respective embedded field or property.

 	// Example 1:

    // In Customer class:

    @ManyToMany
    @JoinTable(name="CUST_PHONES")
    public Set<PhoneNumber> getPhones() { return phones; }

    // In PhoneNumber class:

    @ManyToMany(mappedBy="phones")
    public Set<Customer> getCustomers() { return customers; }

    Example 2:

    // In Customer class:

    @ManyToMany(targetEntity=com.acme.PhoneNumber.class)
    public Set getPhones() { return phones; }

    // In PhoneNumber class:

    @ManyToMany(targetEntity=com.acme.Customer.class, mappedBy="phones")
    public Set getCustomers() { return customers; }

    Example 3:

    // In Customer class:

    @ManyToMany
    @JoinTable(name="CUST_PHONE",
        joinColumns=
            @JoinColumn(name="CUST_ID", referencedColumnName="ID"),
        inverseJoinColumns=
            @JoinColumn(name="PHONE_ID", referencedColumnName="ID")
        )
    public Set<PhoneNumber> getPhones() { return phones; }

    // In PhoneNumberClass:

    @ManyToMany(mappedBy="phones")
    public Set<Customer> getCustomers() { return customers; }

JoinTable、JoinColumns、JoinColumn

  • @JoinTable
    Specifies the mapping of associations. It is applied to the owning side of an association.
    在擁有方一側註釋
    If the JoinTable annotation is missing, the default values of the annotation elements apply. The name of the join table is assumed to be the table names of the associated primary tables concatenated together (owning side first) using an underscore.
    sql 表如果是用下劃線連接的話,可以省略。
	//Example:

    @JoinTable(
        name="CUST_PHONE",
        joinColumns=
            @JoinColumn(name="CUST_ID", referencedColumnName="ID"),
        inverseJoinColumns=
            @JoinColumn(name="PHONE_ID", referencedColumnName="ID")
    )
  • @JoinColumn
    Specifies a column for joining an entity association or element collection. If the JoinColumn annotation itself is defaulted, a single join column is assumed and the default values apply.
    指定實體類或集合的 列
   //Example:

   @ManyToOne
   @JoinColumn(name="ADDR_ID")
   public Address getAddress() { return address; }


   Example: unidirectional one-to-many association using a foreign key mapping
 
   // In Customer class
   @OneToMany
   @JoinColumn(name="CUST_ID") // join column is in table for Order
   public Set<Order> getOrders() {return orders;}
發佈了56 篇原創文章 · 獲贊 6 · 訪問量 4919
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章