Hibernate不断发展,几乎成为Java数据库持久性的事实标准,因为它非常强大、灵活,而且具备了优异的性能。
传统上,Hibernate的配置依赖于外部 XML 文件:数据库映射被定义为一组 XML 映射文件,并且在启动时进行加载。当然创建这些映射有很多方法,可以从已有数据库模式或Java类模型中自动创建,也可以手工创建。无论如何,您最终将获得大量的 Hibernate 映射文件,而且增加了我们的工作步骤。
而现在我们可以借助新的 Hibernate Annotation 库,即可一次性将注释直接嵌入到您的 Java 类中,不再需要映射配置的xml文件,提供了一种强大及灵活的方法来声明持久性映射。
本文主要讲解一下如果通过注释来创建复合主键以及嵌入式主键:
比如系统有用户表(UserAccount) 角色表(Role) 用户角色关系表(UserRole)三张表,用户角色关系表中 userId、roleId 组成复合主键。
一、先code 一个复合主键的类UserRolePK:作为符合主键类,要满足以下几点要求。
1.必须实现Serializable接口。
2.必须有默认的public无参数的构造方法。
3.必须覆盖equals和hashCode方法。equals方法用于判断两个对象是否相同,EntityManger通过find方法来查找Entity时,是根据equals的返回值来判断的。只有对象的userId和roleId 值完全相同时或同一个对象时则返回true。否则返回false。hashCode方法返回当前对象的哈希码,生成的hashCode相同的概率越小越好,算法可以进行优化。
具体代码如下
1 |
/** |
2 |
* 用户角色表的复合主键
|
3 |
* @author Michael sun
|
4 |
*/
|
5 |
public class UserRolePK implements Serializable {
|
6 |
7 |
public UserRolePK() {
|
8 |
9 |
}
|
10 |
11 |
/**
|
12 |
* serialVersionUID
|
13 |
*/
|
14 |
private static final long serialVersionUID = -4901479789268752591L;
|
15 |
16 |
/**
|
17 |
* 用户名
|
18 |
*/
|
19 |
private String userId;
|
20 |
21 |
/**
|
22 |
* 角色ID
|
23 |
*/
|
24 |
private Integer roleId;
|
25 |
26 |
/**
|
27 |
* @return the userId
|
28 |
*/
|
29 |
public String getUserId() {
|
30 |
return userId;
|
31 |
}
|
32 |
33 |
/**
|
34 |
* @return the roleId
|
35 |
*/
|
36 |
public Integer getRoleId() {
|
37 |
return roleId;
|
38 |
}
|
39 |
40 |
/**
|
41 |
* @param pUserId the userId to set
|
42 |
*/
|
43 |
public void setUserId(String pUserId) {
|
44 |
userId = pUserId;
|
45 |
}
|
46 |
47 |
/**
|
48 |
* @param pRoleId the roleId to set
|
49 |
*/
|
50 |
public void setRoleId(Integer pRoleId) {
|
51 |
roleId = pRoleId;
|
52 |
}
|
53 |
54 |
/**
|
55 |
* overrides hashCode()
|
56 |
* @return int
|
57 |
*/
|
58 |
public int hashCode() {
|
59 |
int result;
|
60 |
result = userId.hashCode();
|
61 |
result = 29 * result + roleId.hashCode();
|
62 |
return result;
|
63 |
}
|
64 |
65 |
/**
|
66 |
* overrides equals
|
67 |
* @see java.lang.Object#equals(java.lang.Object)
|
68 |
*/
|
69 |
70 |
public boolean equals(Object obj) {
|
71 |
if ( this == obj) {
|
72 |
return true ;
|
73 |
}
|
74 |
if ( null == obj) {
|
75 |
return false ;
|
76 |
}
|
77 |
if (!(obj instanceof UserRolePK)) {
|
78 |
return false ;
|
79 |
}
|
80 |
81 |
final UserRolePK pko = (UserRolePK) obj;
|
82 |
if (!userId.equals(pko.userId)) {
|
83 |
return false ;
|
84 |
}
|
85 |
if ( null == roleId || roleId.intValue() != pko.roleId) {
|
86 |
return false ;
|
87 |
}
|
88 |
return true ;
|
89 |
}
|
90 |
91 |
} |
二、通过@IdClass注释在实体中标注复合主键,需要注意:
1.@IdClass标注用于标注实体所使用主键规则的类
2.在实体中同时标注主键的属性。本例中在userId和roleId的getter方法前标注@Id,表示复合主键使用这两个属性
实体代码如下:
1 |
/** |
2 |
* 用户角色关系表
|
3 |
* @author Michael sun
|
4 |
*/
|
5 |
@Entity |
6 |
@Table (name = "TB_USER_ROLE" )
|
7 |
@IdClass (UserRolePK. class )
|
8 |
public class UserRole implements Serializable {
|
9 |
10 |
/**
|
11 |
* serialVersionUID
|
12 |
*/
|
13 |
private static final long serialVersionUID = -8743424029912282776L;
|
14 |
15 |
/**
|
16 |
* 用户名
|
17 |
*/
|
18 |
private String userId;
|
19 |
20 |
/**
|
21 |
* 角色ID
|
22 |
*/
|
23 |
private Integer roleId;
|
24 |
25 |
/**
|
26 |
* 创建人
|
27 |
*/
|
28 |
private String createUser;
|
29 |
30 |
/**
|
31 |
* @return the userId
|
32 |
*/
|
33 |
@Id
|
34 |
@Column (name = "USER_ID" , nullable = false )
|
35 |
public String getUserId() {
|
36 |
return userId;
|
37 |
}
|
38 |
39 |
/**
|
40 |
* @return the roleId
|
41 |
*/
|
42 |
@Id
|
43 |
@Column (name = "ROLE_ID" , nullable = false )
|
44 |
public Integer getRoleId() {
|
45 |
return roleId;
|
46 |
}
|
47 |
48 |
/**
|
49 |
* @param pUserId the userId to set
|
50 |
*/
|
51 |
public void setUserId(String pUserId) {
|
52 |
userId = pUserId;
|
53 |
}
|
54 |
55 |
/**
|
56 |
* @param pRoleId the roleId to set
|
57 |
*/
|
58 |
public void setRoleId(Integer pRoleId) {
|
59 |
roleId = pRoleId;
|
60 |
}
|
61 |
62 |
/**
|
63 |
* @return the createUser
|
64 |
*/
|
65 |
@Column (name = "CREATE_USER" )
|
66 |
public String getCreateUser() {
|
67 |
return createUser;
|
68 |
}
|
69 |
70 |
/**
|
71 |
* @param pCreateUser the createUser to set
|
72 |
*/
|
73 |
public void setCreateUser(String pCreateUser) {
|
74 |
createUser = pCreateUser;
|
75 |
}
|
76 |
77 |
} |
复合主键也可以采用嵌入式主键替代,例如上面复合主键修改成嵌入式主键的步骤如下:
一、code一个嵌入式主键的类,类似于上面的复合主键的类,需要注意代码中加 @Column 注释的地方
具体代码如下:
1 |
/** |
2 |
* 用户角色表的复合主键
|
3 |
* @author Michael sun
|
4 |
*/
|
5 |
public class UserRolePK implements Serializable {
|
6 |
7 |
/**
|
8 |
* UserRolePK
|
9 |
*/
|
10 |
public UserRolePK() {
|
11 |
super ();
|
12 |
}
|
13 |
14 |
/**
|
15 |
* @param userId
|
16 |
* @param roleId
|
17 |
*/
|
18 |
public UserRolePK(String userId, Integer roleId) {
|
19 |
super ();
|
20 |
this .userId = userId;
|
21 |
this .roleId = roleId;
|
22 |
}
|
23 |
24 |
/**
|
25 |
* serialVersionUID
|
26 |
*/
|
27 |
private static final long serialVersionUID = -4901479789268752591L;
|
28 |
29 |
/**
|
30 |
* 用户名
|
31 |
*/
|
32 |
private String userId;
|
33 |
34 |
/**
|
35 |
* 角色ID
|
36 |
*/
|
37 |
private Integer roleId;
|
38 |
39 |
/**
|
40 |
* @return the userId
|
41 |
*/
|
42 |
@Column (name = "USER_ID" , nullable = false )
|
43 |
public String getUserId() {
|
44 |
return userId;
|
45 |
}
|
46 |
47 |
/**
|
48 |
* @return the roleId
|
49 |
*/
|
50 |
@Column (name = "ROLE_ID" , nullable = false )
|
51 |
public Integer getRoleId() {
|
52 |
return roleId;
|
53 |
}
|
54 |
//其他和上面的复合主键一样
|
55 |
} |
二、嵌入式主键实体类的写法需要在复合主键类的get方法加注@EmbeddedId
具体代码如下
1 |
/** |
2 |
* 用户角色关系表
|
3 |
* @author Michael sun
|
4 |
*/
|
5 |
6 |
@Entity |
7 |
@Table (name = "TB_USER_ROLE" )
|
8 |
public class UserRole implements Serializable {
|
9 |
10 |
/**
|
11 |
* serialVersionUID
|
12 |
*/
|
13 |
private static final long serialVersionUID = -8743424029912282776L;
|
14 |
15 |
/**
|
16 |
* 复合主键
|
17 |
*/
|
18 |
@EmbeddedId
|
19 |
private UserRolePK pk;
|
20 |
21 |
/**
|
22 |
* 创建人
|
23 |
*/
|
24 |
private String createUser;
|
25 |
26 |
/**
|
27 |
* @return the pk
|
28 |
*/
|
29 |
@EmbeddedId
|
30 |
public UserRolePK getPk() {
|
31 |
return pk;
|
32 |
}
|
33 |
34 |
/**
|
35 |
* @param pPk the pk to set
|
36 |
*/
|
37 |
public void setPk(UserRolePK pPk) {
|
38 |
pk = pPk;
|
39 |
}
|
40 |
41 |
/**
|
42 |
* @return the createUser
|
43 |
*/
|
44 |
@Column (name = "CREATE_USER" )
|
45 |
public String getCreateUser() {
|
46 |
return createUser;
|
47 |
}
|
48 |
49 |
/**
|
50 |
* @param pCreateUser the createUser to set
|
51 |
*/
|
52 |
public void setCreateUser(String pCreateUser) {
|
53 |
createUser = pCreateUser;
|
54 |
}
|
55 |
56 |
/**
|
57 |
* @return the String
|
58 |
*/
|
59 |
@Transient
|
60 |
public String getUserId() {
|
61 |
return pk.getUserId();
|
62 |
}
|
63 |
64 |
/**
|
65 |
* @return the mergeFlowId
|
66 |
*/
|
67 |
@Transient
|
68 |
public Integer getRoleId() {
|
69 |
return pk.getRoleId();
|
70 |
}
|
71 |
72 |
/**
|
73 |
* @param pUserId the userId to set
|
74 |
*/
|
75 |
public void setUserId(String pUserId) {
|
76 |
this .pk.setUserId(pUserId);
|
77 |
}
|
78 |
79 |
/**
|
80 |
* @param pRoleId the roleId to set
|
81 |
*/
|
82 |
public void setRoleId(Integer pRoleId) {
|
83 |
this .pk.setRoleId(pRoleId);
|
84 |
}
|
85 |
86 |
} |
原创文章,转载请注明: 转载自micmiu – 软件开发+生活点滴[ http://www.micmiu.com/ ]
本文链接地址: http://www.micmiu.com/j2ee/hibernate/hibernate3-anno-complex-pk/
相关推荐
这篇文档将介绍如何使用Hibernate注解来生成复合主键或嵌入式主键。 复合主键(Composite Key)是指由两个或更多个列共同构成的唯一标识,而嵌入式主键(Embedded Key)则是将主键字段嵌入到实体类内部。在不使用...
注释、AroundInvoke、异步、集群、上下文、数据源 EAR文件、EJB-Servlet、二进制实体、嵌入式实体、实体继承、实体生命周期 实体监听、实体管理器、实体合并、实体序列化、实体主键、实体关系 实体二级表、实体更新...
在代码中,你会看到如何实例化SQLiteOpenHelper的子类,然后通过getWritableDatabase()或getReadableDatabase()方法获取数据库对象。这两个方法分别用于获取可读写和只读的数据库句柄。之后,你可以使用SQL语句(如...
当应用需要访问数据库时,通常会通过ContentResolver或直接使用SQLiteOpenHelper的getWritableDatabase()或getReadableDatabase()方法获取到数据库实例。 在实际应用中,我们还需要考虑线程安全问题,因为Android...
在Android开发中,SQLite是一个非常重要的组成部分,它是一个轻量级的、开源的、嵌入式的关系型数据库,被广泛用于存储和管理应用程序中的结构化数据。本代码库提供了关于如何在Android应用中使用SQLite数据库进行...
- 这些方法通过`SQLiteOpenHelper`的`getWritableDatabase()`或`getReadableDatabase()`获取数据库实例,然后执行相应的SQL语句。 3. **UI交互** - 应用界面通常包含一个列表视图显示所有记事,以及一个编辑页面...
- **复合标识组件**:说明如何将组件作为复合主键的一部分来映射。 - **动态组件**:讨论如何实现可变结构的组件映射。 #### 十、继承映射 - **三种策略**:介绍 Hibernate 支持的三种继承映射策略。 - **限制**:...
14.2.4 primary key(主键)约束 285 14.2.5 foreign key(外键)约束 287 14.2.6 check(校验)约束 289 14.3 深入探讨外键与完整性检查 290 14.3.1 引用完整性检查 290 14.3.2 match子句 291 14.3.3 更新、...