Hibernate是采用面向对象的思想设计的,继承映射是将对象的继承关系映射到数据库对应的表中。
继承映射的方法有三种:1.一个子类对应一张表。
2.整个继承系统所包含的对象的属性并集映射到一张表中。
3.父类,子类都各自对应一张表,子类表中只包含私有属性字段和对应父类的外键,父类表中包含所有共有属性字段。
类的继承关系如图:
对应的类:
Peopel.java:
public class People {
private String id;
private String name;
private int age;
//getter,setter
}
Student.java:
public class Student extends People {
private int point;
//getter,setter……
}
Engineer.java:
public class Engineer extends People {
private String computer;
//getter,setter……
}
第一种方法:一个子类对应一张表
这里可以为每个子类都写一个配置文件,配置文件中会自动识别继承关系,也可以只写一个配置文件,在配置文件中自己指定继承关系,这里只给出前面方法,后面方法可以参考下文给出的连接。
Student.hbm.xml:
1 <hibernate-mapping>
2 <class name="com.sunflower.yuan.pojo.Student" table="student">
3 <id name="id" type="string" column="id">
4 <generator class="uuid"></generator>
5 </id>
6
7 <property name="name" type="string" column="name"></property>
8 <property name="age" type="integer" column="age"></property>
9 <property name="point" type="integer" column="point"></property>
10 </class>
11 </hibernate-mapping>
第3至第8行中的name="id",name="name",name="age"属性都是继承自People的,系统会自动通过getter方法得到
Engineer.hbm.xml:
1 <hibernate-mapping>
2 <class name="com.sunflower.yuan.pojo.Engineer" table="engineer">
3 <id name="id" type="string" column="id">
4 <generator class="uuid"></generator>
5 </id>
6
7 <property name="name" type="string" column="name"></property>
8 <property name="age" type="integer" column="age"></property>
9 <property name="computer" type="string" column="computer"></property>
10 </class>
11 </hibernate-mapping>
同上.
在数据库中生成表格(SQL语句):
drop table if exists engineerdrop table if exists studentcreate table engineer (id varchar(255) not null, name varchar(255), age integer, computer varchar(255), primary key (id))create table student (id varchar(255) not null, name varchar(255), age integer, point integer, primary key (id))
测试:
1 public class Test {
2 // 保存测试
3 public void save() {
4 Session session = HibernateUtil.getSession();
5 Transaction ts = session.beginTransaction();
6
7 try {
8 Student student = new Student();
9 student.setName("宫崎骏");
10 student.setAge(18);
11 student.setPoint(90);
12
13 Engineer engineer = new Engineer();
14 engineer.setName("钱学森");
15 engineer.setAge(50);
16 engineer.setComputer("联想");
17
18 session.save(student);
19 session.save(engineer);
20
21 ts.commit();
22 }
23 catch (Exception e) {
24 ts.rollback();
25 e.printStackTrace();
26 }
27 finally {
28 HibernateUtil.closeSession(session);
29 }
30 }
31
32 // 查询测试
33 @SuppressWarnings("unchecked")
34 public void get() {
35 Session session = HibernateUtil.getSession();
36 Transaction ts = session.beginTransaction();
37
38 try {
39 //Iterator将数据放在缓存中,需要查询的时候再向数据库发起查询.
40 Iterator iter = session.createQuery(
41 "from com.sunflower.yuan.pojo.People").iterate();
42 while (iter.hasNext()) {
43 People people = (People)iter.next();
44 System.out.println(people.getName());
45 }
46 ts.commit();
47 }
48 catch (Exception e) {
49 ts.rollback();
50 e.printStackTrace();
51 }
52 finally {
53 HibernateUtil.closeSession(session);
54 }
55 }
56
57 public static void main(String[] args) {
58 Test test = new Test();
59 // test.save();
60 test.get();
61 }
62 }
第40至第41行需要注意:HQL语句中如果继承系统中的类,然而这个类没有给出配置文件,那么就要写出这个类的全名,如果这个类是父祖,那么将会查询出所有子孙对应表格里的数据。还需要注意的是Iterator和List使用的区别,Iterator会在需要得到数据的时候再像数据库发起一条查询语句,而List会通过一条查询语句将所有数据装载在内存中。
第二种方法:整个继承系统所包含的对象的属性并集映射到一张表中
这种方法只需要写一个配置文件对应于根父类:
People.hbm.xml:
1 <hibernate-mapping>
2 <class name="com.sunflower.yuan.pojo.People" table="people">
3 <id name="id" type="string" column="id">
4 <generator class="uuid"></generator>
5 </id>
6
7 <!-- 鉴别器,在数据中区别子类的字段定义 -->
8 <discriminator column="peopleType" type="string"></discriminator>
9
10 <property name="name" type="string" column="name"></property>
11 <property name="age" type="integer" column="age"></property>
12
13 <subclass name="com.sunflower.yuan.pojo.Student"
14 discriminator-value="student">
15 <property name="point" type="integer" column="point"></property>
16 </subclass>
17
18 <subclass name="com.sunflower.yuan.pojo.Engineer"
19 discriminator-value="engineer">
20 <property name="computer" type="string" column="computer"></property>
21 </subclass>
22 </class>
23 </hibernate-mapping>
第8行为鉴别器,用于在表中鉴别出不同的子类,第14行和第19行是为鉴别器中子类进行区分的值.注意第8行的鉴别器一定要放在<id/>下面,否则运行时出错,刚开始的时候我是写在子类配置的上面的,结果运行时报错。
建表语句:
drop table if exists peoplecreate table people (id varchar(255) not null, peopleType varchar(255) not null, name varchar(255), age integer, point integer, computer varchar(255), primary key (id))
测试:
Test.java:
1 public class Test {
2 // 保存测试
3 public void save() {
4 Session session = HibernateUtil.getSession();
5 Transaction ts = session.beginTransaction();
6
7 try {
8 Student student = new Student();
9 student.setName("宫崎骏");
10 student.setAge(18);
11 student.setPoint(90);
12
13 Engineer engineer = new Engineer();
14 engineer.setName("钱学森");
15 engineer.setAge(50);
16 engineer.setComputer("联想");
17
18 session.save(student);
19 session.save(engineer);
20
21 ts.commit();
22 }
23 catch (Exception e) {
24 ts.rollback();
25 e.printStackTrace();
26 }
27 finally {
28 HibernateUtil.closeSession(session);
29 }
30 }
31
32 // 查询测试
33 @SuppressWarnings("unchecked")
34 public void get() {
35 Session session = HibernateUtil.getSession();
36 Transaction ts = session.beginTransaction();
37
38 try {
39 List list = session.createQuery("from People").list();
40 for (int i = 0; i < list.size(); i++) {
41 Object obj = list.get(i);
42 if (obj instanceof Student) {
43 System.out.println("学生分数是:" + ((Student) obj).getPoint());
44 }
45 if (obj instanceof Engineer)
46 System.out.println("工程师电脑是:"
47 + ((Engineer) obj).getComputer());
48 }
49 ts.commit();
50 }
51 catch (Exception e) {
52 ts.rollback();
53 e.printStackTrace();
54 }
55 finally {
56 HibernateUtil.closeSession(session);
57 }
58 }
59
60 public static void main(String[] args) {
61 Test test = new Test();
62 // test.save();
63 test.get();
64 }
65 }
第39至48行是遍历整个表,进行判断查找出不同子类的信息。注意这里的遍历用的是List而不是Interator,因为Interator是在缓存中的,当需要查询的时候才向数据库发出查询请求,如果这里用Interator只能查到id字段,下面的不再进行查询。如果需要查询指定的子类,例如Student,那么在HQL语句中,对子类全名进行查询:session.createQuery("from com.sunflower.yuan.pojo.Student")。
第三种方法:父类,子类都各自对应一张表
这种方法父类、子类都各自对应一张表,父类和子类表中通过主键外键关联
People.hbm.xml:
1 <hibernate-mapping>
2 <class name="com.sunflower.yuan.pojo.People" table="people">
3 <id name="id" type="string" column="id">
4 <generator class="uuid"></generator>
5 </id>
6
7 <property name="name" type="string" column="name"></property>
8 <property name="age" type="integer" column="age"></property>
9
10 <joined-subclass name="com.sunflower.yuan.pojo.Student"
11 table="student">
12 <key column="id"></key>
13 <property name="point" type="integer" column="point"></property>
14 </joined-subclass>
15
16 <joined-subclass name="com.sunflower.yuan.pojo.Engineer"
17 table="engineer">
18 <key column="id"></key>
19 <property name="computer" type="string" column="computer"></property>
20 </joined-subclass>
21 </class>
22 </hibernate-mapping>
第10行和第16行中<joined-subclass/>标签是加入子类关联的标签,第12行和第18行中是指定与父类表关联的外键
建表语句:
alter table engineer drop foreign key FK6C827E6FD8CA6343;alter table student drop foreign key FK8FFE823BD8CA6343;drop table if exists engineer;drop table if exists people;drop table if exists student;create table engineer (id varchar(255) not null, computer varchar(255), primary key (id));create table people (id varchar(255) not null, name varchar(255), age integer, primary key (id));create table student (id varchar(255) not null, point integer, primary key (id));alter table engineer add index FK6C827E6FD8CA6343 (id), add constraint FK6C827E6FD8CA6343 foreign key (id) references people (id);