(11)對映繼承關係二之每個類對應一張表(@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
阿新 • • 發佈:2019-01-24
這種策略支援雙向的一對多關聯,這裡不支援IDENTITY生成器策略。因為存在多型查詢,所以id在繼承關係的表中必須是唯一的。這就意味著不能用AUTO和IDENTITY生成器。
在mysql中,只能用生成表id來使得多個表的id保持不同。因為父類中含有共同的屬性,簡單來講id同,就在父表中,所以子表不用再寫生成表了。在實體中,每個表都含有父類及子類特有的屬性欄位。
person類
@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)//繼承策略是每個類層次結構對映一張表
@TableGenerator(
name="t_gen" ,//(requested)A unique generator name that can be referenced by one or more classes to be the generator for id values.
table="t_gen_table",//Name of table that stores the generated id values.
pkColumnName = "t_key",//pk列名
valueColumnName = "t_value",//pk值列名
pkColumnValue="person_pk",//pk列值
initialValue=1,
allocationSize=1
/*
* 在這種方式多型查詢中,不能確定是哪個子類的,所以學生、教師的id不能相同。根據多型的測試結果,也能看出id不能相同,所以mysql不嫩用自動生成策略
* 用一個id生成表,來確定插入時 的id是什麼
*/
)
public class Person {
private int id;
private String name;
@Id
@GeneratedValue(generator="t_gen",strategy=GenerationType.TABLE)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
student 類繼承person類
@Entity
public class student extends Person {
private int score;
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
}
Test
在利用多型查詢中,是將所有的表聯合起來,組合成所有的類公用一張表的形式
@Test
public void testSave() {
student s=new student();
s.setName("s1");
s.setScore(80);
teacher t=new teacher();
t.setName("t1");
t.setTitle("高階");
Session session=sf.getCurrentSession();
session.beginTransaction();
session.save(s);
session.save(t);
session.getTransaction().commit();
}
@Test
public void testGet() {
testSave();
Session session=sf.getCurrentSession();
session.beginTransaction();
//student s=(student) session.get(student.class, 1);
/*
* 指定學生表,則會輸出學生表的資訊
select
student0_.id as id0_0_,
student0_.name as name0_0_,
student0_.score as score2_0_
from
student student0_
where
student0_.id=?
*/
//使用多型:
Person p=(Person) session.get(Person.class, 2);
/*
*
select
person0_.id as id0_0_,
person0_.name as name0_0_,
person0_.title as title1_0_,
person0_.score as score2_0_,
person0_.clazz_ as clazz_0_
from
( select id, null as title, name,null as score, 0 as clazz_ from Person
union
select id, title, name,null as score, 1 as clazz_ from teacher
union
select id, null as title, name, score, 2 as clazz_ from student
) person0_
where
person0_.id=?
union用於合併兩個或者多個select語句的結果集,並消去重複行。
union內部的select語句必須有相同數目的列,列也必須有相似的資料型別
上面的大from語句相當於將子表資料合併成了single.type的形式。
再根據id確定是哪個子類的。
*/
session.getTransaction().commit();
}