mybatis关联查询,为什么我的方式不对?

JoeBlackzqq 2019-05-07 02:14:47
mybatis关联查询,我的方式测试通过,但是结果不正确,错哪了?

表结构:

CREATE TABLE `d_shop_sku` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(32) COLLATE utf8mb4_bin DEFAULT NULL,
`category_id` bigint(20) unsigned DEFAULT NULL,
`attribute_ids` varchar(32) COLLATE utf8mb4_bin DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

CREATE TABLE `d_shop_attribute` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`sku_id` bigint(20) unsigned DEFAULT NULL,
`name` varchar(32) COLLATE utf8mb4_bin DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;


表数据:



我的代码:
generateConfig.xml

<table tableName="d_shop_sku" domainObjectName="ShopSku" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false">
<generatedKey column="id" sqlStatement="MySql" identity="true" />
<columnOverride column="attribute_ids" javaType="java.util.List" typeHandler="com.zcm.mybatis.typehandler.IntegerListTypeHandler" />
</table>
<table tableName="d_shop_attribute" domainObjectName="ShopAttribute" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false">
<generatedKey column="id" sqlStatement="MySql" identity="true" />
</table>


自定义一个pojo类: ShopSku

package com.zcm.mybatis.dao.pojo;

import lombok.Getter;
import lombok.Setter;

import java.util.List;


public class ShopSku extends com.zcm.mybatis.dao.entity.ShopSku {

@Getter
@Setter
private List attributes;

}



自定义一个ShopSkuDao.xml, 片断:

<resultMap id="AttributeResultMap" type="com.zcm.mybatis.dao.entity.ShopAttribute">
<id column="id" jdbcType="BIGINT" property="id" />
<result column="sku_id" jdbcType="VARCHAR" property="skuId" />
<result column="name" jdbcType="VARCHAR" property="name" />
</resultMap>

<resultMap id="BasePlusResultMap3" type="com.zcm.mybatis.dao.pojo.ShopSku">
<id column="id" jdbcType="BIGINT" property="id" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="category_id" jdbcType="BIGINT" property="categoryId" />
<result column="attribute_ids" jdbcType="VARCHAR" property="attributeIds" javaType="java.util.List" typeHandler="com.zcm.mybatis.typehandler.IntegerListTypeHandler" />
<collection column="attributeIds" property="attributes" ofType="com.zcm.mybatis.dao.entity.ShopAttribute" select="getAttribute3">
</collection>
</resultMap>

<select id="getById3" resultMap="BasePlusResultMap3">
select * from d_shop_sku
where id = #{id,jdbcType = BIGINT}
</select>

<select id="getAttribute3" resultMap="AttributeResultMap">
select * from d_shop_attribute
where id in
<foreach collection="list" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</select>


一个测试接口:

@Test
public void getById3() // 单参数: Long
{
var sku = shopSkuDao.getById3(1L);
System.out.println(sku == null);
if(sku != null)
{
System.out.println(JSON.toJSONString(sku, SerializerFeature.WRITE_MAP_NULL_FEATURES));
}
}


运行结果一切都正常,除了attributes,这个结果是[], 明显结果是不正确的!


2019-05-07 14:00:28.436 INFO 36522 --- [ main] com.zaxxer.hikari.HikariDataSource : test - Starting...
2019-05-07 14:00:28.704 INFO 36522 --- [ main] com.zaxxer.hikari.HikariDataSource : test - Start completed.
2019-05-07 14:00:28.722 DEBUG 36522 --- [ main] com.zcm.mybatis.dao.ShopSkuDao.getById3 : ==> Preparing: select * from d_shop_sku where id = ?
2019-05-07 14:00:28.786 DEBUG 36522 --- [ main] com.zcm.mybatis.dao.ShopSkuDao.getById3 : ==> Parameters: 1(Long)
2019-05-07 14:00:28.844 DEBUG 36522 --- [ main] com.zcm.mybatis.dao.ShopSkuDao.getById3 : <== Total: 1
false
{attributes:[],name:"桔子1",id:1,attributeIds:[3,1],categoryId:2}



关键的地方应该是collection里的东西,attributeIds已经通过typeHandler转换为List<Integer>,我想把这个attributeIds传递给子查询,但是发现并不对,请高人解答下!
...全文
363 5 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhanghaishuai 2019-05-08
  • 打赏
  • 举报
