本文共 4741 字,大约阅读时间需要 15 分钟。
哎~~~前一个礼拜csdn博客当掉了,使我都懒得写博客了~~等这博客稳定了再写吧,先转载下一些好文章。
基于业务需求,您会需要使用两个字段来作复合主键,例如在User数据表中,您也许会使用"name"与"phone"两个字段来定义复合主键。
假设您这么建立User表格:
CREATE TABLE user ( name VARCHAR ( 100 ) NOT NULL , phone VARCHAR ( 50 ) NOT NULL , age INT , PRIMARY KEY (name, phone));
在表格中,"name"与"age"被定义为复合主键,在映像时,您可以让User类别直接带有"name"与"age"这两个属性,而Hibernate要求复合主键类别要实作Serializable接口,并定义equals()与hashCode()方法:
User.java
package onlyfun.caterpillar; import java.io.Serializable; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; // 复合主键类的对应类别必须实作Serializable接口 public class User implements Serializable { private String name; private String phone; private Integer age; public User() { } public Integer getAge() { return age; } public void setAge(Integer age) { this .age = age; } public String getName() { return name; } public void setName(String name) { this .name = name; } public String getPhone() { return phone; } public void setPhone(String phone) { this .phone = phone; } // 必须重新定义equals()与hashCode() public boolean equals(Object obj) { if (obj == this ) { return true ; } if ( ! (obj instanceof User)) { return false ; } User user = (User) obj; return new EqualsBuilder() .append( this .name, user.getName()) .append( this .phone, user.getPhone()) .isEquals(); } public int hashCode() { return new HashCodeBuilder() .append( this .name) .append( this .phone) .toHashCode(); }}
equals()与hashCode()方法被用作两笔不同数据的识别依据;接着您可以使用<composite-id>在映射文件中定义复合主键与对象的属性对应:
User.hbm.xml
<? 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" > < hibernate-mapping > < class name ="onlyfun.caterpillar.User" table ="user" > < composite-id > < key-property name ="name" column ="name" type ="java.lang.String" /> < key-property name ="phone" column ="phone" type ="java.lang.String" /> </ composite-id > < property name ="age" column ="age" type ="java.lang.Integer" /> </ class > </ hibernate-mapping >
在储存数据方面,复合主键的储存没什么区别,现在的问题在于如何依据复合主键来查询数据,例如使用load()方法,您可以创建一个User实例,并设定复合主键对应的属性,接着再透过load()查询对应的数据,例如:
User user = new User();user.setName( " bush " );user.setPhone( " 0970123456 " ); Session session = sessionFactory.openSession(); // 以实例设定复合主键并加载对应的数据 user = (User) session.load(User. class , user); System.out.println(user.getAge() + " /t " + user.getName() + " /t " + user.getPhone());session.close();
可以将主键的信息独立为一个类别,例如:
UserPK.java
package onlyfun.caterpillar; import java.io.Serializable; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; public class UserPK implements Serializable { private String name; private String phone; public String getName() { return name; } public void setName(String name) { this .name = name; } public String getPhone() { return phone; } public void setPhone(String phone) { this .phone = phone; } public boolean equals(Object obj) { if (obj == this ) { return true ; } if ( ! (obj instanceof User)) { return false ; } UserPK pk = (UserPK) obj; return new EqualsBuilder() .append( this .name, pk.getName()) .append( this .phone, pk.getPhone()) .isEquals(); } public int hashCode() { return new HashCodeBuilder() .append( this .name) .append( this .phone) .toHashCode(); }}
现在User类别的主键信息被分离出来了,例如:
User.java
package onlyfun.caterpillar; import java.io.Serializable; public class User implements Serializable { private UserPK userPK; // 主键 private Integer age; public User() { } public UserPK getUserPK() { return userPK; } public void setUserPK(UserPK userPK) { this .userPK = userPK; } public Integer getAge() { return age; } public void setAge(Integer age) { this .age = age; }}
在映像文件方面,需要指定主键类的信息,例如:
User.hbm.xml
<? 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" > < hibernate-mapping > < class name ="onlyfun.caterpillar.User" table ="user" > < composite-id name ="userPK" class ="onlyfun.caterpillar.UserPK" unsaved-value ="any" > < key-property name ="name" column ="name" type ="java.lang.String" /> < key-property name ="phone" column ="phone" type ="java.lang.String" /> </ composite-id > < property name ="age" column ="age" type ="java.lang.Integer" /> </ class > </ hibernate-mapping >
在查询数据时,必须指定主键信息,例如:
UserPK pk = new UserPK();pk.setName( " bush " );pk.setPhone( " 0970123456 " ); Session session = sessionFactory.openSession(); // 以主键类实例设定复合主键并加载对应的数据 User user = (User) session.load(User. class , pk); System.out.println(user.getAge() + " /t " + user.getUserPK().getName() + " /t " + user.getUserPK().getPhone());session.close();