hibernate继承映射策略之每个子类一张表

本文以hibernate的单表继承映射为例,详细阐述了每个子类一张表的映射策略。通过配置文件和执行SQL语句的展示,对比了数据冗余和查询效率。总结了三种继承映射策略的优缺点:1) 数据冗余多但效率高;2) 数据冗余少但查询效率低,主键设置有限制;3) 数据冗余少,查询效率稍高,但维护表数量多。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

以文章《hibernate单表继承映射》中的几个类为例,我们来看下“每个子类一张表”的映射策略。

与之不同的是Person.hbm.xml配置文件,代码如下:

<hibernate-mapping package="com.test.pojo">
	<class name="Person">
		<id name="id">
			<!-- assigned:自己指定主键 -->
			<generator class="assigned"></generator>
		</id>
		<property name="name" />
		<property name="age" />
		<joined-subclass name="Student">
			<key column="id" />
			<property name="work" />
		</joined-subclass>
		<joined-subclass name="Teacher">
			<key column="id" />
			<property name="salary" />
		</joined-subclass>
	</class>
</hibernate-mapping>
测试类:

public class HibernateTest {
	@Test
	public void testCreateDB(){
		Configuration cfg=new Configuration().configure();
		SchemaExport se=new SchemaExport(cfg);
		//第一个参数表示是否生成ddl脚本,第二个参数表示是否执行到数据库中
		se.create(true, true);
	}
	/**
	 * 保存数据
	 */
	@Test
	public void save(){
		Session session=null;
		Transaction tx=null;
		try{
			session=HibernateUtil.getSession();
			tx=session.beginTransaction();
			Teacher teacher=new Teacher();
			teacher.setId(1);
			teacher.setName("teacher");
			teacher.setAge(20);
			teacher.setSalary(5000);
			Student student=new Student();
			student.setId(2);
			student.setName("stu1");
			student.setAge(20);
			student.setWork("hello world");
			Student stu=new Student();
			stu.setId(3);
			stu.setName("stu2");
			stu.setAge(21);
			stu.setWork("Struts2");
			session.save(student);
			session.save(stu);
			session.save(teacher);
			tx.commit();
		}catch(Exception e){
			if(tx!=null)
				tx.rollback();
			e.printStackTrace();
		}finally{
			HibernateUtil.closeSession();
		}
	}
}
执行testCreateDB,打印信息如下:

alter table Student 
        drop 
        foreign key FK_ohs43dct8k52ch2exlmf4bs3l

alter table Teacher 
        drop 
        foreign key FK_g6jmt7fcm6gfd0jvhimb9xy84

drop table if exists Person

    drop table if exists Student

    drop table if exists Teacher

    create table Person (
        id integer not null,
        name varchar(255),
        age integer,
        primary key (id)
    )

    create table Student (
        id integer not null,
        work varchar(255),
        primary key (id)
    )

    create table Teacher (
        id integer not null,
        salary integer,
        primary key (id)
    )

    alter table Student 
        add constraint FK_ohs43dct8k52ch2exlmf4bs3l 
        foreign key (id) 
        references Person (id)

    alter table Teacher 
        add constraint FK_g6jmt7fcm6gfd0jvhimb9xy84 
        foreign key (id) 
        references Person (id)

数据库表信息如下:


执行save方法,打印sql语句如下:

Hibernate: 
    insert 
    into
        Person
        (name, age, id) 
    values
        (?, ?, ?)
Hibernate: 
    insert 
    into
        Student
        (work, id) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        Person
        (name, age, id) 
    values
        (?, ?, ?)
Hibernate: 
    insert 
    into
        Student
        (work, id) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        Person
        (name, age, id) 
    values
        (?, ?, ?)
Hibernate: 
    insert 
    into
        Teacher
        (salary, id) 
    values
        (?, ?)

数据库表信息如下:


总结:

三种继承映射比较:

1、所有数据存一张表,数据冗余比较多。效率比较高。---推荐使用

2、每个子类一张表,数据冗余比较少,查询效率低,主键不能自增。需要指明为assigned,uuid,hilo等。

3、每个类一张表,数据冗余比较少。查询效率比每个子类一张表稍高。维护的表个数多。







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值