数据库结构
create table component(name varchar(50) not null,
sex varchar(50) not null,
description varchar(50),
primary key(name,sex));
主键类,一定要实现Serializable接口,并改写equals和hascode方法
package component;
import java.io.Serializable;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;

public class ComponentPK implements Serializable ...{
private String name;
private String sex;

public String getName() ...{
return name;
}
public void setName(String name) ...{
this.name = name;
}
public String getSex() ...{
return sex;
}
public void setSex(String sex) ...{
this.sex = sex;
}
public boolean equals(Object obj) ...{
if(obj == this) ...{
return true;
}

if(!(obj instanceof Component)) ...{
return false;
}
ComponentPK componentpk = (ComponentPK) obj;
return new EqualsBuilder()
.append(this.name, componentpk.getName())
.append(this.sex, componentpk.getSex())
.isEquals();
}

public int hashCode() ...{
return new HashCodeBuilder()
.append(this.name)
.append(this.sex)
.toHashCode();
}
}
package component;

public class Component ...{
private String description;
private ComponentPK componentpk;
public ComponentPK getComponentpk() ...{
return componentpk;
}
public void setComponentpk(ComponentPK componentpk) ...{
this.componentpk = componentpk;
}
public String getDescription() ...{
return description;
}
public void setDescription(String description) ...{
this.description = description;
}
}
HBM文件
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse - Hibernate Tools
-->
<hibernate-mapping package="component"> 
<class name="Component" table="component">
<composite-id name="componentpk"
class="ComponentPK"
unsaved-value="any">
<key-property name="name"
column="name"
type="java.lang.String"/>
<key-property name="sex"
column="sex"
type="java.lang.String"/>
</composite-id>
<property name="description" column="description" type="java.lang.String"/>
</class> 
</hibernate-mapping>
测试代码:

public static void main(String[] args) ...{
Configuration cfg=new Configuration();
cfg.configure();
SessionFactory sf=cfg.buildSessionFactory();
Session session=sf.openSession();
Transaction t=session.beginTransaction();
ComponentPK pk=new ComponentPK();
pk.setName("1");
pk.setSex("3");
Component component=new Component();
component.setComponentpk(pk);
component.setDescription("12");
session.save(component);
t.commit();
System.out.println("success");
}
如果组成复合主键的某一个属性是其他持久话类的话,则需要使用<key many-to-one>
增加表User:
CREATE TABLE `user` (
`id` varchar(50) NOT NULL,
`pass` varchar(50) default NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=gb2312;
增加持久化类User及相应的Mapping文件
package component;

public class User ...{
private String id;
private String pass;
public String getId() ...{
return id;
}
public void setId(String id) ...{
this.id = id;
}
public String getPass() ...{
return pass;
}
public void setPass(String pass) ...{
this.pass = pass;
}
}
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse - Hibernate Tools
-->
<hibernate-mapping package="component"> 
<class name="User" table="user">
<id name="id" column="id">
<generator class="assigned"></generator>
</id>
<property name="pass" column="pass" type="java.lang.String"/>
</class> 
</hibernate-mapping>
修改ComponentPK类
package component;
import java.io.Serializable;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;

public class ComponentPK implements Serializable ...{
private String name;
private String sex;
private User user;
public User getUser() ...{
return user;
}
public void setUser(User user) ...{
this.user = user;
}
public String getName() ...{
return name;
}
public void setName(String name) ...{
this.name = name;
}
public String getSex() ...{
return sex;
}
public void setSex(String sex) ...{
this.sex = sex;
}
public boolean equals(Object obj) ...{
if(obj == this) ...{
return true;
}

if(!(obj instanceof Component)) ...{
return false;
}
ComponentPK componentpk = (ComponentPK) obj;
return new EqualsBuilder()
.append(this.name, componentpk.getName())
.append(this.sex, componentpk.getSex())
.isEquals();
}

public int hashCode() ...{
return new HashCodeBuilder()
.append(this.name)
.append(this.sex)
.toHashCode();
}
}
修改Component.hbm.xml
<hibernate-mapping package="component"> 
<class name="Component" table="component">
<composite-id name="componentpk"
class="ComponentPK"
unsaved-value="any">
<key-property name="name"
column="name"
type="java.lang.String"/>
<key-property name="sex"
column="sex"
type="java.lang.String"/>
<key-many-to-one name="user" class="User" column="userid" access="field" foreign-key="id"></key-many-to-one>
</composite-id>
<property name="description" column="description" type="java.lang.String"/>
</class> 
</hibernate-mapping>
修改测试代码:

public static void main(String[] args) ...{
Configuration cfg=new Configuration();
cfg.configure();
SessionFactory sf=cfg.buildSessionFactory();
Session session=sf.openSession();
Transaction t=session.beginTransaction();
User user=(User)session.get(User.class, "11111");
ComponentPK pk=new ComponentPK();
pk.setName("1");
pk.setSex("3");
pk.setUser(user);
Component component=new Component();
component.setComponentpk(pk);
component.setDescription("12");
session.save(component);
t.commit();
System.out.println("success");
}
可以看到数据库结果如下:
User(id为111111)
| id | pass |
|---|---|
| 11111 | !234 |
Component的联合主键(name,sex,userid),其中userid已经引用了user表的主键
| name | sex | description | userid |
|---|---|---|---|
| 1 | 3 | 12 | 11111 |
本文介绍如何在Hibernate中定义复合主键及其映射方式,包括使用复合主键类实现序列化接口并重写equals与hashCode方法,以及在Hibernate映射文件中配置复合主键。
1万+

被折叠的 条评论
为什么被折叠?



