在做项目中,比如我以前在基础系统写过接口,经常会遇到这么一种情况:需要该表的2-3个字段才可以唯一确定这个表的一行记录。这种情况我们用原生sql语句很快就能解决,但是如果我们用hibernate来写数据持久层的代码,hibernate是如何应对这种情况的呢?视频中的老师回答了我的这个问题:用复合主键映射来解决。
复合主键映射:
复合主键用<composite-id>来描述
通常做法是将主键相关字段放到一个单独的类中,这样类是有要求的:
* 必须实现序列化接口
* 覆盖equals和hashcode方法
配置文件代码示例如下:
java类的代码如下:
package com.bjpowernode.hibernate;
import java.io.Serializable;
public class FiscalYearPeriodPK implements Serializable {
//核算年
private int fiscalYear;
//核算月
private int fiscalPeriod;
public int getFiscalYear() {
return fiscalYear;
}
public void setFiscalYear(int fiscalYear) {
this.fiscalYear = fiscalYear;
}
public int getFiscalPeriod() {
return fiscalPeriod;
}
public void setFiscalPeriod(int fiscalPeriod) {
this.fiscalPeriod = fiscalPeriod;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + fiscalPeriod;
result = prime * result + fiscalYear;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final FiscalYearPeriodPK other = (FiscalYearPeriodPK) obj;
if (fiscalPeriod != other.fiscalPeriod)
return false;
if (fiscalYear != other.fiscalYear)
return false;
return true;
}
}
Component映射:
举例来说:user类和employee类都有address、email、zipCode,contactTe等属性。将address、email、zipCode,contactTe从user和employee实体类中拿出来,单独建立一个联系方式类***contact,这个类就叫做值对象,也就是所说的组件。
在映射文件中,通过<component>标签,可以将contact类的属性映射到employee和user表中,这样,employee和user表中的字段就会是employee和user表类中的id、name以及contact类中的address、email、zipCode,contactTe。而在数据库中,contact类不用单独创建一张表。
部分代码如下:
employee:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.bjpowernode.hibernate.Employee" table="t_emplyee">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<component name="employeeContact">
<property name="email"/>
<property name="address"/>
<property name="zipCode"/>
<property name="contactTel"/>
</component>
</class>
</hibernate-mapping>
user:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.bjpowernode.hibernate.User" table="t_user">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<component name="userContact">
<property name="email"/>
<property name="address"/>
<property name="zipCode"/>
<property name="contactTel"/>
</component>
</class>
</hibernate-mapping>