Mybatis使用中的几个问题

1 篇文章 0 订阅
1 篇文章 0 订阅

Mybatis使用中的几个问题

  • mapper.xml中允许入参为null
  • interface mapper.java与mapper.xml自动注入绑定

入参为NULL

当入参为NULL的时候一般会做下面的处理

  • 使用动态SQL:
<select id="getDept" parameterType="haspMap" resultType="haspMap">
select * from dept where 1=1 <if test="dept_id != null">and dept_id = #{dept_id}</if>
</select>

这样本来没什么问题的,之前写代码的时候也都是采用这种方式,也没觉得什么,偶然看到一篇关于这方面优化的文章,提到少用动态SQL这一点,说是解析会多加空格呀,想测试SQL正确性时拷贝出来还要一个个删掉if等控制真麻烦之类的一堆理由,具体会不会优化不清楚,但想到测试这一块说的确实是那回事,就想着以后还是写的时候少些动态的吧,然后就修改成下面的语句试验一把

<!-- 错误的写法  -->
<select id="getDept" parameterType="haspMap" resultType="haspMap">
select * from dept where dept_id = nvl(#{dept_id},dept_id)
</select>

结果报错了:

“nested exception is org.apache.ibatis.type.TypeException: Could not set parameters for mapping: ParameterMapping{property=’dept_id’, mode=IN, javaType=class java.lang.String, jdbcType=null, numericScale=null, resultMapId=’null’, jdbcTypeName=’null’, expression=’null’}. Cause: org.apache.ibatis.type.TypeException: Error setting null for parameter #3 with JdbcType OTHER . Try setting a different JdbcType for this parameter or a different jdbcTypeForNull configuration property. Cause: java.sql.SQLException: 无效的列类型: 1111”

查阅资料后说是

由于参数出现了null值,对于Mybatis,如果进行操作的时候,没有指定jdbcType类型的参数,mybatis默认jdbcType.OTHER导致,给参数加上jdbcType可解决(注意大小写)

于是改成下面形式

<select id="getDept" parameterType="haspMap" resultType="haspMap">
select * from dept where dept_id = nvl(#{dept_id,jdbcType=VARCHAR},dept_id)
</select>

修改后执行正常。
个人觉得总把jdbcType写上去会安全些,虽说麻烦

interface mapper.java与mapper.xml自动注入绑定

在已有的框架基础上修修补补追加功能很多问题都发现不了,在学习spring boot的时候将autoconfigure模式转成xml模式时碰到了各种问题

路径问题

这个问题也是搞不清楚了,现在只知道的是classpath对应[src/main/java]和[src/main/resource],如果是web的话还有个[WEB-INF]吧,资源文件的话最好都放在[src/main/resource]下面

比较怪的是我把mybatis-config.xml放在[src/main/resource]下面,然后在application.properties里面用下面的方式配置的时候总说找不到对应xml

#application.properties
mybatis.config-location=classpath:/mybatis-config.xml

xml文件位置移到各种不同位置改参数都不行,网上查资料也没配个工程目录图,也是搞不清楚。后来看到哪篇博文说spring boot对yml支持性更好,就改成yml再试验下

# MyBatis
mybatis:
    configLocation: classpath:/mybatis-config.xml

改成这样就可以了,真够莫名其妙的

绑定问题

由于用autoconfigure模式的时候不用再xml里面配置,都是通过注解的方式写在Java对象里面的,项目确实很整洁,不用各种配置,而我想改成xml配置的方式主要是因为SQL也注解在Java对象的话,SQL文简单还好,一复杂起来那真是噩梦,一大堆字符串拼接,还不好检查。
由于之前autoconfigure不用配置,现在改成xml配置的时候想偷个懒,当时是这样想的:新建一个mapper.xml直接放在[src/main/resource],把之前的mapper.java里面注解的SQL提出来写到mapper.xml,只要mapper.xml的namespace写成mapper.java的限定名,这样胡搞瞎搞下应该可以吧,然后就这样做了,结果报错

nested exception is org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): 某某包.某某Mapper.某某方法.

GitHub上找到一个相关的例子对照看了下,照着搞了一遍跑通了,在它基础上按照我之前偷懒的想法改了下工程结构,运行又报那个错误,再找了篇MyBatis的文档看了下,里面写了这样一句话:

要注意这个使用完全限定名调用 Java 对象的方法是相似的,这样做是有原因的。这个 命名可以直接给
相同命名空间下的的映射类, 使用一个名称, 参数和返回值和已映射的查询 语句都一样的方法即可。

这份文档是机器翻译出来的还是咋的,语义不太通顺,大意应该是说mapper.xml里面开头部分的namespace的完全限定名要跟对应的接口的限定名完全一致,这样容器启动的时候就可以映射过去绑定起来,程序中就可以直接调用映射的接口执行相应操作了。

还有很多不明白的地方,先把现在的想法写下来吧。^_^

                                        -- 2016.12.26
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值