JPA多对多关联如何按标签添加到Post的时间排序?改用List会影响性能吗?
需求实现可行性
该需求完全可以实现,先修正你现有代码的一处配置错误:当前@JoinTable的inverseJoinColumns指向了post_id,属于笔误,正确配置应该指向Tag表的主键,可参考如下最终实现代码:
@Entity public class Post{ private Long id; @ManyToMany(fetch = FetchType.LAZY) @JoinTable(name = "tag_posts", joinColumns = @JoinColumn(name = "post_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "tag_id", referencedColumnName = "id")) @OrderColumn(name = "tag_add_order") private List<Tag> hashtags= new ArrayList<>(); }
要实现按「添加到Post的先后顺序」排序,最优方案是搭配@OrderColumn注解使用List类型的属性:
- JPA会自动在关联中间表
tag_posts中新增一个排序字段(上述代码指定为tag_add_order),专门存储每个Tag被添加到当前Post的顺序 - 新增、删除关联关系时,JPA会自动维护该排序字段的数值
- 查询关联数据时,JPA会自动按该字段升序排序,返回的顺序和添加顺序完全一致
如果不新增排序字段,仅靠内存中的LinkedHashSet无法持久化顺序,重新从数据库查询后返回的集合顺序是数据库默认的返回顺序,和添加顺序无关。
修改为List的性能影响
是否有性能损耗取决于你是否正确搭配注解:
- 正确搭配@OrderColumn使用:性能损耗极低,仅在修改关联关系时需要多维护一个排序字段的数值,查询时仅多一个排序条件,常规业务场景下完全可以忽略该影响。
- 未加@OrderColumn直接使用List:性能损耗非常大,此时JPA会将该关联识别为无序列表(Bag类型),不仅无法保证返回顺序,执行删除、更新关联的操作时,会先删除当前Post对应的所有中间表记录,再批量插入全部新的关联记录,数据量大时性能下降明显,不推荐使用。
内容的提问来源于stack exchange,提问作者user13505963
相关产品推荐
相关产品推荐

