Hibernate复合主键
2015-07-06 06:58
337 查看
有关Hibernate的联合主键
对于新系统的设计开发而言,我们应尽量避免在库表中引入与业务逻辑相关的主键关系。将业务逻辑主键引入库表,以后业务逻辑的变化,将很可能对底层数据库结构产生连带影响。
复合主键的引入,很大程度上意味着业务逻辑已经侵入到数据存储逻辑之中。
因此,应尽量避免。但实际情况中,我们必须面对遗留系统的旧表开发,这时,对现有复合主键的支持就非常必要。
hibernate中,通过composite-id节点对复合主键进行定义。
我们可以通过两种形式确定主键:
1)基于实体类属性的复合主键
2)基于主键类的复合主键
下面通过例子看一下两种方式的用法。
我们建一个用户表user(firstname, lastname, age),以firstname, lastname作为复合主键。建表语句:
CREATE TABLE `hbm_test`.`user` (
`firstname` VARCHAR(50) NOT NULL DEFAULT '',
`lastname` VARCHAR(50) NOT NULL DEFAULT '',
`age` INTEGER UNSIGNED DEFAULT 0,
PRIMARY KEY(`firstname`, `lastname`)
)
ENGINE = InnoDB;
1)基于实体类属性的复合主键
映射文件如下:
<class name="User" table="user"> <composite-id> <key-property name="Lastname" column="lastname" type="string" /> <key-property name="Firstname" column="firstname" type="string" /> </composite-id> <property name="Age" column="age" type="integer" not-null="false" length="10" /> </class>
通过composite-id节点声明了一个复合主键,是由“firstname" "lastname"组成。
实体类User中包含了复合主键firstname lastname,hibernate要求复合主键类实现equals hashCode,
以作为不同数据间的识别的标志。
public class User implements Serializable{ private String firstname; private String lastname; private int age; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getFirstname() { return firstname; } public void setFirstname(String firstname) { this.firstname = firstname; } public String getLastname() { return lastname; } public void setLastname(String lastname) { this.lastname = lastname; } public boolean equals(Object obj){ if(!(obj instanceof User)){ return false; }else{ User user = (User)obj; return new EqualsBuilder().appendSuper(super.equals(obj)) .append(this.firstname, user.firstname) .append(this.lastname, user.lastname) .isEquals(); } } public int hashCode(){ return new HashCodeBuilder(-528253723, -475504089) .appendSuper(super.hashCode()) .append(this.firstname) .append(this.lastname) .toHashCode(); } }
EqualsBuilder HashCodeBuilder均为 apache common lang包中的工具类。
对于Session.load方法,我们可将User类对象本身作为查询条件:
User user = new User();
user.setFirstname("hello");
user.setLastname("world");
user = (User)session.load(User.class, user);
System.out.println("age: " + user.getAge());
2)基于主键类的复合主键
我们可以将主键逻辑加以分离,以一个单独的主键类对复合主键进行描述。
现在把User中的firstname lastname提取到一个独立的主键类UserPK中:
public class UserPK implements Serializable{ private String firstname; private String lastname; public String getFirstname() { return firstname; } public void setFirstname(String firstname) { this.firstname = firstname; } public String getLastname() { return lastname; } public void setLastname(String lastname) { this.lastname = lastname; } }
之后修改映射文件的composite-id节点:
<composite-id name="userPk" class="UserPK"> <key-property name="Lastname" column="lastname" type="string" /> <key-property name="Firstname" column="firstname" type="string" /> </composite-id> <property name="Age" column="age" type="integer" not-null="false" length="10" />
只是配置了name和class属性,name指定了实体类中的主键类属性名,class指定了主键类类型。
User.java修改如下:
public class User implements Serializable{ private UserPK userPk; private int age; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public UserPK getUserPk() { return userPk; } public void setUserPk(UserPK userPk) { this.userPk = userPk; } }
之后,我们即可通过UserPK进行数据查询:
UserPK userPk = new UserPK();
userPk.setFirstname("hello");
userPk.setLastname("world");
User user = (User)session.load(User.class, userPk);
System.out.println("age: " + user.getAge());
via: http://www.zhuoda.org/irini/73145.html
转自:http://blog.csdn.net/haikuotiankong1997/article/details/7745072
========================================================相关文章推荐
- MVC用户登录方法(lamda表达式)
- VMSTAT命令常用功能说明
- 如何用15分钟开启高效的一天
- Linux系统下的作业控制(Job Control)
- CView类的使用
- 堆和栈的区别
- C常见面试题
- ActiveX 添加标准属性
- ubuntu 安装 oracle 11g xe
- Command Pattern 命令模式
- 使用InstallUtil对Windows服务进行安装与卸载
- error C2440: 'static_cast' : cannot convert from 'void (__thiscall CChatDlg::* )(WPARAM,LPARAM)' to
- cannot open Debug/*.exe for writing
- [Leetcode][JAVA] Binary Tree Level Order Traversal
- [LeetCode] Power of Two 判断2的次方数
- Matlab应用实例(4)—linprog(02高级)
- ActionBar Fragment运用最佳实践
- IDNLoopView 图片/视图循环播放控件
- 摘录-IT企业必读的200个.NET面试题-09 .NET中的数据库开发
- 关于OC的内存管理-01