Hibernate 註解使用

Hibernate 註解使用

在Hibernate中一般配置對象關係映射關係有兩種,一種是基於xml的方式,另外一種是基於Hibernate Annotation庫的註解方式。在Hibernate 3.2版本和Java 5 環境下開始支持使用註解配置對象關係映射,使用Hibernate註解以後,可不用定義持久化類所對應的*.hbm.xml文件,直接用註解的方式寫入持久化類中實現html

兩種方法要注意的兩個不一樣處:
(1):hibernate.hbm.xml 文件中把引用:xxx.hbm.xml改成引用實體類:java

即把<mapping resource="com/wsw/hibernate/model/Person.hbm.xml"/>
改成:<mapping class="com.wsw.hibernate.model.Teacher" />數據庫

(2):獲取SessionFactory方式發生了變化:數組

即把SessionFactorysf=newConfiguration().configure().buildSessionFactory()
改成SessionFactory sf=new AnnotationConfiguration().configure().buildSessionFactory()app

經常使用的註解標籤

在屬性註解使用上,您既能夠保持字段的持久性(註解寫在成員變量之上),也能夠保持屬性(註解寫在getter方法之上)的持久性,但建議不要在屬性上引入註解,由於屬性是private的,若是引入註解會破壞其封裝特性,因此建議在getter方法上加入註解框架

@Entityfetch

將一個Javabean類聲明爲一個實體的數據庫表映射類,最好實現序列化。默認狀況下,全部的類屬性都爲映射到數據表的持久性字段。若在類中有屬性不映射到數據庫中的,要用下面的@Transient來註解。ui

*屬性:*
`name` - 可選,對應數據庫中的一個表。若表名與實體類名相同,則能夠省略。

@Table
在@Entity下使用,表示實體對應數據庫中的表的信息this

屬性:
name - 可選,表示表的名稱,默認表名和實體名稱一致,不一致的狀況下需指定表名。
catalog - 可選,表示Catalog名稱,默認爲 Catalog("")
schema - 可選 , 表示 Schema 名稱 , 默認爲Schema("").net

@Entity()
@Table(name="Student")
public class Student implements Serializable{
}

@Id

必須,定義了映射到數據庫表的主鍵的屬性,一個實體只能有一個屬性被映射爲主鍵

@GeneratedValue

定義自動增加的主鍵的生成策略.
屬性:
strategy - 表示主鍵生成策略,取值有如下

GenerationType.AUTO 根據底層數據庫自動選擇(默認),若數據庫支持自動增加>類型,則爲自動增加。
GenerationType.INDENTITY 根據數據庫的Identity字段生成,支持DB二、MySQL、MS、SQL Server、SyBase與HyperanoicSQL數據庫的Identity
GenerationType.SEQUENCE 使用Sequence來決定主鍵的取值,適合Oracle、DB2等支持Sequence的數據庫,通常結合@SequenceGenerator使用。(Oracle沒有自動增加類型,只能用Sequence)
GenerationType.TABLE 使用指定表來決定主鍵取值,結合@TableGenerator使用。
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY) 
private int sid;

GenerationType.TABLE的使用

@Id  
@GeneratedValue(strategy=GenerationType.TABLE,generator="strategyName")   
@TableGenerator(
    name = "strategyName",   // 主鍵生成策略的名稱,它被引用在@GeneratedValue中設置的「generator」值中
    table="",   //表示表生成策略所持久化的表名   
    catalog="",   //表所在的目錄名
    schema="",   //數據庫名
    pkColumnName="",   //在持久化表中,該主鍵生成策略所對應鍵值的名稱
    valueColumnName="",   //表示在持久化表中,該主鍵當前所生成的值,它的值將會隨着每次建立累加  
    pkColumnValue="",   //表示在持久化表中,該生成策略所對應的主鍵  
    allocationSize=1   //表示每次主鍵值增長的大小,例如設置成1,則表示每次建立新記錄後自動加1,默認爲50
)

GenerationType.SEQUENCE的使用

