这种策略支持双向的一对多关联,这里不支持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();
}