Hibernate 承袭关系配置
Hibernate 继承关系配置
以Department和Employee实体为例。Developer和Tester都继承Employee。
Department类和Employee类和映射的声明:
Hibernate 多对一关联配置
Developer类:
Tester类:
1. 整个继承关系映射到一张表(single-table-per-hierarchy)
优点:不管是查询父类还是子类,只需要查询一张表,性能比较好。
缺点:扩展性不好,当需要增加子类或者属性,我们需要往表中增加字段,很多字段都空置,不符合面向对象编程的思想。
修改Employee.hbm.xml
2. 每个类映射到一个表(joined-subclass)
每个子类实例的数据会放在两张表里:父类表(基本属性)和子类表(子类特有的属性)
优点:父类表中没有空置的字段。
缺点:查询子类数据需要连表查询(父类表和子类表),效率不高。
适合:子类较少,每个子类的属性都各不相同。
修改Employee.hbm.xml:
3. 鉴别器和内联器结合
充分利用1和2的优点
Employee.hbm.xml:
4. 每个具体类映射一张独立表(union-subclass)
和2不同,这里子类的所有属性(包括从父类继承的)会保存到一张独立的表中。
Employee.hbm.xml:
这里的id生成器用的是hilo(或uuid)。
native(mysql里是自动增长)方式不可以:
id值会重复。
如Employee, Developer和Tester三张独立的表,每张表的id都是从1开始自增长的。
当查询id为1的Employee的时候,会查询到3个对象。
以Department和Employee实体为例。Developer和Tester都继承Employee。
Department类和Employee类和映射的声明:
Hibernate 多对一关联配置
Developer类:
public class Developer extends Employee { private String develop; public Developer() { } public Developer(String name) { super(name); } // Getters and setters are omitted
Tester类:
public class Tester extends Employee { private String test; public Tester(){ } public Tester(String name) { super(name); } // Getters and setters are omitted }
1. 整个继承关系映射到一张表(single-table-per-hierarchy)
优点:不管是查询父类还是子类,只需要查询一张表,性能比较好。
缺点:扩展性不好,当需要增加子类或者属性,我们需要往表中增加字段,很多字段都空置,不符合面向对象编程的思想。
修改Employee.hbm.xml
<class name="Employee" discriminator-value="0"> <id name="id"> <generator class="native"/> </id> <!-- 增加一个字段,以区别对应的是哪个实体 --> <discriminator column="type" type="string"/> <property name="name" length="20" not-null="true"/> <many-to-one name="department" column="depart_id" cascade="save-update" fetch="join" lazy="no-proxy" /> <!-- Inheritance - Single-Table-Per-Hierarchy --> <subclass name="Developer" discriminator-value="3"> <property name="develop" length="40"/> </subclass> <subclass name="Tester" discriminator-value="4"> <property name="test" length="40"/> </subclass> </class>
Session s = null; Transaction tx = null; Department depart = new Department("FCI"); Employee em1 = new Employee("John"); em1.setDepartment(depart); Developer em2 = new Developer("Lucy"); em2.setDepartment(depart); em2.setDevelop("Java"); Tester em3 = new Tester("Lily"); em3.setDepartment(depart); em3.setTest("Load runner"); try { s = HibernateUtil.getSession(); tx = s.beginTransaction(); s.save(em1); s.save(em2); s.save(em3); tx.commit(); } catch (HibernateException e) { tx.rollback(); e.printStackTrace(); } finally { s.close(); }
2. 每个类映射到一个表(joined-subclass)
每个子类实例的数据会放在两张表里:父类表(基本属性)和子类表(子类特有的属性)
优点:父类表中没有空置的字段。
缺点:查询子类数据需要连表查询(父类表和子类表),效率不高。
适合:子类较少,每个子类的属性都各不相同。
修改Employee.hbm.xml:
<class name="Employee"> <id name="id"> <generator class="native"/> </id> <property name="name" length="20" not-null="true"/> <many-to-one name="department" column="depart_id" cascade="save-update" fetch="join" lazy="no-proxy" /> <!-- Inheritance --> <joined-subclass name="Developer"> <key column="develop_id" foreign-key="id"/> <property name="develop" length="40"/> </joined-subclass> <joined-subclass name="Tester"> <key column="test_id" foreign-key="id"/> <property name="test" length="40"/> </joined-subclass> </class> </hibernate-mapping>
3. 鉴别器和内联器结合
充分利用1和2的优点
Employee.hbm.xml:
<hibernate-mapping package="com.john.myhibernate.domain"> <class name="Employee" discriminator-value="0"> <id name="id"> <generator class="native"/> </id> <discriminator column="type" type="string"/> <property name="name" length="20" not-null="true"/> <many-to-one name="department" column="depart_id" cascade="save-update" fetch="join" lazy="no-proxy" /> <!-- Inheritance --> <subclass name="Developer" discriminator-value="3"> <property name="develop" length="40"/> </subclass> <subclass name="Tester" discriminator-value="4"> <join table="my_tester"> <key column="test_id" foreign-key="id"/> <property name="test" length="40"/> </join> </subclass> </class> </hibernate-mapping>
4. 每个具体类映射一张独立表(union-subclass)
和2不同,这里子类的所有属性(包括从父类继承的)会保存到一张独立的表中。
Employee.hbm.xml:
<class name="Employee"> <id name="id"> <generator class="hilo"/> </id> <property name="name" length="20" not-null="true"/> <many-to-one name="department" column="depart_id" cascade="save-update" fetch="join" lazy="no-proxy" /> <!-- Inheritance --> <union-subclass name="Developer" table="developer"> <property name="develop" length="40"/> </union-subclass> <union-subclass name="Tester" table="tester"> <property name="test" length="40"/> </union-subclass> </class> </hibernate-mapping>
这里的id生成器用的是hilo(或uuid)。
native(mysql里是自动增长)方式不可以:
id值会重复。
如Employee, Developer和Tester三张独立的表,每张表的id都是从1开始自增长的。
当查询id为1的Employee的时候,会查询到3个对象。