hibernate联合主键生成策略以及一对多配置
1:一般能用一个字段做主键的就不要用两个字段,不过不可避免的会遇到要用两个字段做主键,此时要用hibernate,可以使用联合主键。如图:要用id和name做主键
办法:单独设计一个类,起名StudentPK,在该类必须重写equals,hashcode,实现Serializable接口。
此时在Student类中可以删除掉id和name的属性及get/set方法,但是必须加入新的属性,该属性的类型是StudentPK,如:private StudentPK pk;然后生成get/set方法,此时要想存一个Student,首先:new一个StudentPK,然后如图:
此时还不够,还必须在配置文件中告诉你哪个是主键?
ps:
为什么实现serise接口?因为ser是序列化的,是将该类序列化然后写到硬盘上的。
作为student这个对象,它在数据库表中可能存在着多条记录,这多条记录如果我们把它放到内存里的话就是多个对象,这多个对象,假如现在被放到了内存中都是student,那么你可以想象每个student对象都有一个主键对象(StudentPK),假如要做集群,有多台服务器,这台宕机了,我们可以序列化,还有一种情况,内存满了,我可以使用虚拟内存,就是把我们硬盘上的一部分空间作为内存来使用,在这种情况下,我们就可以把上面那些内容暂时放到要硬盘上去,所以这个时候就需要实现序列化了。
如图:
为什么要重写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的。
二。一对多关联
我原先的设置是这样的,这是个错误的配置。
正确的配置如下:
*重要的提示!
顺带一提的事这个JoinColumn的意义是从表(Authority)中的这个字段(username)和主表(User)的主键(username这个不是配置里面的那个username要注意哦!)相互关联。