Mybatis 子查询 - mybatis select child object
最近有这样一个需求,查询符合条件的 3D 图纸包的信息以及该图纸包里包含的图纸的信息,这显然是查询一个对象的子属性,于是有了本文,本文将讲述 mybatis 子查询,即 return a list inside an object from mybatis.
mybatis 子查询主要用到 collection 属性,如下:
|
|
这里,xxx.xxx.xxx.xxx 是具体的类名,关系到公司的实际业务,此处略过,下面的 ofType 也可以是实际的类名,如果是实际的类名,那么可能所有的字段将都会返回了,如果不想要返回所有的字段,可以设为 java.util.Map,下面细说下 collection 属性 property 表示这个对象的字段的名称,即子查询的结果在 xxx.xxx.xxx.xxx 里对应的变量的名称,为方便起见 下文称 xxx.xxx.xxx.xxx 为 Parent.java ,则 Parent.java 应该如下:
这里忽略了其他别的变量哦,主要是变量名 paperList 要和 collection 里面的 property 对应。 javaType 表示这个子查询返回值的类型,即 paperList 的类型,这里是 java.util.List,而 ofType 指的是映射到 paperList 里面的元素的类型,这里是 java.util.Map,关键是 column,它实际是传参,你可以这么理解,column="{传入子查询的参数名 = 对应的 Parent 里面的字段名,…}" ,这里传入子查询的参数名是 packageId,对应 Parent 里的 id,下面看下具体的 sql
|
|
这里 xxx 表示图纸的数据库,xxx2 是图纸和图纸包的关联数据库,xxx3 是图纸包数据库,该查询(findByCourseId)的查询结果可能如下:
|
|
当然,你可以修改 Parent.java 里的 map 为具体的类型,比如 我这里为 3D 图纸的类型,然后修改 ofType 以及 resultType 为具体的类型,这样你拿到的数据类型也是对的,但是返回的数据可能有冗余,并且不支持起别名哦。
总体而言,我还是觉得用 map 更好点,但是如果返回的数据你还要操作,比如读取值,那么使用具体的类型可能更好。
2019.11.04 更新 :添加 fetchType=“eager” 如果不添加 可能会出现:
Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.apache.ibatis.executor.loader.javassist.JavassistProxyFactory$EnhancedResultObjectProxyImpl and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: java.util.HashMap[“data”]->java.util.ArrayList[0]->xxx.xxx.xxx_$$_jvst4a2_0[“handler”])
如果出现这个错误,那么将:
<collection property="paperList" javaType="java.util.List" ofType="java.util.Map" column="{packageId=id}" select="paperList"> </collection>
改为如下即可:
<collection property="paperList" javaType="java.util.List" ofType="java.util.Map" column="{packageId=id}" select="paperList" fetchType="eager"> </collection>