我有一个由Spring MVC框架构建的RESTful项目,带有Mybatis ORM。
有两个表,Book和Author,具有一对多关系。

我启用了延迟加载,这样当我查询Book时,它不会查询Author,除非我调用book.getAuthor()方法,一切都很正常。
mybatis-config.xml:启用延迟加载

BookMapper.xml

然而,当RESTful控制器返回Book对象时,它使用Jackson将Book对象传递给json,并触发mybatis加载Author对象。
控制器:在第30行,它只查询Book。


在第31行之后,它还查询Author

有没有办法防止mybatis在RESTful控制器返回json时触发延迟加载?
发布于 2018-03-28 05:49:16
问题不在mybatis。问题出在序列化上。如果属性被查询,mybatis别无选择,只能加载属性。
解决方案是配置序列化,这样authors属性就不会序列化。
例如,可以使用Jackson MixIns来完成此操作
首先,创建用于指定附加配置的mix-in:
abstract class NoAuthorsMixIn {
@JsonIgnore abstract List<Author> authors();
}然后,您需要将此混入添加到spring使用的jackson映射器配置中。确切的方式取决于您使用的是xml配置还是java配置。对于java配置,如下所示:
@Configuration
public class JacksonConfiguration {
@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(Book.class, NoAuthorsMixIn.class);
return mapper;
}
}请注意,这将禁用所有控制器方法中的authors序列化。如果您需要能够根据控制器和/或控制器方法来切换它,则设置会更加复杂(例如,查看this )。
发布于 2018-03-28 09:57:34
我找到了一个解决方案,不是最好的,但它是有效的。仍然期待一个更好的解决方案。
当杰克逊序列化图书对象时,它触发了Book.getAuthors(),Mybatis检测到Book.getAuthors()被调用,因此Mybatis通过Javassist代理执行延迟加载,如下所示:

请注意,“任何调用getter的人都会触发延迟加载”(红圈),这就是Jackson总是在序列化中触发延迟加载的原因!
为了解决这个问题,我修改了Book bean:
@JsonIgnore on Book.getAuthors(),防止杰克逊在Book.loadDetail()上调用getAuthors().@JsonGetter(value = "authors"),这样当杰克逊可以序列化作者时,就不会触发延迟加载。

结果如下:




https://stackoverflow.com/questions/49486951
复制相似问题