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的。

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

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要注意哦!)相互关联。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Hibernate配置联合,可以通过使用 @IdClass 或 @EmbeddedId 注解来实现。 1. 使用 @IdClass 注解: 首先,需要创建一个用于表示联合的类,该类需要实现 Serializable 接口,并且需要包含所有联合字段。例如: ``` public class MyCompositeKey implements Serializable { private Long id1; private Long id2; // constructors, getters, setters, equals, hashCode, etc. } ``` 然后,在实体类中使用 @IdClass 注解,并指定联合类的名称。例如: ``` @Entity @IdClass(MyCompositeKey.class) public class MyEntity { @Id private Long id1; @Id private Long id2; // other entity fields, getters, setters, etc. } ``` 2. 使用 @EmbeddedId 注解: 首先,需要创建一个用于表示联合的类,该类需要实现 Serializable 接口,并且需要使用 @Embeddable 注解标记。例如: ``` @Embeddable public class MyCompositeKey implements Serializable { private Long id1; private Long id2; // constructors, getters, setters, equals, hashCode, etc. } ``` 然后,在实体类中使用 @EmbeddedId 注解,并指定联合类的名称。例如: ``` @Entity public class MyEntity { @EmbeddedId private MyCompositeKey id; // other entity fields, getters, setters, etc. } ``` 以上就是在 Hibernate配置联合的两种方式。需要注意的是,使用 @IdClass 注解时需要在实体类中指定所有联合字段,而使用 @EmbeddedId 注解时只需要在联合类中指定即可。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值