0
点赞
收藏
分享

微信扫一扫

疑似mybatis的bug:Example动态拼接字符串,报错sql错误

问题

本地pom

<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.1.5</version>
</dependency>

<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-base</artifactId>
<version>1.1.5</version>
</dependency>

 

java代码

//查询是否有正在包装的栈板号
Example example = new Example(Pallet.class);
example.createCriteria()
.andEqualTo("fWoid", palletDTO.getFWoid())
.andNotEqualTo("palletId", palletDTO.getPalletId())
.andEqualTo("status", 0);
example.setTableName(format("pallet_%s", projectName));

XxxMapper.selectOneByExample(example);

 

正常情况下的sql语句(pallet_id带入整数)

SELECT *
FROM pallet_WX10
WHERE (f_woid = 39 and pallet_id <> '10' and status = 0)
LIMIT 1;

 

pallet带入字符串

SELECT * FROM pallet_QWQ001 WHERE (f_woid = 42 and pallet_id <> CONCAT("'",ZHANBAN1,"'") and status = 0);

疑似mybatis的bug:Example动态拼接字符串,报错sql错误_java代码

 

 

笔者猜测,框架可能根据pallet后缀id去猜解字段数据类型了。

解决方法

1、手工写sql

解决方法1

<select id="queryOne" resultType="com.h2.mes.entity.Pallet">
<![CDATA[
SELECT * FROM pallet_${projectName} WHERE (f_woid = #{fWoid} and pallet_id <> '${palletId}' and status = 0) limit 1
]]>
</select>

解决方法2(2021-12-5)

<select id="queryOne" resultType="com.h2.mes.entity.Pallet">
<![CDATA[
SELECT * FROM pallet_${projectName} WHERE (f_woid = #{fWoid} and pallet_id <> #{palletId,jdbcType=VARCHAR} and status = 0) limit 1
]]>
</select>

 

2、java代码

 

//查询是否有正在包装的栈板号
Map<String,Object> condition = ImmutableMap.<String,Object>builder()
.put("fWoid", palletDTO.getFWoid())
.put("palletId", palletDTO.getPalletId())
.put("projectName", projectName)
.build();
final Pallet availPallet = palletMapper.queryOne(condition);
if (availPallet != null) {
return new JsonResult(PACK1, PALLET_EXIST_UNFINISHED, availPallet);
}

 一点思考

如果能重载一些方法,添加形参可能有办法解决这个问题。比如一些框架中形参会有

JavaType type
JdbcType type


#官方既有方法
public Criteria andNotEqualTo(String property, Object value) {
addCriterion(column(property) + " <>", value, property(property));
return (Criteria) this;
}

#重载示例如下
public Criteria andNotEqualTo(String property, Object value,JavaType type) {
....
}

public Criteria andNotEqualTo(String property, Object value,JdbcType type) {
.....
}

让用户在一些字段数据类型模棱两可的情况下,可以自定义类型,让框架去处理。

2021-12-5更新:

经过笔者对源代码的了解,需要改造的地方比较多,要大改:

疑似mybatis的bug:Example动态拼接字符串,报错sql错误_java代码_02

 

 还有tk.mybatis.mapper.entity.Mapper,这里要大改

疑似mybatis的bug:Example动态拼接字符串,报错sql错误_字段_03

疑似mybatis的bug:Example动态拼接字符串,报错sql错误_java代码_04

其他参考:

MyBatis中的JdbcType映射介绍_bisal的专栏

举报

相关推荐

0 条评论