@Id  
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator="strategyName")   
@SequenceGenerator(
    name="strategyName", //name屬性表示該表主鍵生成策略的名稱,它被引用在@GeneratedValue中設置的「generator」值中
    sequenceName=""  //表示生成策略用到的數據庫序列名稱
)

更多基於註解的Hibernate主鍵生成策略介紹

@Transient

將忽略這些字段和屬性,不用持久化到數據庫。

@Column

可將屬性映射到列,使用該註解來覆蓋默認值
屬性:
name- 可選,表示數據庫表中該字段的名稱,默認情形屬性名稱一致

length - 可選,表示該字段的大小,僅對 String 類型的字段有效,默認值255.
insertable - 可選,表示在ORM框架執行插入操做時,該字段是否應出現INSETRT 語句中,默認爲 true
updateable - 可選,表示在ORM 框架執行更新操做時,該字段是否應該出如今 UPDATE 語句中,默認爲 true. 對於一經建立就不能夠更改的字段,該屬性很是有用,如對於 birthday 字段。
columnDefinition - 可選,表示該字段在數據庫中的實際類型。一般ORM 框架能夠根 據屬性類型自動判斷數據庫中字段的類型,可是對於Date 類型仍沒法肯定數據庫中字段類型到底是 DATE,TIME 仍是 TIMESTAMP. 此外 ,String 的默認映射類型爲 VARCHAR, 若是要將 String 類型映射到特定數據庫的 BLOB或 TEXT 字段類型,該屬性很是有用。

@Version

聲明添加對樂觀鎖定的支持

一些屬性

fetch

關聯關係獲取方式,便是否採用延時加載
Fetch.EAGER - 及時加載,是在查詢數據時,也直接一塊兒獲取關聯對象的數據。多對一默認是Fetch.EAGER
Fetch.LAZY -延遲加載,查詢數據時,不一塊兒查詢關聯對象的數據。而是當訪問關聯對象時才觸發相應的查詢操做,獲取關聯對象數據。一對多默認是Fetch.LAZY

cascade

設置級聯方式
CascadeType.PERSIST 保存
CascadeType.REMOVE - 刪除
CascadeType.MERGE 修改
CascadeType.REFRESH 刷新
CascadeType.ALL - 所有

mappedBy

mappedBy指的是多方對一方的依賴的屬性,(注意:若是沒有指定由誰來維護關聯關係,則系統會給咱們建立一張中間表)。
若是這個一對多的關係不是經過第三張表來維持,而是多方保存一方的id(多方外鍵引用一方),則必需要有mappedBy來指明多方中哪一個變量來保存一方(外鍵),值是多方里面保存一方的屬性名字
在判斷究竟是誰維護關聯關係時,能夠經過查看外鍵,哪一個實體類定義了外鍵,哪一個類就負責維護關聯關係
mappedBy至關於xml配置中的inverse="true"

一對多關聯

@OneToMany

描述一個一對多的關聯,該屬性應該爲集合類型 @OneToMany 默認會使用鏈接表作一對多關聯
若是這個一對多的關係不是經過第三張表來維持,而是多方保存一方的id(多方外鍵引用一方),則必需要有mappedBy來指明多方中哪一個變量來保存一方(外鍵),值是多方里面保存一方的屬性名字

@OneToMany(cascade={CascadeType.ALL},mappedBy="grade")
    public Set<Student> getStudents() {
        return students;
    }

多對一關聯

@ManyToOne

表示一個多對一的映射,該註解標註的屬性一般是數據庫表的外鍵。 單向多對一關聯在多方:
@ManyToOne(targetEntity=XXXX.class) //指定關聯對象
@JoinColumn(name="") //指定產生的外鍵字段名

雙向一對多同雙向多對一

在多方
@ManyToOne
@JoinColumn(name="本身的數據庫外鍵列名")
在一方
@OneToMany(mappedBy="多端的關聯屬性名")

/*
 * 學生類負責關聯關係
 */
