解决mybatis 中collection嵌套collection引发的bug
作者:AndyMocan 发布时间:2023-03-20 20:55:39
我就废话不多说了,大家还是直接看代码吧~
<resultMap id="ParentMap" type="org.example.mybatis.Parent">
<id column="Id" jdbcType="VARCHAR" property="id" />
<result column="Name" jdbcType="VARCHAR" property="name" />
<result column="SurName" jdbcType="VARCHAR" property="surName" />
<collection property="children"
javaType="ArrayList" ofType="org.example.mybatis.Child"
resultMap="ChildMap" columnPrefix="c_"/>
</resultMap>
<resultMap id="ChildMap" type="org.example.mybatis.Child">
<id column="Id" jdbcType="VARCHAR" property="id" />
<result column="ParentId" jdbcType="VARCHAR" property="parentId" />
<result column="Name" jdbcType="VARCHAR" property="name" />
<result column="SurName" jdbcType="VARCHAR" property="surName" />
<result column="Age" jdbcType="INTEGER" property="age" />
<collection property="toys"
javaType="ArrayList" ofType="org.example.mybatis.Toy"
resultMap="ToyMap" columnPrefix="t_"/>
</resultMap>
<resultMap id="ToyMap" type="org.example.mybatis.Toy">
<id column="Id" jdbcType="VARCHAR" property="id" />
<result column="ChildId" jdbcType="VARCHAR" property="childId" />
<result column="Name" jdbcType="VARCHAR" property="name" />
<result column="Color" jdbcType="VARCHAR" property="color" />
</resultMap>
<sql id="Parent_Column_List">
p.Id, p.Name, p.SurName,
</sql>
<sql id="Child_Column_List">
c.Id as c_Id, c.ParentId as c_ParentId, c.Name as c_Name, c.SurName as c_Surname, c.Age as c_Age,
</sql>
<sql id="Toy_Column_List">
t.Id as t_Id, t.Name as t_Name, t.Color as t_Color
</sql>
<select id="getParent" parameterType="java.lang.String" resultMap="ParentMap" >
select
<include refid="Parent_Column_List"/>
<include refid="Child_Column_List" />
<include refid="Toy_Column_List" />
from Parent p
left outer join Child c on p.Id = c.ParentId
left outer join Toy t on c.Id = t.ChildId
where p.id = #{id,jdbcType=VARCHAR}
</select>
表面来看没有任何问题 实际 查询的child对象中的toys一直是空
类关系介绍:
Parent类有属性ArrayList<Child> children
Child类有属性ArrayList<Toy> toys
Toy是一个普通的类
原因在于:
<collection property="toys"
javaType="ArrayList" ofType="org.example.mybatis.Toy"
resultMap="ToyMap" columnPrefix="t_"/>
columnPrefix配置的是t_实际mybatis处理后是 c_t_
解决办法:
只需要修改 sql 修改前缀为 c_t_ 即可
<sql id="Toy_Column_List">
t.Id as c_t_Id, t.Name as c_t_Name, t.Color as c_t_Color
</sql>
补充知识:mybatis 嵌套的结果集不能被安全的转为自定义ResultHandler 的解决办法
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.executor.ExecutorException: Mapped Statements with nested result mappings cannot be safely used with a custom ResultHandler. Use safeResultHandlerEnabled=false setting to bypass this check.
问题描述
session.select("dao.ArticleMapper.selectAll", null, new RowBounds(1, 2),resultHandler);
会报不安全, 查询Configuration 源码发现里面有一个常量是
public Configuration() {
this.safeRowBoundsEnabled = false;
this.safeResultHandlerEnabled = true;//意思是不允许自定义ResultHand 处理器,
this.mapUnderscoreToCamelCase = false;
this.aggressiveLazyLoading = true;
解决办法
public static SqlSession getsqlSession(){
SqlSession session = sqlSessionFactory.openSession(ExecutorType.REUSE);
Configuration configuration = session.getConfiguration(); //反射得到configuration ,然后
configuration.setSafeResultHandlerEnabled(false); // 设置为false
return session;
}
这样就可以了。
来源:https://blog.csdn.net/AndyMocan/article/details/83059459


猜你喜欢
- 冒泡排序原理:从头(左边)开始比较每一对相邻的元素,如果第1个比第2个大,就交换它们的位置,执行完一轮后,最末尾(最右边)就是最大的元素。举
- 对于javascript的冒泡,我一直误解它了,冒泡,即是从底层往外blow blow blow ...惭愧的是,我一直以为阻止冒泡是阻止父
- 1、添加maven依赖<dependency>
- 这一篇我们说说Java线程Thread的interrupt中断机制。中断线程线程的thread.interrupt()方法是中断线程,将会设
- 一、之前旧的写法class Singleton{ private Singleton() {} &nb
- 1:定义一个自己的父级容器,让它继承自一个布局(LinearLayout、RelativeLayout都可以)public class Si
- 比较适合新手。逻辑上仍然有点问题。可以用于学习java文件操作下载地址:http://yun.baidu.com/share/link?sh
- 本文实例讲述了Spring Bean的初始化和销毁。分享给大家供大家参考,具体如下:一 点睛在开发过程中,经常遇到在Bean使用之前或者之后
- swagger简介Swagger是一款RESTful接口的文档在线自动生成、功能测试功能框架。一个规范和完整的框架,用于生成、描述、调用和可
- 本文实例为大家分享了Android实现滑动屏幕切换图片的具体代码,供大家参考,具体内容如下activity_main.xml 文件代码:&l
- Spring BeanPostProcessor执行顺序首先 Spring 通过调用构造方法创建 User 对象;User 对象创建好之后,
- Looper是什么用于为线程运行消息循环的类。默认情况下,线程没有与之关联的消息循环。要创建一个,在要运行循环的线程中调用 prepare(
- 前言Android底层服务,即运行在 linux 下的进程,是 Android 系统运行的基础,完成 Android 或者说计算机最基本的功
- 文章描述这个程序也记不清是什么时候写的了,犹记得那时我还很年轻,偶然从网上看到了这样一个类似的标题(AI五子棋的实现),进去后看到那个是ja
- 本文实例为大家分享了Android判断当前App状态的具体实现代码,供大家参考,具体内容如下第一种: /** *判断当前应用程序
- 锁作为并发共享数据,保证一致性的工具,在JAVA平台有多种实现(如 synchronized 和 ReentrantLock等等 ) 。这些
- Java基本类型与byte数组之间相互转换,刚刚写的package cn.teaey.utils;import java.nio.chars
- 本文实例讲述了Android滑动按钮事件。分享给大家供大家参考,具体如下:今天纪录一下滑动按钮功能。。首先效果图:然后是分别建立三个文件,第
- C语言运算符及其优先级汇总表口诀圆下箭头一顿号非凡增减富强针地长三乘除,四加减,五移位千万别把鱼忘记,它在盛饭的厨子里小灯大灯灯灯不等爸喂鱼
- 安卓项目开发中,项目中使用到jni开发,使用C/C++编写了自己的so库,调试和运行一切正常,Android.mk文件代码如下:LOCAL_