@OneToOne @ManyToMany使用不做过多解释,重点解决“懒加载无效问题”。
示例:
@OneToMany
teacher 和 student是一对多关系
只需要在studentList上使用@OneToMany注解,对应的参数为 懒加载、级联操作、子表外键
我为了验证懒加载是否生效,在debug模式下发现懒加载并没有生效。在正常模式下,返回到页面也是有studentList的数据。于是开始排坑,逐渐怀疑人生。。
直到看到了某国际友人说的这么一句话。
It seems to be a debugging artifact.
At debugging time, because the transaction is still open, the watched
lazy loaded entity properties will be loaded at the breakpoint
evaluation time.
于是在application.properties中加上spring.jpa.show-sql=true
,打开执行的SQL。
debug下,执行到29行,共执行了以下两句SQL:
Hibernate: select teacher0_.id as id1_1_0_, teacher0_.age as age2_1_0_, teacher0_.name as name3_1_0_ from teacher teacher0_ where teacher0_.id=?
Hibernate: select studentlis0_.teacher_id as teacher_4_0_0_, studentlis0_.id as id1_0_0_, studentlis0_.id as id1_0_1_, studentlis0_.addr as addr2_0_1_, studentlis0_.name as name3_0_1_, studentlis0_.teacher_id as teacher_4_0_1_ from student studentlis0_ where studentlis0_.teacher_id=?
开始只查询了teacher表,紧接着进行了关联查询,结合上面那句话猜测可能是debug导致的。而在正常模式下启动,也是两条SQL,猜测可能是返回前端时,序列化自动调用了getStudentList()方法,导致执行了第二条SQL。
于是新建TeacherDto.class
并在controller中return teacherDto,不直接返回teacher。
在正常模式下启动,果然只有一条SQL,没有进行级联查询。
Hibernate: select teacher0_.id as id1_1_0_, teacher0_.age as age2_1_0_, teacher0_.name as name3_1_0_ from teacher teacher0_ where teacher0_.id=?
至此踩坑结束……
总结:
在使用@OneToOne、@OneToMany、@ManyToMany时,只需要加上参数fetch = FetchType.LAZY
即可。
在debug模式下,会自动进行级联查询,导致懒加载无效,可能是idea方便开发人员调试,故意这样设置的。
在接口返回时,避免直接返回entity,可返回Dto或Vo。
希望能帮你脱坑!