14—继承关系映射和集合映射

继承关系映射和集合映射

1.继承关系映射

Hibernate 允许将继承关系保存到数据库中 

三种继承映射策略 

    第一种 subclass 父类和子类数据用同一张表保存,引入辨别者列,区分数据是父类数据还是子类数据

    第二种 join-subclass 父类和子类 数据都是单独一张表,表之间通过外键表示继承关系 

    第三种 unions-subclass(了解 父类和子类 都是单独一张表,表之间没有任何联系 

 

1)subclass 元素的继承映射 

父类数据 和 子类数据 存放一张表,引入一列 辨别者列(区分数据是否父类还是子类)

    ①编写 EmployeeHourEmployeeSalaryEmployee 

  1. public class Employee {
  2. private Integer id;
  3. private String name;
  4. ……省略setter和getter方法
  5. }
  1. // 小时工
  2. public class HourEmployee extends Employee {
  3. private Double rate; // 时薪
  4. public Double getRate() {
  5. ……省略setter和getter以及toString方法
  6. }
  1. // 正式员工
  2. public class SalaryEmployee extends Employee {
  3. private Double salary;
  4.     ……省略setter和getter方法
  5. }
    ②在继承关系模型中,只需要对父类编写hbm映射就可以了 
  1. <hibernate-mapping>
  2.     <class name="cn.itcast.subclass.Employee" table="employee" catalog="hibernate3day4" discriminator-value="ee">
  3.         <id name="id">
  4.             <generator class="identity"></generator>
  5.         </id>
  6.         <!-- 定义辨别者列 -->
  7.         <!-- 该列主要给Hibernate框架使用  -->
  8.         <discriminator column="etype"></discriminator>
  9.         <property name="name"></property>
  10.         <!-- 每个子类 使用 subclass元素配置 -->
  11.         <subclass name="cn.itcast.subclass.HourEmployee" discriminator-value="he">
  12.             <property name="rate"></property>
  13.         </subclass>
  14.         <subclass name="cn.itcast.subclass.SalaryEmployee" discriminator-value="se">
  15.             <property name="salary"></property>
  16.         </subclass>
  17.     </class>
  18. </hibernate-mapping>  
测试添加和查询 
  1. @Test
  2. // 插入一些数据
  3. public void demo1() {
  4. Session session = HibernateUtils.getCurrentSession();
  5. Transaction transaction = session.beginTransaction();
  6. // 保存员工
  7. Employee employee = new Employee();
  8. employee.setName("张三");
  9. session.save(employee);
  10. // 保存小时工
  11. HourEmployee hourEmployee = new HourEmployee();
  12. hourEmployee.setName("李四");
  13. hourEmployee.setRate(10d);
  14. session.save(hourEmployee);
  15. // 保存正式员工
  16. SalaryEmployee salaryEmployee = new SalaryEmployee();
  17. salaryEmployee.setName("王五");
  18. salaryEmployee.setSalary(3000d);
  19. session.save(salaryEmployee);
  20. transaction.commit();
  21. }
进入数据库查看数据:
    
我们发现,这样就把父子类的数据存到一张表里面了!

进行查询
  1. @Test
  2. // 查询
  3. public void demo2() {
  4. Session session = HibernateUtils.getCurrentSession();
  5. Transaction transaction = session.beginTransaction();
  6. // 查询所有小时工
  7. List<HourEmployee> hourEmployees = session.createQuery(
  8. "from HourEmployee").list();
  9. System.out.println(hourEmployees);
  10. transaction.commit();
  11. }

2)joined-subclass 元素的继承映射

为父类数据和子类数据分别建表,公共信息放入父类表,个性信息放入子类表,通过外键关联

 *** 使用继承映射,类关系是不变的 【上面4个Java文件的内容是不需要改动的!】

  1. <hibernate-mapping>
  2.     <class name="cn.itcast.joinedsubclass.Employee" table="employee" catalog="hibernate3day4" >
  3.         <id name="id">
  4.             <generator class="identity"></generator>
  5.         </id>
  6.         <property name="name"></property>
  7.         <!-- 为每个子类表编写 joined-subclass 元素 -->
  8.         <joined-subclass name="cn.itcast.joinedsubclass.HourEmployee" table="h_employee">
  9.         <!-- 配置子类表 外键 -->
  10.         <!-- eid 是 子类表主键,同时也是外键,引入父类表 id -->
  11.             <key column="eid"></key>
  12.             <property name="rate"></property>
  13.         </joined-subclass>
  14.         <joined-subclass name="cn.itcast.joinedsubclass.SalaryEmployee" table="s_employee">
  15.             <key column="eid"></key>
  16.             <property name="salary"></property>
  17.         </joined-subclass>
  18.     </class>
  19. </hibernate-mapping> 
     
