hibernate3注释生成复合主键或者嵌入式主键的方法及实例

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相同的概率越小越好,算法可以进行优化。  


具体代码如下  

 
/** 
 * 用户角色表的复合主键 
 * @author Michael sun 
 */ 
public class UserRolePK implements Serializable { 
 
    public UserRolePK() { 
 
    } 
 
    /** 
     * serialVersionUID 
     */ 
    private static final long serialVersionUID = -4901479789268752591L; 
 
    /** 
     * 用户名 
     */ 
    private String userId; 
 
    /** 
     * 角色ID 
     */ 
    private Integer roleId; 
 
    /** 
     * @return the userId 
     */ 
    public String getUserId() { 
        return userId; 
    } 
 
    /** 
     * @return the roleId 
     */ 
    public Integer getRoleId() { 
        return roleId; 
    } 
 
    /** 
     * @param pUserId the userId to set 
     */ 
    public void setUserId(String pUserId) { 
        userId = pUserId; 
    } 
 
    /** 
     * @param pRoleId the roleId to set 
     */ 
    public void setRoleId(Integer pRoleId) { 
        roleId = pRoleId; 
    } 
 
    /** 
     * overrides hashCode() 
     * @return int 
     */ 
    public int hashCode() { 
        int result; 
        result = userId.hashCode(); 
        result = 29 * result + roleId.hashCode(); 
        return result; 
    } 
 
    /** 
     * overrides equals 
     * @see java.lang.Object#equals(java.lang.Object) 
     */ 
 
    public boolean equals(Object obj) { 
        if (this == obj) { 
            return true; 
        } 
        if (null == obj) { 
            return false; 
        } 
        if (!(obj instanceof UserRolePK)) { 
            return false; 
        } 
 
        final UserRolePK pko = (UserRolePK) obj; 
        if (!userId.equals(pko.userId)) { 
            return false; 
        } 
        if (null == roleId || roleId.intValue() != pko.roleId) { 
            return false; 
        } 
        return true; 
    } 
 

 

二、通过 @IdClass注释在实体中标注复合主键,需要注意,  

     1.@IdClass标注用于标注实体所使用主键规则的类  
     2.在实体中同时标注主键的属性。本例中在userId和roleId的getter方法前标注@Id,表示复合主键使用这两个属性实体代码如下。  
 
/** 
 * 用户角色关系表 
 * @author Michael sun 
 */ 
@Entity 
@Table(name = "TB_USER_ROLE") 
@IdClass(UserRolePK.class) 
public class UserRole implements Serializable { 
 
    /** 
     * serialVersionUID 
     */ 
    private static final long serialVersionUID = -8743424029912282776L; 
 
    /** 
     * 用户名 
     */ 
    private String userId; 
 
    /** 
     * 角色ID 
     */ 
    private Integer roleId; 
 
    /** 
     * 创建人 
     */ 
    private String createUser; 
 
    /** 
     * @return the userId 
     */ 
    @Id 
    @Column(name = "USER_ID", nullable = false) 
    public String getUserId() { 
        return userId; 
    } 
 
    /** 
     * @return the roleId 
     */ 
    @Id 
    @Column(name = "ROLE_ID", nullable = false) 
    public Integer getRoleId() { 
        return roleId; 
    } 
 
    /** 
     * @param pUserId the userId to set 
     */ 
    public void setUserId(String pUserId) { 
        userId = pUserId; 
    } 
 
    /** 
     * @param pRoleId the roleId to set 
     */ 
    public void setRoleId(Integer pRoleId) { 
        roleId = pRoleId; 
    } 
 
    /** 
     * @return the createUser 
     */ 
    @Column(name = "CREATE_USER") 
    public String getCreateUser() { 
        return createUser; 
    } 
 
    /** 
     * @param pCreateUser the createUser to set 
     */ 
    public void setCreateUser(String pCreateUser) { 
        createUser = pCreateUser; 
    } 
 

 

ps, 复合主键的值一般要通过程序设置,而不是按照某一个规则自动生成的。复合主键也可以采用嵌入式主键替代,例如上面复合主键修改成嵌入式主键的步骤如下,

一、code一个嵌入式主键的类,类似于上面的复合主键的类,需要注意代码中加 @Column 注释的地方

具体代码如下,  

 
/** 
 * 用户角色表的复合主键 
 * @author Michael sun 
 */ 
public class UserRolePK implements Serializable { 
 
    /** 
     * UserRolePK 
     */ 
    public UserRolePK() { 
        super(); 
    } 
 
    /** 
     * @param userId 
     * @param roleId 
     */ 
    public UserRolePK(String userId, Integer roleId) { 
        super(); 
        this.userId = userId; 
        this.roleId = roleId; 
    } 
 
    /** 
     * serialVersionUID 
     */ 
    private static final long serialVersionUID = -4901479789268752591L; 
 
    /** 
     * 用户名 
     */ 
    private String userId; 
 
    /** 
     * 角色ID 
     */ 
    private Integer roleId; 
 
    /** 
     * @return the userId 
     */ 
    @Column(name = "USER_ID", nullable = false) 
    public String getUserId() { 
        return userId; 
    } 
 
    /** 
     * @return the roleId 
     */ 
    @Column(name = "ROLE_ID", nullable = false) 
    public Integer getRoleId() { 
        return roleId; 
    } 
    //其他和上面的复合主键一样 

 
 
  二、嵌入式主键实体类的写法 需要在复合主键类的get方法加注@EmbeddedId具体代码如下  
 
/** 
 * 用户角色关系表 
 * @author Michael sun 
 */ 
 
@Entity 
@Table(name = "TB_USER_ROLE") 
public class UserRole implements Serializable { 
 
    /** 
     * serialVersionUID 
     */ 
    private static final long serialVersionUID = -8743424029912282776L; 
 
    /** 
     * 复合主键 
     */ 
    @EmbeddedId 
    private UserRolePK pk; 
 
    /** 
     * 创建人 
     */ 
    private String createUser; 
 
    /** 
     * @return the pk 
     */ 
    @EmbeddedId 
    public UserRolePK getPk() { 
        return pk; 
    } 
 
    /** 
     * @param pPk the pk to set 
     */ 
    public void setPk(UserRolePK pPk) { 
        pk = pPk; 
    } 
 
    /** 
     * @return the createUser 
     */ 
    @Column(name = "CREATE_USER") 
    public String getCreateUser() { 
        return createUser; 
    } 
 
    /** 
     * @param pCreateUser the createUser to set 
     */ 
    public void setCreateUser(String pCreateUser) { 
        createUser = pCreateUser; 
    } 
 
    /** 
     * @return the String 
     */ 
    @Transient 
    public String getUserId() { 
        return pk.getUserId(); 
    } 
 
    /** 
     * @return the mergeFlowId 
     */ 
    @Transient 
    public Integer getRoleId() { 
        return pk.getRoleId(); 
    } 
 
    /** 
     * @param pUserId the userId to set 
     */ 
    public void setUserId(String pUserId) { 
        this.pk.setUserId(pUserId); 
    } 
 
    /** 
     * @param pRoleId the roleId to set 
     */ 
    public void setRoleId(Integer pRoleId) { 
        this.pk.setRoleId(pRoleId); 
    } 
 

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值