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();
}
緣由:咱們在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類中配置了級聯
-
級聯刪除操做測試
H
ibernate關聯映射-一對一
以人與身份證號爲例
一對一操做有兩種映射方式:
在任意一方添加外鍵
主鍵映射
外鍵映射
建立實體
User類
上述配置,t_user表放棄對外鍵的維護權利
IDCard類
joinColumn指定外鍵列名稱,當前配置外鍵是在t_idcard表中
測試代碼
-
主鍵映射
以Husband與Wife爲例
W
ife的主鍵生成策略是identity
@PrimaryKeyJoinColumn 說明husband與wife是使用主鍵映射
H
usband的主鍵咱們設置成參考wife的主鍵方式
測試操做