您好,登录后才能下订单哦!
本篇内容介绍了“Spring JPA联表查询之OneToMany怎么使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
@OneToMany 注解实现一对多关系映射。比如用户跟房子的关系, 一个用户可以有好多房子,而一个房子只能一个用户。
老规矩,实例之前先看看源码:
public @interface OneToMany { Class targetEntity() default void.class; CascadeType[] cascade() default {}; FetchType fetch() default LAZY; String mappedBy() default ""; boolean orphanRemoval() default false; }
注解属性详情请见 注解属性详解,其中需要注意的是 @OneToMany 的 fetch 的默认值是 LAZY。
我这里所说的单向联表就是只有一方添加注解;通俗讲就是我可以通过 user 获取到其 house 的信息,而不同通过 house 获取到其 user 的信息。
因为对方是 many 多端,所以这边需要用 List 集合
@Entity @Data public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; private String name; private int age; @OneToMany @JoinColumn(name = "user_id") private List<House> house; }
@Entity @Data public class House { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; private String addr; }
小贴士
实例运行之后,大家肯定会发现一个奇怪的问题:user_id 字段明明写在了 user 实体类中,但是实际却添加在 house 表中,这是为啥呢?
因为在 JPA 规范中,一对多的双向关系是由 多端(many) 来维护。就是说 多端(many) 为关系维护端,负责关系的增删改查;一端(one) 则为关系被维护端。
执行请求/user/findById?id=1
,控制台打印如下:
Hibernate: select user0_.id as id1_2_0_, user0_.age as age2_2_0_, user0_.name as name3_2_0_ from user user0_ where user0_.id=? Hibernate: select house0_.user_id as user_id3_1_0_, house0_.id as id1_1_0_, house0_.id as id1_1_1_, house0_.addr as addr2_1_1_ from house house0_ where house0_.user_id=?
User(id=1, name=lili, age=11, house=[House(id=1, addr=江苏南京), House(id=2, addr=江苏无锡), House(id=3, addr=江苏苏州)])
我们除了需要通过 user 信息来获取其 house 信息外,有时还需要通过 house 信息来获取其 user 信息。但是需要注意的是 user 对于 house 来说,是一对多;而 house 对于 user 来说,是多对一。这时我们就需要引入另一个联表注解 @ManyToOne
,在 house 的实体中添加 user 字段,并添加 @ManyToOne
注解。(这里有一个堆栈溢出的问题需要注意一下,详情请见 JPA 错题集 第二个报错信息)
user 实体中 house 字段
@OneToMany @JoinColumn(name = "user_id") @JsonIgnore public List<House> house;
@ManyToOne @JsonIgnore private User user;
执行请求 /house/findById?id=1
,控制台打印如下:
Hibernate: select house0_.id as id1_1_0_, house0_.addr as addr2_1_0_, house0_.user_id as user_id3_1_0_, user1_.id as id1_2_1_, user1_.age as age2_2_1_, user1_.name as name3_2_1_ from house house0_ left outer join user user1_ on house0_.user_id=user1_.id where house0_.id=? 2023-04-27 20:35:29.940 TRACE 24272 --- [nio-7777-exec-6] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [INTEGER] - [1]
有同学可能已经发现了,当添加了 @JsonIgnore
这个属性之后
执行请求 /user/findById?id=1
,控制台打印如下:
Hibernate: select user0_.id as id1_2_0_, user0_.age as age2_2_0_, user0_.name as name3_2_0_ from user user0_ where user0_.id=? [nio-7777-exec-1] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [INTEGER] - [1]
只取进行用户信息的查询,那我的 house 怎么办呢?别急,我会给你们找回来的!
User 的 control 层
@GetMapping("findById") public Optional<User> findById(int id){ Optional<User> users = userService.findById(id); users.get().getHouse().forEach(v->{ System.out.println(v.getId() + "-"+ v.getAddr()); }); return userService.findById(id); }
执行请求 /user/findById?id=1
,控制台打印如下:
Hibernate: select house0_.user_id as user_id3_1_0_, house0_.id as id1_1_0_, house0_.id as id1_1_1_, house0_.addr as addr2_1_1_, house0_.user_id as user_id3_1_1_ from house house0_ where house0_.user_id=? [nio-7777-exec-1] o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [INTEGER] - [1] 1-南京 2-苏州 3-无锡
“Spring JPA联表查询之OneToMany怎么使用”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。