Hibernate註解開發

1. PO(簡單)類註解配置
    在hibernate中咱們使用註解,能夠幫助咱們簡化hbm文件配置。
    導入的包是javax.persisitance 
    
    @Entity                //定義一個實體
    @Table                //來描述類與表對應
    @Id                      //來聲明一個主鍵
    @JoinCoulumn(name = "外鍵") //用於指定外鍵類(在外鍵所在的類中配置)
    @JoinTable來描述中間表,並在中間表中描述外鍵分別與兩個多表的映射關係
    @GenerateValue  //用它來聲明一個主鍵生成策略
        默認狀況下至關於native
    能夠選擇的主鍵生成策略 AUTO IDENTITY SEQUENCE
    @Column         //來定義列
    注意:對於PO類中全部屬性,若是你不寫註解,默認狀況下也會在表中生成對應的列。
    列的名稱就是屬性的名稱
    @Temporal來聲明日期類型
        能夠選擇
        TemporalType.DATA   只有年月日  
        TemporalType.TIME   只有小時分鐘秒
        TemporalType.TIMESTAMP 有年月日小時分鐘秒
        咱們最終須要在hibernate.cfg.xml文件中將咱們類中的註解配置引用生效
package com.itheima.domain;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@Entity   //聲明一個實體
//描述與表對應
@Table(name = "t_book",catalog = "hibernateTest")
public class Book {
    @Id   //主鍵
    //聲明主鍵生成策略,不寫默認是native
    @GeneratedValue(strategy=GenerationType.IDENTITY)  //identity
    private Integer id;
    
    //聲明列。name 對應數據庫的列名,length 長度,nullable 是否爲空
    @Column(name = "name",length=30,nullable =  true)
    private String name;
    
    //聲明時間類型
    @Temporal(TemporalType.TIMESTAMP) //既有日期又有時分秒
    private Date publicactionDate;
 
    private Double price; //由於聲明瞭@Entity 實體,因此這裏價格就算不加註解們也會生成進表中,值都爲默認值
    
    public Double getPrice() {
         return price;
    }
    public void setPrice(Double price) {
         this.price = price;
    }
    public Integer getId() {
         return id;
    }
    public void setId(Integer id) {
         this.id = id;
    }
    public String getName() {
         return name;
    }
    public void setName(String name) {
         this.name = name;
    }
    public Date getPublicactionDate() {
         return publicactionDate;
    }
    public void setPublicactionDate(Date  publicactionDate) {
         this.publicactionDate = publicactionDate;
    }
}
 
 
在實體類中使用註解聲明後,還須要在hibernate.cfg.xml底下配置
<mapping class = "實體類的全類名">
編寫測試類進行保存測試
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.itheima.domain.Book;
import com.itheima.utils.HibernateUtils;
public class HibernateAnnotionTest {
    @Test
    public void test1(){
         Session session =  HibernateUtils.openSession();
         Transaction transaction =  session.beginTransaction();
         
         Book book = new Book();
         book.setName("一言不合學java");
         book.setPrice(998d);
         book.setPublicactionDate(new Date());
         
         session.save(book);
         
         
         transaction.commit();
         session.close();
         
         
    }
}
 
問題:1.若是咱們主鍵生成策略想使用UUID類型?
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;
import org.hibernate.annotations.GenericGenerator;
@Entity
@Table(catalog = "hibernateTest")
public class Person {
    
    //問題一:問題:1.若是咱們主鍵生成策略想使用UUID類型?
    @Id
    //主鍵成策略擴展的標籤
    @GenericGenerator(name =  "myuuid",strategy="uuid")
    @GeneratedValue(generator="myuuid")
    private String id ;
    
    //問題二:問題2:若是設定類的屬性不在表中映射?
    //使用@Transient
    @Transient
    private String msg;
}
 
對於咱們以上講解的關於屬性配置的註解,咱們也能夠在其對應的getXxx方法去使用
 
 

一對多(多對一)

@OneToMany
@ManyToOne
以Customer與Order爲例
 
Customer類
 
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
 
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
 
//客戶的實體類  ------- 一的一方
@Entity
@Table(name = "t_customer",catalog = "hibernateTest")
public class Customer {
    @Id
    private Integer id ; //主鍵
    
    private String name ; //姓名
    
    // 描述客戶能夠有多個訂單
        /*
         * targetEntity至關於<one-to-many class="">
         * mappedBy至關於inverse=true
         */
    @OneToMany(targetEntity=Customer.class,mappedBy="c",orphanRemoval=true)
    //描述客戶能夠有多個訂單
    private Set<Order> order =  new HashSet<Order>();
 
    public Integer getId() {
        return id;
    }
 
    public void setId(Integer id) {
        this.id = id;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public Set<Order> getOrder() {
        return order;
    }
 
    public void setOrder(Set<Order> order) {
        this.order = order;
    }
    
    
}
 
 
Order類
 
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
 
//訂單-----多的一方
@Entity
@Table(name = "t_order")
public class Order {
 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
 
    private Double money;
 
    private String receiverInfo; // 收貨地址
    // 訂單與客戶關聯
    @ManyToOne(targetEntity = Customer.class)
    @JoinColumn(name = "c_id") // 指定外鍵列
    private Customer c; // 描述訂單屬於某一個客戶
 
    public Customer getC() {
        return c;
    }
 
    public void setC(Customer c) {
        this.c = c;
    }
 
    public Integer getId() {
        return id;
    }
 
    public void setId(Integer id) {
        this.id = id;
    }
 
    public Double getMoney() {
        return money;
    }
 
