JPA注解持久化類(lèi)很方便,需要jar包:ejb3-persistence.jar。我用以下三個(gè)類(lèi)來(lái)說(shuō)明用法。
sh原創(chuàng ) 轉載請注明:
http://67566894.javaeye.com/blog/659829 - @SuppressWarnings("serial")
- @Entity
- @Table(name="T_X")
- public class X implements Serializable
- {
- @Id
- @GeneratedValue(strategy = GenerationType.AUTO)
- private int id;
-
- @Column(length=32)
- private String name;
-
- @Transient
- private String temp;
-
- @Temporal(TemporalType.TIMESTAMP)
- private Date date;
-
- @OneToOne(cascade = CascadeType.ALL, mappedBy = "x")
- private A a;
- }
- @SuppressWarnings("serial")
- @Entity
- @Table(name="T_A")
- public class A implements Serializable
- {
- @Id
- @GeneratedValue(strategy = GenerationType.AUTO)
- private int id;
-
- @OneToMany(cascade = CascadeType.ALL, mappedBy = "a", fetch = FetchType.EAGER)
- private List<B> b = new ArrayList<B>();
-
- @OneToOne()
- @JoinColumn(name = "x_Id")
- private X x;
- }
-
- @SuppressWarnings("serial")
- @Entity
- public class B implements Serializable{
- @Id
- @GeneratedValue(strategy = GenerationType.AUTO)
- protected int id;
-
- @ManyToOne()
- @JoinColumn(name = "a_id")
- protected A a;
- }
@SuppressWarnings("serial")@Entity@Table(name="T_X")public class X implements Serializable{@Id@GeneratedValue(strategy = GenerationType.AUTO)private int id;@Column(length=32)private String name;@Transient //表示此數據不在數據庫表里建立屬性private String temp;@Temporal(TemporalType.TIMESTAMP) //這個(gè)是帶時(shí)分秒的類(lèi)型private Date date;@OneToOne(cascade = CascadeType.ALL, mappedBy = "x")private A a;}@SuppressWarnings("serial")@Entity@Table(name="T_A")public class A implements Serializable{@Id@GeneratedValue(strategy = GenerationType.AUTO)private int id;@OneToMany(cascade = CascadeType.ALL, mappedBy = "a", fetch = FetchType.EAGER)private List<B> b = new ArrayList<B>();@OneToOne()@JoinColumn(name = "x_Id") //加這句后就會(huì )雙方共同維護關(guān)系private X x;}@SuppressWarnings("serial")@Entitypublic class B implements Serializable{@Id@GeneratedValue(strategy = GenerationType.AUTO)protected int id;@ManyToOne()@JoinColumn(name = "a_id")protected A a;}要注意的是:fetch = FetchType.EAGER這句話(huà)在一個(gè)類(lèi)里面只能出現一次,出現兩次就會(huì )報錯“cannot simultaneously fetch multiple bags”,要把其他的改為fetch = FetchType.LAZY延遲加載就可以了。聽(tīng)說(shuō)把List集合改為Set也能解決這個(gè)錯誤。
其他要點(diǎn):
1、@Table(name="T_X")這句話(huà)可以不寫(xiě),不寫(xiě)就已類(lèi)名作為表名
2、如果想讓兩個(gè)類(lèi)的屬性生成一個(gè)數據表,在一個(gè)類(lèi)里這樣加入另一個(gè)類(lèi)即可: @Embedded
private C c;
3、如果想要一個(gè)類(lèi)繼承另一個(gè)類(lèi)的所有屬性,則在父類(lèi)里這樣寫(xiě):
@SuppressWarnings("serial")
@Entity
@MappedSuperclass //增加這一行
并把父類(lèi)的所有屬性的private改為protected即可
4、建議在一對多關(guān)聯(lián)中在"一"方用延遲加載"多"方可以在HQL中顯式的"迫切左外連接" left join fetch 這樣做Hibernate可以少訪(fǎng)問(wèn)數據庫,也可以用"@BatchSize(size = 5)"來(lái)減少訪(fǎng)問(wèn)數據庫的次數
1. @Id 聲明屬性為主鍵
2. @GeneratedValue表示主鍵是自動(dòng)生成策略,一般該注釋和 @Id 一起使用
3. @Entity 任何 hibernte 映射對象都要有次注釋
4. @Table(name = “tablename”) 類(lèi)聲明此對象映射到哪個(gè)表
5. @Column(name = “Name”,nullable=false,length=32) 聲明數據 庫字段和類(lèi)屬性對應關(guān)系
6. @Lob 聲明字段為 Clob 或 Blob 類(lèi)型
7. @OneToMany(mappedBy=”order”,cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@OrderBy(value = “id ASC”)
一對多聲明,和 ORM 產(chǎn)品聲明類(lèi)似,一看就明白了。
@ManyToOne(cascade=CascadeType.REFRESH,optional=false)
@JoinColumn(name = “order_id”)
聲明為雙向關(guān)聯(lián)
8. @Temporal(value=TemporalType.DATE) 做日期類(lèi)型轉換。
9. @OneToOne(optional= true,cascade = CascadeType.ALL, mappedBy = “person”)
一對一關(guān)聯(lián)聲明
@OneToOne(optional = false, cascade = CascadeType.REFRESH)
@JoinColumn(name = “Person_ID”, referencedColumnName = “personid”,unique = true)
聲明為雙向關(guān)聯(lián)
10. @ManyToMany(mappedBy= “students”)
多對多關(guān)聯(lián)聲明。
@ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
@JoinTable(name = “Teacher_Student”,
joinColumns = {@JoinColumn(name = “Teacher_ID”, referencedColumnName = “teacherid”)},
inverseJoinColumns = {@JoinColumn(name = “Student_ID”, referencedColumnName =
“studentid”)})
多對多關(guān)聯(lián)一般都有個(gè)關(guān)聯(lián)表,是這樣聲明的!
11. @Transiten表示此屬性與表沒(méi)有映射關(guān)系,是一個(gè)暫時(shí)的屬性
12. @Cache(usage= CacheConcurrencyStrategy.READ_WRITE)表示此對象應用緩存
JPA規范 @Entity:通過(guò)@Entity注解將一個(gè)類(lèi)聲明為一個(gè)實(shí)體bean
@Table:通過(guò) @Table注解可以為實(shí)體bean映射指定表,name屬性表示實(shí)體所對應表的名稱(chēng),如果沒(méi)有定義 @Table,那么系統自動(dòng)使用默認值:實(shí)體的類(lèi)名(不帶包名)
@Id:用于標記屬性的主鍵
@Column:表示持久化屬性所映射表中的字段,如果屬性名與表中的字段名相同,則可以省略@Column注解,另外有兩種方式標記,一是放在屬性前,另一種是放在getter方法前,例如:
@Column(name = "EMPLOYEE_NAME")
private String employee_name; 或者
@Column(name = "EMPLOYEE_NAME")
public String getEmployee_name() {
return employee_name;
} 這兩種方式都是正解的,根據個(gè)人喜好來(lái)選擇。大象偏向于第二種,并且喜歡將屬性名與字段名設成一樣的,這樣可以省掉@Column注解,使代碼更簡(jiǎn)潔。
@Temporal(TemporalType.DATE):如果屬性是時(shí)間類(lèi)型,因為數據表對時(shí)間類(lèi)型有更嚴格的劃分,所以必須指定具體時(shí)間類(lèi)型,如④所示。在javax.persistence.TemporalType枚舉中定義了3種時(shí)間類(lèi)型:
通過(guò) @Temporal 定義映射到數據庫的時(shí)間精度:
@Temporal(TemporalType.DATE) 日期
@Temporal(TemporalType.TIME) 時(shí)間
@Temporal(TemporalType.TIMESTAMP) 兩者兼具
@Temporal只是起映射作為
@Transient
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface Transient {}
指明一個(gè)屬性或方法不能持久化
@TableGenerator:表生成器,將當前主鍵的值單獨保存到一個(gè)數據庫表中,主鍵的值每次都是從指定的表中查詢(xún)來(lái)獲得,這種生成主鍵的方式是很常用的。這種方法生成主鍵的策略可以適用于任何數據庫,不必擔心不同數據庫不兼容造成的問(wèn)題。大象推薦這種方式管理主鍵,很方便,集中式管理表的主鍵,而且更換數據庫不會(huì )造成很大的問(wèn)題。各屬性含義如下:
name:表示該表主鍵生成策略的名稱(chēng),這個(gè)名字可以自定義,它被引用在@GeneratedValue中設置的"generator"值中
table:表示表生成策略所持久化的表名,說(shuō)簡(jiǎn)單點(diǎn)就是一個(gè)管理其它表主鍵的表,本例中,這個(gè)表名為GENERATOR_TABLE
pkColumnName:表生成器中的列名,用來(lái)存放其它表的主鍵鍵名,這個(gè)列名是與表中的字段對應的
pkColumnValue:實(shí)體表所對應到生成器表中的主鍵名,這個(gè)鍵名是可以自定義滴
valueColumnName:表生成器中的列名,實(shí)體表主鍵的下一個(gè)值,假設EMPLOYEE表中的EMPLOYEE_ID最大為2,那么此時(shí),生成器表中與實(shí)體表主鍵對應的鍵名值則為3
allocationSize:表示每次主鍵值增加的大小,例如設置成1,則表示每次創(chuàng )建新記錄后自動(dòng)加1,默認為50
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface OneToMany {
String targetEntity() default "";
CascadeType[] cascade() default {};
FetchType fetch() default LAZY;
String mappedBy() default "";
}
String targetEntity (Optional) The fully qualified class name of
the entity class that is the target of the association.
Optional only if the Collection property
is defined using Java generics. Must be
specified otherwise.
The parameter type of the
Collection when defined
using generics(Generics泛型), 如果使用泛型,就可省略指明targetEntity
CascadeType[] cascade (Optional) The operations that should be cascaded
to the target of the association
No operations are cascaded
FetchType fetch (Optional) Whether the association should be
lazy loaded or eagerly fetched.
FetchType.LAZY 默認為延遲加載
String mappedBy (Optional) The field that owns the relationship
指多的一方關(guān)聯(lián)的屬性名
mappedBy指定的是不需要維護關(guān)系的一端 ??
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface ManyToOne {
String targetEntity() default "";
CascadeType[] cascade() default {};
FetchType fetch() default EAGER;
boolean optional() default true;
}
targetEntity (Optional) The fully qualified class name of the entity class that is the target of the associationThe type of the property that stores the association
是指一方的實(shí)體類(lèi)型的class ,默認的就是這個(gè)屬性的類(lèi)型。其實(shí)有些可以省略掉
CascadeType[] cascade (Optional) The operations that should be cascaded
to the target of the association No operations are cascaded
FetchType fetch (Optional) Whether the association should be
lazy loaded or eagerly fetched. FetchType.EAGER 默認為主動(dòng)加載
boolean optional (Optional) Whether the association is optional.
If set to false then a non-null relationship must always exist.
true
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface OneToOne {
String targetEntity() default "";
CascadeType[] cascade() default {};
FetchType fetch() default EAGER;
boolean optional() default true;
String mappedBy() default "";
boolean usePKasFK() default false;
}
The JoinColumn annotation is used to specify a mapped column for joining an entity association or a
secondary table.
@Target({TYPE, METHOD, FIELD}) @Retention(RUNTIME)
public @interface JoinColumn {
String name() default "";
String referencedColumnName() default "";
boolean primaryKey() default false;
boolean unique() default false;
boolean nullable() default true;
boolean insertable() default true;
boolean updatable() default true;
String columnDefinition() default "";
String secondaryTable() default "";
}
@Target({METHOD, FIELD}) @Retention(RUNTIME)
public @interface ManyToMany {
String targetEntity() default "";
CascadeType[] cascade() default {};
FetchType fetch() default LAZY;
String mappedBy() default "";
}