主键为多个字段的映射问题
来源:互联网 发布:道教佛教 知乎 编辑:程序博客网 时间:2024/05/16 08:11
在同常情况下,Hibernate建议为持久化类定义一个标识属性,用于唯一地标识某个持久化实例。
对于主键只有一个字段的情况来说,用@Id进行标识就行了,此处不多说。
问题是当标识属性对应多个字段时,该怎么办呢?
组件作为符合主键
使用组件作为复合主键,也就是使用组件作为持久化类的标识符,则该组件类必须满足以下要求:
1. 有无参的构造函数。
2. 必须实现java.io.Serializable接口。
3. 建议正确地重写equals()和hashCode()方法,也就是根据组件类的关键属性来区分组件对象。
当使用组件作为复合主键时,Hibernate无法为这种复合主键生成主键值,所以程序必须为持久化实例分配这种组件标识符(即它不像id一样指定生成的策略之后就可以自动的生成对应的值,需要我们手动的赋值给它)。
下面看一个组件类的例子:
// 1. 实现Serializable接口public class Name implements Serializable{ private String first; private String last; // 2. 无参的构造函数 public Name() { } public Name(String first, String last) { this.first = first; this.last = last; } // 3. 重写equals()和hashCode()方法 @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Name name = (Name) o; if (first != null ? !first.equals(name.first) : name.first != null) return false; return !(last != null ? !last.equals(name.last) : name.last != null); } @Override public int hashCode() { int result = first != null ? first.hashCode() : 0; result = 31 * result + (last != null ? last.hashCode() : 0); return result; }}
当持久化类使用组件作为复合主键时,程序需要使用@EmbededId来修饰该主键。@EmbededId和@Embeded的用法基本相似,只是@Embeded用于修饰普通的组件属性,而@EmbededId用于修饰组件类型的主键。
下面的Person类将使用一个Name类型的主键:
public class Person { // 以Name组件作为标识属性 @EmbeddedId @AttributeOverrides({ // 指定 @AttributeOverride(name="first", column = @Column(name = "person_firstname")), @AttributeOverride(name="last", column = @Column(name = "person_lastname")) }) private Name name; private Integer age; // 省略下面的getter、setter,构造器什么的}
上面Person的标识属性不再是基本类型,也不是String字符串,而是Name类型。Name类型是用户自定义的组件类型,因此程序使用了@EmbeddedId修饰该复合主键,并使用@AttributeOverride定义组件内各属性与底层数据列之间的映射。
多列作为联合主键
Hibernate还提供了另一种联合主键支持,Hibernate允许直接将持久化类的多个属性映射成联合主键。不过得满足以下条件:
1. 有无参的构造函数。
2. 实现java.io.Serializable接口。
3. 建议正确地重写equals()和hashCode()方法。
将持久化类的多个属性映射为联合主键非常简单,直接使用多个@Id修饰这些属性即可。
public class Person implements Serializable { // 定义first属性, 作为标识属性的成员 private String first; // 定义last属性, 作为标识属性的成员 private String last; private Integer age; // 省略下面的代码 // 重写equals和hashCode方法 @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; if (first != null ? !first.equals(person.first) : person.first != null) return false; if (last != null ? !last.equals(person.last) : person.last != null) return false; return !(age != null ? !age.equals(person.age) : person.age != null); } @Override public int hashCode() { int result = first != null ? first.hashCode() : 0; result = 31 * result + (last != null ? last.hashCode() : 0); result = 31 * result + (age != null ? age.hashCode() : 0); return result; }}
程序使用Person类的两个属性作为联合主键,因此Person类需要实现Serializable接口。对于Person的实例,first和last组合起来能唯一标识该实例。
- 主键为多个字段的映射问题
- Hibernate中使用未映射为主键的“id”字段进行查询的场景分析
- 学习EF问题之EF无法映射只包含联合主键字段的表
- Hibernate的主键如果为两个参数时的问题一对一单向主键映射注解方式(十四)
- EF无法映射只包含联合主键字段的表
- 拆分一个字段为多个字段
- sqlserver 如何找到主键为空值的字段
- Griview中DataKeyNames的用法(多个字段作主键)
- 对一个字段中的多个其他表的主键进行查询
- Hibernate学习--------多个字段联合做主键(Annotation版本的,xml不常用)
- hibernate 对象关联,映射非主键字段
- 修改字段类型为“标识”,并设置该字段为主键的SQL语句怎么写
- Hibernate 映射视图的联合主键的问题
- Hibernate处理无主键的表的映射问题
- Hibernate处理无主键的表的映射问题
- hibernate + oracle 映射主键问题
- 关于Hibernate使用组合主键时,组合主键中有些字段为null时的解决方法
- 为一个有数据没有主键id的数据表添加主键字段
- 观察者模式
- 简单的多线程理解
- C++11 多线程
- GC算法 垃圾收集器
- Treap树
- 主键为多个字段的映射问题
- 配置tomcat以运行PHP项目
- udp通信C++实现的细节
- Select模型及tcp select模型
- 数据存储
- Winsock IO模型之select模型
- 基于select模型的udp客户端实现超时机制
- Hiernate操作与缓存
- Wireshark基本介绍及应用tcp