@Entity
@Table(name="Student")
public class Student implements Serializable{
    private int sid;
    private String sex;
    private String name;
    private Grade grade;
    public Student() {
        
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Id
    @GenericGenerator(name="generator",strategy="native")
    @GeneratedValue(generator="generator")
    public int getId() {
        return sid;
    }
    public void setId(int id) {
        this.sid = id;
    }
    @Column(name="sex")
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    @ManyToOne(cascade={CascadeType.ALL})
    @JoinColumn(name="gid")
    public Grade getGrade() {
        return grade;
    }
    public void setGrade(Grade grade) {
        this.grade = grade;
    }
}
/*
 * 班級類
 */
@Entity
@Table(name="Grade")
public class Grade implements Serializable{
    private int gid;
    private String name;
    private Set<Student> students=new HashSet<Student>();
    public Grade() {
    }
    @Id
    @GenericGenerator(name="generator",strategy="native")
    @GeneratedValue(generator="generator")
    public int getGid() {
        return gid;
    }
    public void setGid(int gid) {
        this.gid = gid;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @OneToMany(cascade={CascadeType.ALL},mappedBy="grade")
    public Set<Student> getStudents() {
        return students;
    }
    public void setStudents(Set<Student> students) {
        this.students = students;
    }
}

多對多關聯

在多對多關聯中,雙方都採用@ManyToMany. 其中被維護方mappedBy表示由另外一多方維護
經過中間表由任一多方來維護關聯關係
其中主控方,不像一對多註解那樣,採用@joinColumn,而是採用@joinTable

@JoinTable(
     name="student_course",
     joinColumns={@JoinColumn(name="")},
     inverseJoinColumns={@JoinColumn(name="")}
)

由於多對多之間會經過一張中間表來維護兩表直接的關係,因此經過JoinTable 這個註解來聲明。
name就是指定了中間表的名字。
JoinColumns是一個@JoinColumn類型的數組,表示的是我這方在對方中的外鍵名稱,就是當前類的主鍵。
inverseJoinColumns也是一個@JoinColumn類型的數組,表示的是對方在我這方中的外鍵名稱,也能夠這樣想:上面提到mappedBy,至關於inverse="true".因此,在@joinTable中的inverseJoinColumns中定義的字段爲mappedBy所在類的主鍵。

在前面的基礎上增長課程類並補充學生類

/*
 * 學生類負責關聯關係
 */
@Entity
@Table(name="Student")
public class Student implements Serializable{
    private int sid;
    private String name;
    private String sex;
    private Grade grade;
    private Set<Course> courses=new HashSet<Course>();
    public Student() {
        
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Id
    @GenericGenerator(name="generator",strategy="native")
    @GeneratedValue(generator="generator")
    public int getId() {
        return sid;
    }
    public void setId(int id) {
        this.sid = id;
    }
    @Column(name="sex")
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    @ManyToOne(cascade={CascadeType.ALL})
    @JoinColumn(name="gid")
    public Grade getGrade() {
        return grade;
    }
    public void setGrade(Grade grade) {
        this.grade = grade;
    }
    @ManyToMany(cascade={CascadeType.ALL},fetch=FetchType.EAGER)
    @JoinTable(name="student_course",joinColumns={@JoinColumn(name="sid")},inverseJoinColumns={@JoinColumn(name="cid")})
    public Set<Course> getCourses() {
        return courses;
    }
    public void setCourses(Set<Course> courses) {
        this.courses = courses;
    }
}
@Entity
@Table(name="Course")
public class Course implements Serializable{

    private int cid;
    private String cName;
    private Set<Student> students=new HashSet<Student>();
    public Course() {
    }
    @Id
    @GenericGenerator(name="generator",strategy="native")
    @GeneratedValue(generator="generator")
    public int getCid() {
        return cid;
    }
    public void setStudents(Set<Student> students) {
        this.students = students;
    }
    public void setCid(int cid) {
        this.cid = cid;
    }
    public String getcName() {
        return cName;
    }
    public void setcName(String cName) {
        this.cName = cName;
    }
    @ManyToMany(cascade={CascadeType.ALL},fetch=FetchType.LAZY ,mappedBy="courses") 
    public Set<Student> getStudents() {
        return students;
    }
}
相關文章
相關標籤/搜索