*** 优先使用 joined-subclass,  如果类信息非常少,也可以使用 subclass 

2.集合映射

hbm文件中使用<set>配置一对多和多对多(set集合是无序不允许重复的),在实际开发中,经常会使用有序的集合List(有序,可重复)

    配置方式有<bag> <list> <set>等,而<bag>是基于list的,在javabean中我们继续使用list进行关系维护,只需要在配置的时候使用<bag>即可。<bag>的效率最高!它是无序,可重复的。

<bag>示例:

JavaBean:Article.java

  1. public class Article {
  2. private Integer id;
  3. private String title;
  4. private Author author;
  5.     setter&getter……
  6. }
映射文件:Article.hbm.xml
  1. <hibernate-mapping>
  2. <class name="cn.itcast.collectionmapping.Article" table="article">
  3. <id name="id">
  4. <generator class="identity"></generator>
  5. </id>
  6. <property name="title"></property>
  7. <!-- 多对一 -->
  8. <many-to-one name="author" class="cn.itcast.collectionmapping.Author" column="author_id"></many-to-one>
  9. </class>
  10. </hibernate-mapping>
JavaBean:Author.java
  1. // 作者
  2. public class Author {
  3. private Integer id;
  4. private String name;
  5. private List<Article> articles = new ArrayList<Article>();
  6.     setter&getter……
  7. }
映射文件:Author.hbm.xml
  1. <hibernate-mapping>
  2. <class name="cn.itcast.collectionmapping.Author" table="author">
  3. <id name="id">
  4. <generator class="identity"></generator>
  5. </id>
  6. <property name="name"></property>
  7. <!-- 一对多 -->
  8. <bag name="articles" cascade="all">
  9. <key column="author_id"></key>
  10. <one-to-many class="cn.itcast.collectionmapping.Article"/>
  11. </bag>
  12. </hibernate-mapping>
最后在hibernate.cfg.xml文件中进行配置
  1. <mapping resource="cn/itcast/collectionmapping/Author.hbm.xml"/>
  2. <mapping resource="cn/itcast/collectionmapping/Article.hbm.xml"/>
进行测试:
  1. @Test
  2. // 插入一个作者,两篇文章
  3. public void demo1() {
  4. Session session = HibernateUtils.getCurrentSession();
  5. Transaction transaction = session.beginTransaction();
  6. Author author = new Author();
  7. author.setName("金庸");
  8. Article article = new Article();
  9. article.setTitle("天龙八部");
  10. Article article2 = new Article();
  11. article2.setTitle("笑傲江湖");
  12. author.getArticles().add(article);
  13. author.getArticles().add(article2);
  14. session.save(author);
  15. transaction.commit();
  16. }

至此,bag的操作结束,它其实和list的操作没啥很大区别。

问题:为什么list的操作就有序了呢?
    原理:在数据表中保存数据下标(维护有序性 )
上面的代码不需要改动,只需要在映射文件Author.hbm.xml文件中修改配置即可
  1. <hibernate-mapping>
  2. <class name="cn.itcast.collectionmapping.Author" table="author">
  3. <id name="id">
  4. <generator class="identity"></generator>
  5. </id>
  6. <property name="name"></property>
  7. <list name="articles" cascade="all">
  8. <key column="author_id"></key>
  9. <!-- 生成列,article_index 维护顺序 -->
  10. <list-index column="article_index"></list-index>
  11. <one-to-many class="cn.itcast.collectionmapping.Article"/>
  12. </list>
  13. </class>
  14. </hibernate-mapping>
简单的说就是多了一列来维护顺序,我们可以查看最后数据库查询的结果:
        +----+----------+-----------+---------------+
| id | title    | author_id | article_index |
+----+----------+-----------+---------------+
|  1 | 天龙八部 |         1 |             0 |
|  2 | 笑傲江湖 |         1 |             1 |
+----+----------+-----------+---------------+


阅读更多

扫码向博主提问

寒夕若梦

非学,无以致疑;非问,无以广识
去开通我的Chat快问
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页