import java.io.Serializable; import java.security.acl.Group; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.Lob; import javax.persistence.ManyToMany; import javax.persistence.OneToOne; import javax.persistence.OrderBy; import javax.persistence.SequenceGenerator; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; import javax.persistence.Transient; import javax.xml.registry.infomodel.User; /** * 核心提示:JPA 注解的幾個要點 1.設置Pojo為實體 @Entity //標識這個pojo是一個jpa實體 public class Users implements Serializable{ } 2.設置表名 @Entity @Table (name= users ) //指定表名為users public class Users implements Serializable{ } 3.設置主鍵 public JPA 注解的幾個要點 */ //2.設置表名 @Entity //@Entity 標識這個pojo是一個jpa實體 @Table(name = "users") //指定表名為users public class test implements Serializable { /** * */ private static final long serialVersionUID = 1L; } //3.設置主鍵 public class Users implements Serializable { @Id private String userCode; //4.主鍵生成策略 public class Users implements Serializable { @Id @GeneratedValue(strategy=GenerationType.IDENTITY)//主鍵自增,注意,這種方式依賴於具體的數據庫,如果數據庫不支持自增主鍵,那么這個類型是沒法用的 @Column(name = "user_id", nullable = false) private int userId; public class Users implements Serializable { @Id @GeneratedValue(strategy=GenerationType.TABLE)//通過一個表來實現主鍵id的自增,這種方式不依賴於具體的數據庫,可以解決數據遷移的問題,但是還要設置table的其他屬性。關於這個可以看本BLOG的前幾篇日志。有關於TABLE的設置 @Column(name = "user_code", nullable = false) private String userCode; public class Users implements Serializable { @Id @GeneratedValue(strategy=GenerationType.SEQUENCE)//通過Sequence來實現表主鍵自增,這種方式依賴於數據庫是否有SEQUENCE,如果沒有就不能用 @SequenceGenerator(name="seq_user") @Column(name = "user_id", nullable = false) private int userId; /** * 設置自動識別數據庫選擇是用sequence方式還是identity方式。我一般都是選擇這個方式。 * nullable與name選項一般都不用設置。nullable 是否可以為空,name如果不設置默認是字段名稱 */ public class Users{ @Id @GeneratedValue(strategy=GenerationType.AUTO) private int id; /*** * 5. 設置字段類型 通過@Column注解設置,包含的設置如下 .name:字段名 如果不設置默認則是字段名 .unique:是否唯一 .nullable:是否可以為空 .inserttable:是否可以插入 .updateable:是否可以更新 .columnDefinition: 定義建表時創建此列的DDL .secondaryTable: 從表名。如果此列不建在主表上(默認建在主表),該屬性定義該列所在從表的名字。 下面是JAVAEE 1.5的API 文檔說明 可以看一下 String columnDefinition The SQL fragment that is used when generating the DDL for the column. boolean insertable Whether the column is included in SQL INSERT statements generated by the persistence provider. int length The column length. String name The name of the column. boolean nullable Whether the database column is nullable. int precision The precision for a decimal (exact numeric) column. int scale The scale for a decimal (exact numeric) column. String table The name of the table that contains the column. boolean unique Whether the property is a unique key. boolean updatable Whether the column is included in SQL UPDATE statements generated by the persistence provider. */ @Column(name = "user_code", nullable = false, length=32)//設置屬性userCode對應的字段為user_code,長度為32,非空 private String userCode; @Column(name = "user_wages", nullable = true, precision=12, scale=2)//設置屬性wages對應的字段為user_wages,12位數字可保留兩位小數,可以為空 private double wages; /** * 注解時間類型要用@Temporal,通過設置@Temporal的value來設置注解時間的類型 * @Temporal的value一共有三種,分別是: * TemporalType.DATE map as java.sql.Date 日期型 精確到日 EG:2008-08-08 * TemporalType.TIME map as java.sql.Time 時間型 精確到秒 EG:20:00:00 * TemporalType.TIMESTAMP map as java.sql.Timestamp 時間型 精確到納秒 EG:2008-08-08 20:00:00.000000001 * 所以根據自己不同的需求來設置TemporalType的值 */ @Temporal(TemporalType.DATE)//設置為時間類型 private Date joinDate; /** API:An orderby_list, specified as follows: orderby_list::= orderby_item [,orderby_item]* orderby_item::= property_or_field_name [ASC | DESC] If ASC or DESC is not specified, ASC (ascending order) is assumed. * 6.字段排序 在加載數據的時候可以為其指定順序,使用@OrderBy注解實現 這個個人感覺用的還是比較少的。所以就沒深入。如果有人用的比較好。希望補充 */ @Table(name = "USERS") public class User { @OrderBy(name = "group_name ASC, name DESC") private List books = new ArrayList(); } /** * ManyToOne API: * CascadeType[] cascade The operations that must be cascaded to the target of the association. FetchType fetch Whether the association should be lazily loaded or must be eagerly fetched. boolean optional Whether the association is optional. Class targetEntity The entity class that is the target of the association. * 一對多映射關系 * 有Group和User兩個表。先是來映射一對多。GROUP是一,User是多。一個組里面可以包含多個用戶。但是一個用戶只能屬於一個組。 * 為了方便。其他屬性就簡單映射了 */ /** * @ManyToOne 默認情況下,JPA 為指向具有多對一多重性的其他實體類的單值關聯自動定義一個 ManyToOne 映射。 使用 @ManyToOne 批注: 140 將獲取類型配置為 LAZY 141 如果空值不適合於應用程序,則將映射配置為禁止空值(針對非基元類型) 142 配置關聯的目標實體(如果無法從被引用的對象類型推斷出它) 143 配置必須層疊到關聯目標的操作:例如,如果刪除了擁有實體,則確保還刪除關聯的目標 cascade 默認值: CascadeType 的空數組。 默認情況下,JPA 不會將任何持續性操作層疊到關聯的目標。 如果希望某些或所有持續性操作層疊到關聯的目標,請將 cascade 設置為一個或多個 CascadeType 實例,其中包括: 143 ALL —針對擁有實體執行的任何持續性操作均層疊到關聯的目標。 143 MERGE —如果合並了擁有實體,則將 merge層疊到關聯的目標。 143 PERSIST —如果持久保存擁有實體,則將 persist層疊到關聯的目標。 143 REFRESH —如果刷新了擁有實體,則 refresh為關聯的層疊目標。 143 REMOVE —如果刪除了擁有實體,則還刪除關聯的目標。 fetch 默認值: FetchType.EAGER。 默認情況下,JPA 持續性提供程序使用獲取類型 EAGER:這將要求持續性提供程序運行時必須迫切獲取數據。 如果這不適合於應用程序或特定的持久字段,請將 fetch 設置為FetchType.LAZY:這將提示持續性提供程序在首次訪問數據(如果可以)時應不急於獲取數據。 optional 默認值: true。 默認情況下,JPA 持續性提供程序假設所有(非基元)字段和屬性的值可以為空。 如果這並不適合於您的應用程序,請將 optional 設置為 false。 targetEntity 默認值:JPA 持續性提供程序從被引用的對象類型推斷出關聯的目標實體 如果持續性提供程序無法推斷出目標實體的類型,則將關聯擁有方上的targetEntity 元素設置為作為關系目標的實體的 Class。 * @author bacoo * */ /**One to Many * cascade 默認值: CascadeType 的空數組。 默認情況下,JPA 不會將任何持續性操作層疊到關聯的目標。 如果希望某些或所有持續性操作層疊到關聯的目標,請將 cascade 設置為一個或多個 CascadeType 實例,其中包括: 161 ALL - 針對擁有實體執行的任何持續性操作均層疊到關聯的目標。 161 MERGE - 如果合並了擁有實體,則將 merge 層疊到關聯的目標。 161 PERSIST - 如果持久保存擁有實體,則將 persist 層疊到關聯的目標。 161 REFRESH - 如果刷新了擁有實體,則 refresh 為關聯的層疊目標。 161 REMOVE - 如果刪除了擁有實體,則還刪除關聯的目標。 fetch 默認值: FetchType.EAGER。 默認情況下,JPA 持續性提供程序使用獲取類型 EAGER:它要求持續性提供程序運行時必須急性獲取數據。 如果這不適合於應用程序或特定的持久字段,請將 fetch 設置為FetchType.LAZY:它提示持續性提供程序在首次訪問數據(如果可以)時應惰性獲取數據。 mappedBy 默認值:如果關系是單向的,則該持續性提供程序確定擁有該關系的字段。 如果關系是雙向的,則將關聯相反(非擁有)方上的 mappedBy 元素設置為擁有此關系的字段或屬性的名稱()。 targetEntity 默認值:使用一般參數定義的 Collection 的參數化類型。 默認情況下,如果使用通過一般參數定義的 Collection,則持續性提供程序從被引用的對象類型推斷出關聯的目標實體。 如果 Collection 不使用一般參數,則必須指定作為關聯目標的實體類:將關聯擁有方上的 targetEntity 元素設置為作為關系目標的實體的 Class。 */ public class Group { @Id @GeneratedValue(strategy=GenerationType.AUTO) private Integer id; @Column private String groupName; @OneToMany(mappedBy="group")//fetch及cascade都有默認值,如果不需要設置,可以不寫 private List<User> users; } public class User { @Id @GeneratedValue(strategy=GenerationType.AUTO) private Integer id; @Column private String userName; @Temporal(TemporalType.DATE) private Date birthday; @ManyToOne @JoinColumn(name="groupId") private Group group; } /** * 一對一映射關聯 cascade 默認值:空 CascadeType 數組。 默認情況下,JPA 不會將任何持續性操作層疊到關聯的目標。 如果希望某些或所有持續性操作層疊到關聯的目標,請將 cascade 設置為一個或多個 CascadeType 實例,其中包括: 165 ALL - 針對擁有實體執行的任何持續性操作均層疊到關聯的目標。 165 MERGE - 如果合並了擁有實體,則將 merge 層疊到關聯的目標。 165 PERSIST - 如果持久保存擁有實體,則將 persist 層疊到關聯的目標。 165 REFRESH - 如果刷新了擁有實體,則 refresh 為關聯的層疊目標。 165 REMOVE - 如果刪除了擁有實體,則還刪除關聯的目標。 fetch 默認值: FetchType.EAGER。 默認情況下,JPA 持續性提供程序使用獲取類型 EAGER:它要求持續性提供程序運行時必須急性獲取數據。 如果這不適合於應用程序或特定的持久字段,請將 fetch 設置為FetchType.LAZY:它提示持續性提供程序在首次訪問數據(如果可以)時應惰性獲取數據。 mappedBy 默認值:JPA 持續性提供程序從被引用的對象類型推斷出關聯的目標實體 如果持續性提供程序無法推斷關聯的目標實體,則將關聯的相反(非擁有)方上的mappedBy 元素設置為擁有此關系的字段或屬性的 String 名稱(如 示例 1-64)所示。 optional 默認值: true。 默認情況下,JPA 持續性提供程序假設所有(非基元)字段和屬性的值可以為空。 如果這並不適合於您的應用程序,請將 optional 設置為 false。 targetEntity 默認值:JPA 持續性提供程序從被引用的對象類型推斷出關聯的目標實體 如果持續性提供程序無法推斷出目標實體的類型,則將關聯的擁有方上的targetEntity 元素設置為作為關系目標的實體的 Class。 */ @Entity @Table(name = "T_ONEA") public class OneA implements Serializable { private static final long serialVersionUID = 1L; @Id @Column(name = "ONEA_ID", nullable = false) private String oneaId; @Column(name = "DESCRIPTION") private String description; @OneToOne(cascade = CascadeType.ALL)//主Pojo這方的設置比較簡單,只要設置好級聯就可以了。 private OneB oneB; @Entity @Table(name = "T_ONEB") public class OneB implements Serializable { private static final long serialVersionUID = 1L; @Id @Column(name = "ONEA_ID", nullable = false) private String oneaId; @Column(name = "DESCRIPTION") private String description; @JoinColumn(name = "ONEA_ID", referencedColumnName = "ONEA_ID", insertable = false, updatable = false)//設置從方指向主方的關聯外鍵,這個ONEA_ID其實是表T_ONEA的主鍵 @OneToOne(mappedBy="oneB") private OneA oneA; // 大字段 @Lob //對應Blob字段類型 @Column(name = "PHOTO") private Serializable photo; @Lob //對應Clob字段類型 @Column(name = "DESCRIPTION") private String description; /** * 瞬時字段 不需要與數據庫映射的字段,在保存的時候不需要保存倒數據庫 */ @Transient private int tempValue; public int getTempValue(){ get tempValue; } public void setTempValue(int value){ this.tempValue = value; }