hibernate学习之第十一篇(1)

news/2024/7/5 23:15:41

hibernate的继承映射
《一》一张表映射一棵继承树

使用discriminator(鉴别标志)
类Worker和Farmer都继承自Person
类Person的源代码如下:

package hibernate.extend;
public class Person {
private int id;
private String name;
private int age;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    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;
    }

}

 

类Worker的源代码如下:

package hibernate.extend;

public class Worker extends Person{

    public int getWork_year() {
        return work_year;
    }

    public void setWork_year(int work_year) {
        this.work_year = work_year;
    }
private int work_year;//工人的工龄
}

 

类Farmer的源代码如下:

package hibernate.extend;
public class Farmer extends Person {
private String farm_name;//农民的农场名

    public String getFarm_name() {
        return farm_name;
    }

    public void setFarm_name(String farm_name) {
        this.farm_name = farm_name;
    }
}
 

只有一个映射文件person.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="hibernate.extend">
    <class name="Person" table="person" discriminator-value="0" >
        <id name="id">
            <generator class="native"/>
        </id>
        <discriminator column="type" type="int"/> //通过discriminator节点,我们声明了用做子类辨别标识的字段名
        <property name="name"/>
        <property name="age"/>
        <subclass name="Worker" discriminator-value="1" >
            <property name="work_year"/>
        </subclass>
        <subclass name="Farmer" discriminator-value="2" >
            <property name="farm_name"/>
        </subclass>

    </class>
</hibernate-mapping>

测试代码:

 static void add(){
        Person p = new Person();
        p.setName("person");
        p.setAge(22);

        Worker worker = new Worker();
        worker.setName("worker");
        worker.setAge(30);
        worker.setWork_year(11);

        Farmer farmer = new Farmer();
        farmer.setName("farmer");
        farmer.setAge(31);
        farmer.setFarm_name("little candy");

        Session s = HibernateUtil.getSession();
        Transaction tx = s.beginTransaction();
        s.save(p);
        s.save(worker);
        s.save(farmer);
        tx.commit();
    }
 

执行报出异常:
 org.hibernate.DuplicateMappingException: duplicate import: Person refers to both hibernate.extend.Person and hibernatetest01.Person (try using auto-import="false")

检查后发现,在hibernaqte.cfg.xml配置文件中,我在以前写一对一关系映射时,曾经用到过Person类。
<mapping resource="hibernatetest01/person.hbm.xml"/>
<mapping resource="hibernate/extend/person.hbm.xml"/>


异常也显示说我重复映射。并提示我使用auto-import属性。
修改映射文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="hibernate.extend" auto-import="false" >
    <class name="Person" table="person" discriminator-value="0" >
        <id name="id">
            <generator class="native"/>
        </id>
        <discriminator column="type" type="int"/> //这一列对对象模型没有作用,是hibernate用来区分具体的子类用的
        <property name="name"/>
        <property name="age"/>
        <subclass name="Worker" discriminator-value="1">
            <property name="work_year"/>
        </subclass>
        <subclass name="Farmer" discriminator-value="2">
            <property name="farm_name"/>
        </subclass>
    </class>
</hibernate-mapping>

修改后,问题得到解决。执行以上程序代码,显示的sql语句为:

写道
Hibernate: insert into person (name, age, type) values (?, ?, 0)
Hibernate: insert into person (name, age, work_year, type) values (?, ?, ?, 1)
Hibernate: insert into person (name, age, farm_name, type) values (?, ?, ?, 2)
 

查看数据库的表结构为:
+----+------+--------+------+----------------+--------------+
| id   | type | name  | age  | work_year | farm_name|
+----+------+----------+-----+--------------+--------------+
|  1   |    0  | person |   22 |      NULL      | NULL         |
|  2   |    1  | worker |   30 |        11        | NULL         |
|  3   |    2  | farmer  |   31 |      NULL      | little candy|
+----+------+----------+------+---------------+-------------+

由上面可见:work_year和farm_name属性必须是可以为null的。不然第一条插入语句就会出现问题。这也是这种方法的一种局限。表中有冗余字段。表结构不是很合理。同时,在类体系结构上增加新的子类时,要对数据库表的结构做修改,也使得不是很方便。
这种方案,由于对类体系的操作归结为对一张表的操作,在性能上有一定的优势。

充:
auto-import (可选 - 默认为 true): 指定是否我们可以在查询语言中使用非全限定的类名(仅限于本映射文件中的类)。
假若你有两个持久化类,它们的非全限定名是一样的(就是在不同的包里面),你应该设置auto-import="false"。假若说你把一个“import过”的名字同时对应两个类, Hibernate会抛出一个异常。


http://www.niftyadmin.cn/n/2864060.html

相关文章

Redis——redis集群方案之codis集群的搭建部署

一.什么是codis集群 codis集群简介 Codis是一个分布式的Redis解决方案&#xff0c;对于上层的应用来说&#xff0c;连接Codis Proxy和连接原生的Redis Server没有明显的区别&#xff08;不支持的命令列表&#xff09;&#xff0c;上层应用可以像使用单机的Redis一样使用&#…

hibernate学习之第十一篇(2)

《二》每个子类映射到一张表&#xff08;joined-subclass&#xff09; 配置文件修改为&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" &qu…

MFS——分布式文件系统的安装与部署

一.什么是MFS MFS简介 分布式文件系统是指文件系统管理的物理存储资源通过计算机网络与各节点相连。简单讲&#xff0c;就是把一些分散的共享文件夹&#xff0c;集合到一个文件夹内。对于用户来说&#xff0c;只需要打开该虚拟文件夹&#xff0c;就可以使用这些分散的文件夹进…

hibernate学习之第十二篇

《三》混合使用“一个类继承体系一张表”和“每个子类一张表” 比如上面的例子&#xff0c;worker类可能属性很少&#xff0c;而farmer属性却很多&#xff0c;把两者都与person放在同一张表中&#xff0c;则显得表的 结构不是很合理&#xff0c;会有很多字段是null。所以我们可…

MFS——如何恢复挂掉的mfsmaster服务

需要了解的知识&#xff1a; 在正常关闭的时候&#xff0c;/var/lib/mfs目录中会产生metadata.mfs这个文件&#xff0c;这个文件是开启mfsmaster服务时必备的文件。如果没有该文件,那么mfsmaster服务也就起不来。在正常开启的时候&#xff0c;/var/lib/mfs目录中就会产生metad…

hibernate学习之第十二篇(续)

《四》每个具体类映射一张独立的表&#xff08;union-subclass&#xff09;&#xff0c;即表与子类之间的独立一对一关系 所有的子类的表中的信息都是完整的&#xff0c;不需要对表进行关联了。 person.hbm.xml的配置如下&#xff1a; <?xml version"1.0" enco…

MFS ——利用pacemaker+corosync+pcs实现mfsmaster的高可用

一.什么是mfsmaster的高可用 我们知道mfsmaster是调度器&#xff0c;是mfs最核心的地方&#xff0c;如果mfsmaster挂了&#xff0c;整个mfs架构会挂掉&#xff0c;对此我们要对mfsmaster进行高可用冗余操作。 MFS文件系统中&#xff0c;master负责各个数据存储服务器的管理&am…

hibernate学习之第十三篇

load方法的懒加载及原理分析 懒加载的目的&#xff0c;减少不必要的数据库查询&#xff0c;提升性能。 借用前面组件映射中的user类&#xff0c;对测试代码做写改变&#xff1a; public class Main {public static void main(String[] args) {User user new User();user.set…