    public void setMoney(Double money) {
        this.money = money;
    }
 
    public String getReceiverInfo() {
        return receiverInfo;
    }
 
    public void setReceiverInfo(String receiverInfo) {
        this.receiverInfo = receiverInfo;
    }
 
}
 
 
 
示例:保存客戶時,保存訂單
對於這個示例咱們須要在Customer中配置(級聯)cascade操做,<save-update>
 
 
第一種方式,可使用JPA提供的註解
(推薦使用)第二種方式:可使用hibernate提供的註解
    @OneToMany(targetEntity=Customer.class,mappedBy="c")
    @Cascade(CascadeType.SAVE_UPDATE)
    //描述客戶能夠有多個訂單
    private Set<Order> order =  new  HashSet<Order>();
 
如下是示例代碼
將id設爲自動增加
@Test
    //測試級聯保客戶時候自動保存訂單
    public void test2(){
         Session session =  HibernateUtils.openSession();
         Transaction transaction =  session.beginTransaction();
         //訂單1
         Order order1 = new Order();
         order1.setReceiverInfo("福建");
         order1.setMoney(998d);
         //訂單2
         Order order2 = new Order();
         order2.setReceiverInfo("福建");
         order2.setMoney(100d);
         
         //顧客1
         Customer customer = new Customer();
         customer.setName("雷老虎");
         //創建關係
         order1.setC(customer);
         order2.setC(customer);
         
         customer.getOrder().add(order1);
         customer.getOrder().add(order2);
         
         session.save(customer);
         
         transaction.commit();
         session.close();
         
         
    }
 
 
訂單中沒有關聯客戶的id,爲何?
緣由:咱們在Customer中配置了mappedBy= c 」(至關於inverse=true) 它表明的是外鍵的維護由Order方來維護,而Customer不維護,這時你在保存客戶時,級聯保存訂單,是能夠的,可是不能維護外鍵,因此,咱們必須在代碼中添加訂單與客戶關係。
 
擴展:關於hibernate註解@Cascade中的DELETE_ORPHAN過期
s
使用下面方案來替換過期方案
 
      H ibernate關聯映射-多對多
使用註解完成多對多配置.
描述學生與老師.
使用@ManyToMany來配置多對多,只須要在其中一端配置中間表,另外一端使用mappedBy表示放置外鍵維護權。
        建立PO類
T eacher類中
 
import java.util.HashSet;
import java.util.Set;
 
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
 
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
 
@Entity
@Table(name = "t_teacher")
public class Teacher {
 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String name;
 
    @ManyToMany(targetEntity = Student.class, mappedBy = "teachers") // 表明由對方來維護外鍵
    @Cascade(CascadeType.ALL)
    private Set<Student> students = new HashSet<Student>();
 
    public Integer getId() {
        return id;
    }
 
    public void setId(Integer id) {
        this.id = id;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public Set<Student> getStudents() {
        return students;
    }
 
    public void setStudents(Set<Student> students) {
        this.students = students;
    }
 
}
 
 
S tudent類中
 
import java.util.HashSet;
import java.util.Set;
 
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.ManyToMany;
import javax.persistence.Table;
 
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
 
@Entity
@Table(name = "t_student")
public class Student {
 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
 
    private String name;
    @ManyToMany(targetEntity = Teacher.class)
     // 使用JoinTabl來描述中間表,並描述中間表中外鍵與Student,Teacher的映射關係
    // joinColumns它是用來描述(本方)Student與中間表中的映射關係
    // inverseJoinColums它是用來描述對方(Teacher)與中間表中的映射關係
    // 其中referencedColumnName = "id"能夠省略,由於默認就是和主鍵關聯
    @JoinTable(name = "s_t", joinColumns = {
            @JoinColumn(name = "c_student_id", referencedColumnName = "id") }, inverseJoinColumns = {
                    @JoinColumn(name = "c_teacher_id", referencedColumnName = "id") })
    @Cascade(CascadeType.ALL)
    private Set<Teacher> teachers = new HashSet<Teacher>();
 
    public Integer getId() {
        return id;
    }
 
    public void setId(Integer id) {
        this.id = id;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public Set<Teacher> getTeachers() {
        return teachers;
    }
 
    public void setTeachers(Set<Teacher> teachers) {
        this.teachers = teachers;
    }
 
}
總結:
一對多和多對多的配置步驟:
    1.添加關聯關係的註解:@ManyToOne,@OneToMany,ManyToMany
        配置targetEntity(對方的類.class)
    2.哪方維護外鍵:mappedBy="對方中,表示本方的名稱"
    3.在維護關係的一方添加外鍵映射
 
級聯保存操做測試
 由於咱們將外鍵的維護權利由Student來維護,咱們演示保存學生時,將都也級聯保存。
 
 
咱們在Student類中配置了級聯
 
  1.  

    級聯刪除操做測試

  H ibernate關聯映射-一對一
    以人與身份證號爲例
 
一對一操做有兩種映射方式:

  1. 在任意一方添加外鍵

  2. 主鍵映射
                 外鍵映射
 
         建立實體
User類
上述配置,t_user表放棄對外鍵的維護權利
 
IDCard類
joinColumn指定外鍵列名稱,當前配置外鍵是在t_idcard表中
 
測試代碼
  1.  

    主鍵映射

以Husband與Wife爲例
 
W ife的主鍵生成策略是identity
@PrimaryKeyJoinColumn 說明husband與wife是使用主鍵映射
 
H usband的主鍵咱們設置成參考wife的主鍵方式
 
測試操做
相關文章
相關標籤/搜索