hibernate联合主键生成策略以及一对多配置

1:一般能用一个字段做主键的就不要用两个字段,不过不可避免的会遇到要用两个字段做主键,此时要用hibernate,可以使用联合主键。如图:要用id和name做主键

hibernate联合主键生成策略以及一对多配置_第1张图片

办法:单独设计一个类,起名StudentPK,在该类必须重写equals,hashcode,实现Serializable接口。

此时在Student类中可以删除掉id和name的属性及get/set方法,但是必须加入新的属性,该属性的类型是StudentPK,如:private StudentPK pk;然后生成get/set方法,此时要想存一个Student,首先:new一个StudentPK,然后如图:

hibernate联合主键生成策略以及一对多配置_第2张图片

此时还不够,还必须在配置文件中告诉你哪个是主键?

hibernate联合主键生成策略以及一对多配置_第3张图片

 ps:

为什么实现serise接口?因为ser是序列化的,是将该类序列化然后写到硬盘上的。

作为student这个对象,它在数据库表中可能存在着多条记录,这多条记录如果我们把它放到内存里的话就是多个对象,这多个对象,假如现在被放到了内存中都是student,那么你可以想象每个student对象都有一个主键对象(StudentPK),假如要做集群,有多台服务器,这台宕机了,我们可以序列化,还有一种情况,内存满了,我可以使用虚拟内存,就是把我们硬盘上的一部分空间作为内存来使用,在这种情况下,我们就可以把上面那些内容暂时放到要硬盘上去,所以这个时候就需要实现序列化了。

如图:

hibernate联合主键生成策略以及一对多配置_第4张图片

为什么要重写equals?

保证唯一性。放到内存之后很多student对象,里面都有自己的studentPK,这个时候如何区分?

而且重写时不能乱写。

为什么要重写hashcode?

因为假如说,如果说我们这个对象,它被装在内存的hash表里面,查询时会首先查hashcode,

什么是hash表?

实际上就是一张表格,也可以是数组。hash表在底层很多是数组来实现的。


一对多

需求: 
1.有一个User类,有如下属性: 
    String username; //PK 
    String password; 
    Set grantedAuthority; //一对多关联到Authorities 
2.有一个Authorities,有如下属性: 
    String username; //主键1 
    String authority; //主键2 
要实现如注释所示的表关系。 

做法: 
一。联合主键的制作 
    网上有三种方法,我用的是@IdClass标签的方法。 
    需要为联合主键多做一个类AuthoritiesPK(需要实现Serializable接口)来实现主键的联合,其中属性只需要有联合主键的字段就行了,并且为它们实现get和set方法,这个类不需要做任何的annotation标记。 
    另一个Authorities类在@Entity标记下面添加一个@IdClass(AuthoritiesPK.class),括号里面的是前面那个新建的类。然后再在Authorities类中的主键的get方法前添加@Id标签就可以了。 
*别忘了mapping文件,只要对User和Authorities两个类做映射就行了,不用做那个AuthoritiesPK的。 

二。一对多关联 
    我原先的设置是这样的,这是个错误的配置。 

Java代码  
@OneToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
@JoinTable(name="authorities", 
joinColumns=@JoinColumn(name="username")) 
public Set getGrantedAuthorities() { 
        return grantedAuthorities; 
}

    这样配置最后在生成表的时候,User和Authorities关联会多出来两个列"grantedAuthorities_username"和"grantedAuthorities_password"并且在使用过程中会出错。 
    正确的配置如下: 
Java代码  
@OneToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
@JoinColumn(name="username") 
public Set getGrantedAuthorities() { 
        return grantedAuthorities; 

    这样Authorities表中的username属性就被正确的和User表中的username关联起来的。 

*重要的提示!  
    顺带一提的事这个JoinColumn的意义是从表(Authority)中的这个字段(username)和主表(User)的主键(username这个不是配置里面的那个username要注意哦!)相互关联。 



你可能感兴趣的:(hibernate)