回复
引用 2 楼 JoeBlackzqq 的回复:
[quote=引用 1 楼 zhanghaishuai 的回复:] <collection column="attributeIds" property="attributes" ofType="com.zcm.mybatis.dao.entity.ShopAttribute" select="getAttribute3"> </collection> 上面的column应该是关联的某个列名或者列的别名,即关联的是attribute_ids,如果是这样的话,拿到的是字符串(根据你表中的数据),那么级联查询的sql就不能接收Iterator。 至于可不可以传入handler处理后的值,可以去找下相关的文档 <collection column="{list=attributeIds}" property="attributes" ofType="com.zcm.mybatis.dao.entity.ShopAttribute" select="getAttribute3"> </collection> select * from d_shop_attribute where id in (${list})
你这种方式,我试过,确实是可以的,但是当attribute_ids为空字符串或null时, 这个会报错, 因为in () , 括号里什么都没有, 有没有办法当attribute_ids为空时,不执行这个关联查询呢?[/quote] 这个我不知道怎么配置能让不执行关联查询,不过可以在子查询中判断一下,如果是null或空字符串,可以执行一个默认的查询
JoeBlackzqq 2019-05-08
  • 打赏
  • 举报
回复
<select id="getAttribute3" resultMap="AttributeResultMap">
select * from d_shop_attribute
where
<if test="ids != ''">
id in (${ids})
</if>
<if test="ids == ''">
1 = 2
</if>
</select>

改为上述这样,能满足有值时进行查询,没有值时故意让查询结果为空!

这应该是非常规做法,尽量不采用!
JoeBlackzqq 2019-05-08
  • 打赏
  • 举报
回复
引用 3 楼 zhanghaishuai 的回复:
[quote=引用 2 楼 JoeBlackzqq 的回复:]
[quote=引用 1 楼 zhanghaishuai 的回复:]
<collection column="attributeIds" property="attributes" ofType="com.zcm.mybatis.dao.entity.ShopAttribute" select="getAttribute3">
</collection>

上面的column应该是关联的某个列名或者列的别名,即关联的是attribute_ids,如果是这样的话,拿到的是字符串(根据你表中的数据),那么级联查询的sql就不能接收Iterator。
至于可不可以传入handler处理后的值,可以去找下相关的文档

<collection column="{list=attributeIds}" property="attributes" ofType="com.zcm.mybatis.dao.entity.ShopAttribute" select="getAttribute3">

</collection>

select * from d_shop_attribute where id in (${list})


你这种方式,我试过,确实是可以的,但是当attribute_ids为空字符串或null时, 这个会报错, 因为in () , 括号里什么都没有, 有没有办法当attribute_ids为空时,不执行这个关联查询呢?[/quote]

这个我不知道怎么配置能让不执行关联查询,不过可以在子查询中判断一下,如果是null或空字符串,可以执行一个默认的查询[/quote]

<where>标签是用于控制where条件的,但是查询是必然会执行的。
执行一个默认查询,如做一个对结果无影响的查询或使查询结果为空的条件,虽然可以,但是步骤上感觉是多余的。我这个查询似乎并不属于关联查询(而是有前提的关联查询),它这里关联查询的前提是关联字段绝对有值的,所以跟我的适用范围不一样!

后来我想了想,还是在service层弄个接口来对查询查询再进行一次关联查询,这样自己就能按条件控制是否进行关联查询了!

谢谢你的方案!
JoeBlackzqq 2019-05-07
  • 打赏
  • 举报
回复
引用 1 楼 zhanghaishuai 的回复:
<collection column="attributeIds" property="attributes" ofType="com.zcm.mybatis.dao.entity.ShopAttribute" select="getAttribute3">
</collection>

上面的column应该是关联的某个列名或者列的别名,即关联的是attribute_ids,如果是这样的话,拿到的是字符串(根据你表中的数据),那么级联查询的sql就不能接收Iterator。
至于可不可以传入handler处理后的值,可以去找下相关的文档

<collection column="{list=attributeIds}" property="attributes" ofType="com.zcm.mybatis.dao.entity.ShopAttribute" select="getAttribute3">

</collection>

select * from d_shop_attribute where id in (${list})


你这种方式,我试过,确实是可以的,但是当attribute_ids为空字符串或null时, 这个会报错, 因为in () , 括号里什么都没有, 有没有办法当attribute_ids为空时,不执行这个关联查询呢?
zhanghaishuai 2019-05-07
  • 打赏
  • 举报
回复
<collection column="attributeIds" property="attributes" ofType="com.zcm.mybatis.dao.entity.ShopAttribute" select="getAttribute3"> </collection> 上面的column应该是关联的某个列名或者列的别名,即关联的是attribute_ids,如果是这样的话,拿到的是字符串(根据你表中的数据),那么级联查询的sql就不能接收Iterator。 至于可不可以传入handler处理后的值,可以去找下相关的文档 <collection column="{list=attributeIds}" property="attributes" ofType="com.zcm.mybatis.dao.entity.ShopAttribute" select="getAttribute3"> </collection> select * from d_shop_attribute where id in (${list})

81,122

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