11.映射继承关系
来源:互联网 发布:口袋助理源码 编辑:程序博客网 时间:2024/06/09 19:49
1.采用 subclass 元素的继承映射
* 每个具体类一张表(table per concrete class) 将域模型中的每一个实体对象映射到一个独立的表中,也就是说不用在关系数据模型中考虑域模型中的继承关系和多态。
* 父类和子类使用同一张表(有一个区分类型的字段)
* 采用 subclass 的继承映射可以实现对于继承关系中父类和子类使用同一张表
* 因为父类和子类的实例全部保存在同一个表中,因此需要在该表内增加一列,使用该列来区分每行记录到底是哪个类的实例----这个列被称为辨别者列(discriminator).
/** * 钟点工 */public class HourEmployee extends Employee{
/** * 正式员工 */public class SalaryEmployee extends Employee {hibernate配置文件
<hibernate-mapping> <class name="cn.itcast.extends01.Employee" table="employee" discriminator-value="ee"> <id name="id" type="integer"> <column name="id"/> <generator class="increment"/> </id> <!--辨别者列,column="etype"用于区分员工的种类,该配置必须放置在id的后面--> <discriminator column="etype" type="string"/> <property name="name" type="string"> <column name="name"/> </property> <!--配置子类 discriminator-value: 子类对应的辨别者列的值 --> <subclass name="cn.itcast.extends01.HourEmployee" discriminator-value="he"> <property name="rate" column="rate" type="double"/> </subclass> <subclass name="cn.itcast.extends01.SalaryEmployee" discriminator-value="se"> <property name="salary" column="salary" type="double"/> </subclass> </class> </hibernate-mapping>* 辨别者列,用于区分员工的种类,该配置必须放置在id的后面
* 普通员工的辨别者列值为ee,小时工辨别者列的值为he,正式员工的辨别者列的值为se
* 在这种映射策略下,使用 subclass 来映射子类,使用 class 或 subclass 的 discriminator-value 属性指定辨别者列的值
* 所有子类定义的字段都不能有非空约束。如果为那些字段添加非空约束,那么父类的实例在那些列其实并没有值,这将引起数据库完整性冲突,导致父类的实例无法保 存到数据库中
SalaryEmployee se=new SalaryEmployee();se.setName("赵敏");se.setSalary(3000d);* double类型的值要加个d,默认数字都是int类型
1.1查询钟点工信息
@Testpublic void findHourEmployee(){ Session session=sf.openSession(); Transaction tx=session.beginTransaction(); //可以使用子类 Query query=session.createQuery("from HourEmployee"); query.list(); tx.commit(); session.close();}查询语句 Hibernate: select houremploy0_.id as id0_, houremploy0_.name as name0_, houremploy0_.rate as rate0_ from employee houremploy0_ where houremploy0_.etype='he'
* 如果查询所有员工,hql语句为 from Employee 多态查询
2.采用 joined-subclass 元素的继承映射
* 采用 joined-subclass 元素的继承映射可以实现每个子类一张表
* 采用这种映射策略时,父类实例保存在父类表中,子类实例由父类表和子类表共同存储。因为子类实例也是一个特殊的父类实例,因此必然也包含了父类实例的属性。 于是将子类和父类共有的属性保存在父类表中,子类增加的属性,则保存在子类表中
<hibernate-mapping> <class name="cn.itcast.extends02.Employee" table="e_emp" > <id name="id" type="integer"> <column name="id"/> <generator class="increment"/> </id> <property name="name" type="string"> <column name="name"/> </property> <!-- 使用joined-subclass映射子类 name="cn.itcast.extends02.HourEmployee":子类的类的完整路径 table="h_emp":子类对应的表 --> <joined-subclass name="cn.itcast.extends02.HourEmployee" table="h_emp"> <!--表示h_emp 表中的主键,同时又是外键--> <key column="hid"/> <property name="rate" column="rate" type="double"/> </joined-subclass> <joined-subclass name="cn.itcast.extends02.SalaryEmployee" table="s_emp"> <key column="sid"/> <property name="salary" column="salary" type="double"/> </joined-subclass> </class> </hibernate-mapping>* 子类增加的属性可以添加非空约束。因为子类的属性和父类的属性没有保存在同一个表中
* 在这种映射策略下,无须使用鉴别者列,但需要为每个子类使用 key 元素映射共有主键,该主键必须与父类标识属性的列名相同。
2.1.删除员工信息
@Testpublic void removeEmployee(){ Session session=sf.openSession(); Transaction tx=session.beginTransaction(); Employee e2=(Employee)session.get(Employee.class, 2); session.delete(e2); tx.commit(); session.close();}* 删除员工信息,不用使用级联
2.2.查询唯一的员工,不是钟点工也不是正式员工
@Testpublic void findUniqueEmployee(){ Session session=sf.openSession(); Transaction tx=session.beginTransaction(); //sql SELECT * FROM e_emp e WHERE e.id NOT IN(SELECT hid FROM h_emp) AND e.id NOT IN(SELECT sid FROM s_emp) Query query=session.createQuery("from Employee e where e.id not in(select h.id from HourEmployee h) and e.id not in(select s.id from SalaryEmployee s)"); query.list(); tx.commit(); session.close();}
3.项目改造
<!-- 加载映射文件--> <mapping resource="cn/itcast/add/Customer.hbm.xml"/> <mapping resource="cn/itcast/add/Order.hbm.xml"/>* 在Hibernate配置文件加载映射文件
Customer.hbm.xml
<class name="cn.itcast.add.Customer" table="customers" entity-name="customersk"> <id name="id" type="integer"> <column name="id"/> <generator class="increment"/> </id> <property name="name" type="string"> <column name="name"/> </property> <set name="orderes" table="orders" inverse="true"> <key> <column name="customer_id"/> </key> <one-to-many entity-name="ordersk"/> </set> </class>Order.hbm.xml
<class name="cn.itcast.add.Order" table="orders" entity-name="ordersk"> <id name="id" type="integer"> <column name="id"/> <generator class="increment"/> </id> <property name="orderNumber" type="string"> <column name="orderNumber"/> </property> <property name="price" type="double"> <column name="price"/> </property> <many-to-one name="customer" entity-name="customersk"> <column name="customer_id"/> </many-to-one> </class>* entity-name:表示实体的名称 相当于起了一个别名
3.1.项目改造(保存save)
session.save("customersk",customer);3.2.项目改在(修改)
@Testpublic void updateCustomer(){CustomerDao customerDao=new CustomerDao();Customer customer=new Customer();customer.setId(1);customer.setName("西门公子");customerDao.updateCustomer(customer);}* 这种方式的修改的是新建一个对象,再使用update方法,临时对象没有在一级缓存里面,每次都会有update语句,不管属性有没有变
3.3.项目改造(查询list)
public List<Customer> findCustomers() {Session session=null;Transaction tx=null;List<Customer> list=null;try {session=HibernateUtil.getSession();if(session!=null){ tx=HibernateUtil.beginTransaction(session); Query query=session.createQuery("from customersk"); list=query.list(); HibernateUtil.commitTransaction(tx);}} catch (HibernateException e) {e.printStackTrace(); //事务回滚HibernateUtil.rollbackTransaction(tx);}finally{HibernateUtil.closeSession(session);}return list;}* hql语句为from customersk customersk别名
- 11.映射继承关系
- 映射继承关系
- Hibernate 继承关系映射
- 14. 继承关系映射
- 继承关系的映射
- Hibernate 继承关系映射
- 继承关系映射
- 继承关系映射
- 继承关系映射
- 继承关系映射详解
- 继承关系映射
- Hibernate继承关系映射
- 继承关系映射
- 继承关系映射
- hibernate继承关系映射
- Hibernate 映射继承关系
- 类继承关系映射
- Hibernate 继承关系映射
- 【转载】记录一下在使用Servlet中getRequestDispatcher()和sendRedirect()的区别
- 深入了解字符集和编码
- 从零开始学习jQuery (二) 万能的选择器
- makefile文件的编写规则及实例 (转)
- android 电容屏(一):电容屏基本原理篇
- 11.映射继承关系
- 从零开始学习jQuery (三) 管理jQuery包装集
- Telnet访问Web服务器资源
- 从零开始学习jQuery (四) 使用jQuery操作元素的属性与样式
- 典范APP的APP定制的实际情况
- IMX6的相关音频结构体的定义
- 对于Freescale MFG编程工具控制文件ucl.xml的分析
- 从零开始学习jQuery (五) 事件与事件对象
- mysql 性能优化方案