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/
相关推荐
hibernate3 注释生成复合主键或者嵌入式主键的方法及实例
代码注释生成器 如你所见 传一张图片就可以生成文字注释 比如说佛祖保佑那张 或者整个爱豆也能
里面是包含2个工具和一个使用说明文档,通过我自己使用总结的步骤和网上详细的说明。 包含内容: Sandcastle.msi SandcastleGUI.exe 使用帮助.CHM ...非常好的通过代码注释生成文档的工具,和MSDN一样酷!
总结一下关于JPA的主键生成策略,JPA是用@GeneratedValue标记来注释的。一般的我把主键生成分成两大类。第一个就是简单的单字段主键类型,一个就是复杂的复合主键类型。我们分2种情况分别讨论。 第一种单字段主键...
C++代码文档生成器 根据代码及注释自动生成代码文档.zip
自动生成C#标准注释(类,函数) 2. 颜色拾取器 3. Oracle,Ext.Net代码自动生成工具 使用方法:打开PL/SQL,浏览一个表Table,切换到SQL窗口,拷贝列定义部分 如:id NUMBER, rq DATE, content NVARCHAR2...
根据注释生成文档
mysql或者Oracle通过表注释生成word
get set方法生成注释和字段注释.zip,包括GetterSetterUtil.java、GetterSetterUtil.class、get set方法生成注释和字段注释.docx详细讲解如果用快捷方式生成set、get注释
如果使用Hibernate开发legacy的数据库应用,对于数据库表中有使用字符串作为主键或者使用复合主键情况,那么对于这些情况的影射档是比较麻烦的。该示例应用演示了两张表ITEM和CATEGORY_ITEM表有主外键关系,并且ITEM...
代码注释生成文档工具,带有demo,对于文档的生成维护很有帮助
Silktest函数自动注释生成器,很好使用
vs注释生成chm帮助文档工具和详细说明书,即使你没有使用过vss也可以看懂。
自己做的一个vb.net注释生成工具,可以生成过程或函数的自认比较正规的注释。欢迎大家多提宝贵意见。
一款快速生成盒型注释的小工具,可以自己定义注释风格,用于C/C++编程 将文本放在src.txt中,利用2,3,4选项可以调整注释风格,按1根据 目前风格生成注释,生成的注释请在dst.txt中查看,直接复制即可使用。 src...
自动生成带注释的getter和setter方法(注释)插件
Mybatis-generator自动生成代码工具,基于mybatis-generator-core-1.3.7.jar,一键生成数据库表对应的entity、dao、mapper文件,并根据数据库表字段注释生成实体类的中文注释,免去自写mapper、dao、实体类的步骤
生成注释的工具,嘛,半成品。
VSCode如何快速生成注释
具体用途参见http://blog.csdn.net/u011250882/article/details/49311933