2.1.3 复合ID(composite-id)
(1) key-property元素
例如类Software定义如下:
package com.weportal.compositeid;
import java.io.Serializable;
import java.util.Date;
public class Software implements Serializable ...{
private String name;
private String version;
private Date releaseDate;
private String type;
public void setVersion(String version) ...{
this.version = version;
}
public void setType(String type) ...{
this.type = type;
}
public void setReleaseDate(Date releaseDate) ...{
this.releaseDate = releaseDate;
}
public String getVersion() ...{
return version;
}
public void setName(String name) ...{
this.name = name;
}
public String getName() ...{
return name;
}
public Date getReleaseDate() ...{
return releaseDate;
}
public String getType() ...{
return type;
}
}
映射文件使用了composite-id元素的key-property元素。
<?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 package="com.weportal.compositeid">
<class name="Software">
<composite-id>
<key-property name="name" length="20"></key-property>
<key-property name="version" length="10"></key-property>
</composite-id>
<property name="releaseDate"></property>
<property name="type"></property>
</class>
</hibernate-mapping>
生成的数据库表的定义如下:
create table `hibernate`.`software`(
`name` varchar(20) default '' not null,
`version` varchar(10) default '' not null,
`releaseDate` datetime,
`type` varchar(255),
primary key (`name`,`version`)
);
create unique index `PRIMARY` on `hibernate`.`software`(`name`,`version`);
(2) key-many-to-one元素
需要组合成复合ID的属性类型是其他的持久化类,从数据库的角度看,是这个表和另一个表存在多对一的关系,当这个多对一的关系需要被放进复合ID中来作为联合主键的时候,需要使用key-many-to-one元素。
例如:Software类的type类型设为SoftwareType,如下所示:
package com.weportal.compositeid;
import java.io.Serializable;
public class SoftwareType implements Serializable...{
private String id;
private String language;
private String target;
private String os;
/** *//**
* @return Returns the language.
*/
public String getLanguage() ...{
return language;
}
/** *//**
* @param language The language to set.
*/
public void setLanguage(String language) ...{
this.language = language;
}
/** *//**
* @return Returns the os.
*/
public String getOs() ...{
return os;
}
/** *//**
* @param os The os to set.
*/
public void setOs(String os) ...{
this.os = os;
}
/** *//**
* @return Returns the target.
*/
public String getTarget() ...{
return target;
}
/** *//**
* @param target The target to set.
*/
public void setTarget(String target) ...{
this.target = target;
}
/** *//**
* @return Returns the id.
*/
public String getId() ...{
return id;
}
/** *//**
* @param id The id to set.
*/
public void setId(String id) ...{
this.id = id;
}
}
package com.weportal.compositeid;
import java.io.Serializable;
import java.util.Date;
public class Software implements Serializable ...{
private String name;
private String version;
private Date releaseDate;
private SoftwareType type;
//private String type;
public void setVersion(String version) ...{
this.version = version;
}
/**//* public void setType(String type) {
this.type = type;
}*/
public void setReleaseDate(Date releaseDate) ...{
this.releaseDate = releaseDate;
}
public String getVersion() ...{
return version;
}
public void setName(String name) ...{
this.name = name;
}
public String getName() ...{
return name;
}
public Date getReleaseDate() ...{
return releaseDate;
}
/**//* public String getType() {
return type;
}*/
public SoftwareType getType() ...{
return type;
}
public void setType(SoftwareType type) ...{
this.type = type;
}
}
映射文件如下:
<?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 package="com.weportal.compositeid">
<class name="Software">
<composite-id>
<key-property name="name" length="20"></key-property>
<key-property name="version" length="10"></key-property>
<key-many-to-one name="type" class="SoftwareType" column="type" access="field" foreign-key="id"></key-many-to-one>
</composite-id>
<property name="releaseDate"></property>
</class>
<class name="SoftwareType" table="SoftwareType">
<id name="id" column="id">
<generator class="uuid"/>
</id>
<property name="language"></property>
<property name="target"></property>
<property name="os"></property>
</class>
</hibernate-mapping>
生成的表software和softwaretype的定义如下:
create table `hibernate`.`softwaretype`(
`id` varchar(255) default '' not null,
`language` varchar(255),
`target` varchar(255),
`os` varchar(255),
primary key (`id`)
);
create unique index `PRIMARY` on `hibernate`.`softwaretype`(`id`);
create table `hibernate`.`software`(
`name` varchar(20) default '' not null,
`version` varchar(10) default '' not null,
`type` varchar(255) default '' not null,
`releaseDate` datetime,
primary key (`name`,`version`,`type`)
);
alter table `hibernate`.`software`
add index `id`(`type`),
add constraint `id`
foreign key (`type`)
references `hibernate`.`softwaretype`(`id`);
create unique index `PRIMARY` on `hibernate`.`software`(`name`,`version`,`type`);
create index `id` on `hibernate`.`software`(`type`);
另外的一种方式:
把name和version作为一个SoftwareID类,其他的属性留在Software中,如下所示:
package com.weportal.compositeid;
import java.io.Serializable;
public class SoftwareID implements Serializable ...{
private String name;
private String version;
/** *//**
* @return Returns the name.
*/
public String getName() ...{
return name;
}
/** *//**
* @param name The name to set.
*/
public void setName(String name) ...{
this.name = name;
}
/** *//**
* @return Returns the version.
*/
public String getVersion() ...{
return version;
}
/** *//**
* @param version The version to set.
*/
public void setVersion(String version) ...{
this.version = version;
}
}
package com.weportal.compositeid;
import java.util.Date;
public class Software ...{
private Date releaseDate;
private String language;
private String target;
private String os;
private SoftwareID id;
/** *//**
* @return Returns the id.
*/
public SoftwareID getId() ...{
return id;
}
/** *//**
* @param id The id to set.
*/
public void setId(SoftwareID id) ...{
this.id = id;
}
/** *//**
* @return Returns the language.
*/
public String getLanguage() ...{
return language;
}
/** *//**
* @param language The language to set.
*/
public void setLanguage(String language) ...{
this.language = language;
}
/** *//**
* @return Returns the os.
*/
public String getOs() ...{
return os;
}
/** *//**
* @param os The os to set.
*/
public void setOs(String os) ...{
this.os = os;
}
/** *//**
* @return Returns the releaseDate.
*/
public Date getReleaseDate() ...{
return releaseDate;
}
/** *//**
* @param releaseDate The releaseDate to set.
*/
public void setReleaseDate(Date releaseDate) ...{
this.releaseDate = releaseDate;
}
/** *//**
* @return Returns the target.
*/
public String getTarget() ...{
return target;
}
/** *//**
* @param target The target to set.
*/
public void setTarget(String target) ...{
this.target = target;
}
}
映射文件如下:
<?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 package="com.weportal.compositeid">
<class name="Software">
<composite-id class="SoftwareID" name="id">
<key-property name="name" length="20"></key-property>
<key-property name="version" length="10"></key-property>
</composite-id>
<property name="language"></property>
<property name="target"></property>
<property name="os"></property>
<property name="releaseDate"></property>
</class>
</hibernate-mapping>
产生的数据表定义如下:
create table `hibernate`.`software`(
`name` varchar(20) default '' not null,
`version` varchar(10) default '' not null,
`language` varchar(255),
`target` varchar(255),
`os` varchar(255),
`releaseDate` datetime,
primary key (`name`,`version`)
);
create unique index `PRIMARY` on `hibernate`.`software`(`name`,`version`);