虽然student与teacher有些许属性重复,但似乎传统方式在完成student与teacher没有什么问题,创建并不复杂…但如果,我们增加新的对象,医生,矿工,消防员,警察,程序员…这样看来传统方式并不适用…这就需要继承映射,Hbernate,TopLink等O-R映射框架都支持继承映射,在此,我会为大家讲解EJB3.0 JPA规范的继承映射!
学生,与老师共有的属性,属于所有人类都拥有的属性,故我们可以创建及Person类,来保存共有属性,而学生与老师继承自Person类,增加了自己的属性.
关键字 :Inheritance
对象使用引用以便关联到其它对象;关系型数据库表之间采用外键来描述表的关系。在关系型数据库中通常没有自然且有效的方法来描述类的继承关系。JPA通过Inheritance annotation提供了几种继承策略,它有以下属性:
InheritanceType strategy:用来声明继承策略。可选值是InheritanceType.SINGLE_TABLE、InheritanceType.JOINED和InheritanceType .TABLE_PER_CLASS。
缺省值是InheritanceType.SINGLE_TABLE。
关于Inheritance的更多内容,可以参考<< Hibernate实战>> by Christian Bauer, Gavin King。
一:
InheritanceType.SINGLE_TABLE 策略为类的继承体系采用同一个表。表名是基类的名称。例如:
首先创建父类:Person.java
package cn.vicky.test01; import java.io.Serializable; import javax.persistence.Basic; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Inheritance; import javax.persistence.InheritanceType; @Entity @Inheritance(strategy = InheritanceType.SINGLE_TABLE) // InheritanceType.SINGLE_TABLE 策略为类的继承体系采用同一个表。表名是基类的名称。 public class Person implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; /* Basic 注释表示该属性是基本属性 */ @Basic @Column(length = 20, unique = true, nullable = false) private String name; @Basic @Enumerated(EnumType.STRING) @Column(length = 5, nullable = false) private Sex sex = Sex.MAN; @Basic @Column(length = 3, nullable = false) private Integer age = 1; 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; } public Sex getSex() { return sex; } public void setSex(Sex sex) { this.sex = sex; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
Student.java
package cn.vicky.test01; import javax.persistence.Basic; import javax.persistence.Column; import javax.persistence.Entity; @Entity public class Student extends Person { private static final long serialVersionUID = 1L; /* Basic 注释表示该属性是基本属性 */ @Basic @Column(length = 20, unique = true, nullable = true) private String study = "Java"; public String getStudy() { return study; } public void setStudy(String study) { this.study = study; } }
Teacher.java
package cn.vicky.test01; import javax.persistence.Basic; import javax.persistence.Column; import javax.persistence.Entity; @Entity public class Teacher extends Person { private static final long serialVersionUID = 1L; /** Basic 注释表示该属性是基本属性 **/ @Basic @Column(length = 20, unique = true, nullable = true) private String teach = "大学日语"; public String getTeach() { return teach; } public void setTeach(String teach) { this.teach = teach; } }
执行单元测试,生成数据库表:
mysql> desc teacher;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(20) | NO | UNI | NULL | |
| sex | varchar(5) | NO | | NULL | |
| teach | varchar(20) | NO | | NULL | |
+-------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
sql语句是:
CREATE TABLE `person` (
`DTYPE` varchar(31) NOT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
`age` int(11) NOT NULL,
`name` varchar(20) NOT NULL,
`sex` varchar(5) NOT NULL,
`study` varchar(20) DEFAULT NULL,
`teach` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`),
UNIQUE KEY `study` (`study`),
UNIQUE KEY `teach` (`teach`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
其中的DTYPE,是记录Person的具体子类型的!我们向数据库表输入数据!
manager.getTransaction().begin(); //Student s = new Student(); //s.setName("Vicky"); //s.setAge(22); //s.setStudy("Flex"); //s.setSex(Sex.MAN); //manager.persist(s); Teacher t = new Teacher(); t.setName("GoodTeacher"); t.setAge(43); t.setTeach("大学英语"); t.setSex(Sex.WOMEN); manager.getTransaction().commit();
查看数据库表:
但是,这样将所有对象保存在一个表中,增加了表的容量,这就需要使用InheritanceType.JOINED