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)则是将主键字段嵌入到实体类内部。在不使用...
2. 通过 @IdClass 注释在实体中标注复合主键。 3. 可以通过 EntityManager 获取数据,或者是直接在 Repository 里写方法。 在上面的示例代码中,我们定义了一个 UserProjectMultiKeysClass 类,该类包含三个字段:...
文件名称列表只有一个:"vs注释生成chm帮助文档工具和详细说明书",这意味着压缩包内可能包含工具本身、可能是一个可执行文件或者DLL,以及一个详细的使用说明书,这份说明书会指导用户如何配置和运行工具,以及如何...
良好的注释能够帮助开发者理解代码的功能、逻辑和目的,特别是在团队合作或者长期项目维护时显得尤为重要。"注释生成工具"就是针对这一需求而设计的软件,旨在自动化地为代码添加注释,以提高开发效率。 这类工具...
里面是包含2个工具和一个使用说明文档,通过我自己使用总结的步骤和网上详细的说明。 包含内容: Sandcastle.msi SandcastleGUI.exe 使用帮助.CHM ...非常好的通过代码注释生成文档的工具,和MSDN一样酷!
在C#编程语言中,有一种高效的方法是利用源代码中的注释来自动生成文档,这种方法既节省时间又确保了文档与代码的一致性。本文将详细介绍如何利用注释和特定工具来实现这一目标。 首先,我们要知道C#支持两种主要的...
"IDEA生成set get方法自动带注释信息"这个主题涉及到的是IDEA如何帮助开发者自动生成带有注释的getter和setter方法,这是一种常见的面向对象编程中的数据访问和修改方式。 getter和setter方法在Java中被广泛用于...
《注释生成器》是一款专为程序员设计的实用工具,旨在简化代码注释的编写过程,提高编程效率,同时注重注释的规范性和可读性。这款程序的出现,是针对编程过程中繁琐的手动注释工作,通过自动化的方式,帮助程序员...
自动生成C#标准注释(类,函数) 2. 颜色拾取器 3. Oracle,Ext.Net代码自动生成工具 使用方法:打开PL/SQL,浏览一个表Table,切换到SQL窗口,拷贝列定义部分 如:id NUMBER, rq DATE, content NVARCHAR2...
get set方法生成注释和字段注释.zip,包括GetterSetterUtil.java、GetterSetterUtil.class、get set方法生成注释和字段注释.docx详细讲解如果用快捷方式生成set、get注释
如果使用Hibernate开发legacy的数据库应用,对于数据库表中有使用字符串作为主键或者使用复合主键情况,那么对于这些情况的影射档是比较麻烦的。该示例应用演示了两张表ITEM和CATEGORY_ITEM表有主外键关系,并且ITEM...
这个"实例类生成器 有注释 C#"显然就是针对C#编程语言设计的一个实用工具,特别适合初学者学习和使用。 首先,让我们了解什么是实例类。在C#中,类是对象的蓝图,它定义了对象的属性和行为。当我们创建一个类的实例...
VSCode 是一个非常流行的代码编辑器,它提供了多种方法来快速生成注释。本文将介绍如何在 VSCode 中快速生成注释。 使用用户代码片段生成注释 VSCode 提供了用户代码片段功能,可以让我们快速生成注释。下面是一个...
对于.NET项目,这通常意味着遵循C#或VB.NET的XML注释约定,这些注释可以被文档生成工具(如Sandcastle或DocFX)利用,生成API参考文档。 2. **.NET项目中的注释** 在.NET项目中,注释通常采用XML格式,例如在C#中...
Mybatis-generator自动生成代码工具,基于mybatis-generator-core-1.3.7.jar,一键生成数据库表对应的entity、dao、mapper文件,并根据数据库表字段注释生成实体类的中文注释,免去自写mapper、dao、实体类的步骤
本实例将探讨如何在C#中获取属性、方法声明前面的“///”注释,这些注释通常用于生成XML文档。XML文档有助于提供代码的清晰说明,方便其他开发者理解和使用。 首先,我们需要了解C#中的三种类型注释: 1. 单行注释...
“工具”标签则表明可能涉及的是利用特定的IDE工具来提高开发效率,例如IntelliJ IDEA的快捷键、插件或者设置,这些都是提升代码注释生成效率的有效手段。 至于压缩包中的"intellij-javadocs.xml"文件,这可能是...
本篇将详细介绍“代码注释图形工具(字符画生成工具)”,特别是其中的“图片转字符画工具(Java5)”和“原理图转字符画工具(AACircuit1_28_7)”。 首先,字符画是一种艺术形式,它通过使用不同字符来创建图像,...
- **Mapper接口**:Mapper接口将包含与数据库交互的方法,注释可以帮助理解这些方法的作用。 - **Mapper XML文件**:XML文件用于定义SQL语句,注释可用于解释每个SQL语句的功能。 4. **全表自动生成**:通过配置...
一款快速生成盒型注释的小工具,可以自己定义注释风格,用于C/C++编程 将文本放在src.txt中,利用2,3,4选项可以调整注释风格,按1根据 目前风格生成注释,生成的注释请在dst.txt中查看,直接复制即可使用。 src...