有时候我们在项目中可能需要联合主键来实现我们的业务,比如说 对于User类来说,我们可以把cardId和name它们两个联合起来作为User类的主键。
官方API给我们解释的如下:
You can use a component as an identifier of an entity class. Your component class must satisfy certain requirements:
1.它必须实现java.io.Serializable
接口
2.It must re-implement equals()
and hashCode()
consistently with the database's notion of composite key equality.
通过上面的我们可以知道,联合主键的实体必须实现Serializable接口以及重写equals()和hashCode()方法。
为什么要这样做呢?
重写这两个方法是因为hibernate要根据数据库的联合主键来判断某两行记录是否是一样的,如果一样那么就认为是同一个对象,如果不一样,那么认为是不同的对象,这反映到程序领域中就是根据hashCode与equals方法来判断某两个对象是否能够放到诸如Set这样的集合当中。
联合主键的实体类实现Serializable接口的原因在于使用get或load方法的时候需要先构建出来该实体的对象,并且将查询依据(联合主键)设置进去,然后作为get或load方法第二个参数传进去即可。
通过例子应该更好的帮助我们理解:
User.java 用户实体类
package com.bawei.demo.vo;
public class User {
private UserPK id;
public UserPK getId() {
return id;
}
public void setId(UserPK id) {
this.id = id;
}
private String sex;
private String address;
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User [id=" + id + ", sex=" + sex + ", address=" + address + "]";
}
}
UserPK.java
package com.bawei.demo.vo;
import java.io.Serializable;
/**
* @author shenyiya
* 实体主键
*
*/
public class UserPK implements Serializable {
private String cardId;
private String name;
public String getCardId() {
return cardId;
}
public void setCardId(String cardId) {
this.cardId = cardId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((cardId == null) ? 0 : cardId.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
UserPK other = (UserPK) obj;
if (cardId == null) {
if (other.cardId != null) {
return false;
}
} else if (!cardId.equals(other.cardId)) {
return false;
}
if (name == null) {
if (other.name != null) {
return false;
} else if (!name.equals(other.name)) {
return false;
}
}
return true;
}
}
User.hbm.xml 实体映射文件
<?xml version="1.0" encoding="gb2312"?>
<!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.bawei.demo.vo.User" table="user">
<composite-id name="id" class="com.bawei.demo.vo.UserPK">
<key-property name="cardId" type="string"></key-property>
<key-property name="name" type="string"></key-property>
</composite-id>
<property name="sex"></property>
<property name="address"></property>
</class>
</hibernate-mapping>
Hibernate.cfg.xml hibernate配置文件
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration>
<session-factory>
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="connection.url">
jdbc:mysql://localhost:3306/demo
</property>
<property name="connection.username">root</property>
<property name="connection.password">123</property>
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="myeclipse.connection.profile">conn</property>
<property name="show_sql">false</property>
<property name="hbm2ddl.auto">update</property>
<mapping resource="com/bawei/demo/dao/Author.hbm.xml" />
<mapping resource="com/bawei/demo/dao/Post.hbm.xml" />
<mapping resource="com/bawei/demo/dao/User.hbm.xml" />
</session-factory>
</hibernate-configuration>
Main 函数 :
public static void main(String[] args) {
// 1.初始化配置文件
Configuration configuration = new Configuration().configure();
// 2.建立session工厂
SessionFactory sessionFactory = configuration.buildSessionFactory();
// 3.从工厂中取得一个连接
Session session = sessionFactory.openSession();
// 4.开启事务
Transaction tx = session.beginTransaction();
// 保存
// UserPK usersPK = new UserPK();
// usersPK.setName("zhangsan");
// usersPK.setCardId("110");
// User user = new User();
// user.setId(usersPK);
// user.setAddress("beijing");
// user.setSex("M");
// session.save(user);
//查询
UserPK usersPK = new UserPK();
usersPK.setName("zhangsan");
usersPK.setCardId("110");
User user=(User) session.load(User.class, usersPK);
System.out.println(user.toString());
// 5.提交事务
tx.commit();
// 6.关闭连接
session.close();
}
效果如下图: