码迷,mamicode.com
首页 > 其他好文 > 详细

Mybatis如何传递多个参数——一个莫名空指针错误引起的思考

时间:2018-09-09 12:00:53      阅读:226      评论:0      收藏:0      [点我收藏+]

标签:and   hash   一个   重入   理解   available   业务   前言   参数   

一、前言

今天在做一些高并发的简单测试时(主要测试悲观锁、乐观锁、重入机制等等的效率,加深对锁的理解),报了一个莫名其妙的空指针错误:

技术分享图片

错误原因指向一个业务实现类,于是赶忙打开该类查看第62行代码:

 

技术分享图片

观察到,第62行只是一个简单的判断语句:

if(redPacket.getStock() > 0)

该判断句所引对象来自61行代码:

RedPacket redPacket = redPacketDAO.getRedPacket(redPacketId);

思考后发现,如果是空指针错误的话,那应该是对象redPacket为空,也就是说61行代码执行失败了。问题来了:既然61行执行失败,干嘛要报62行的错?果然,在我注释掉62行及以后的代码,print打印redPacket对象时,发现该对象本身及其所有属性均能正常打印(自动该类调用自定义的toString()方法),并没有报错。

 

哈,到这里真的有点摸不着头脑了,对象和他的属性均正常,set.get方法也无误,一个线程它正儿八经,正正常常的一行一行执行着,前一句不空,后一句突然变空,这…………

 

困难是有的,但还是可以解决的!抱着试一试的心态,先把62行外层if语句里所有内容注释掉,尝试性又执行一遍,额,空指针没了。

以上就是发现这个奇葩空指针源头的过程,再之后就简单了,一句句排查,锁定了错误的源头在Mybatis的这个方法中:

技术分享图片

 我注意到,sql语句中,参数有两个:id和version,我却还当作一个参数来处理:没有定义parameterType。粗心的毛病啊,,,,当时这段是直接复制悲观锁的代码,根本没注意到多加了一个参数。

二、Mybatis如何传递多个参数

四种方法噢,咱由浅入深,先从最不常用的开始,哈哈。

(1)采用Map传多参数。

    Dao层:

public int selectUser(Map paramMap);

    Mapper.xml:

<update id="selectUser">
        update table_name
        set xxx
        where id = #{id}
        and version = #{version}
 </update>

    Service层:

Private User x(){
    Map paramMap=new hashMap();
    paramMap.put(“id”,”2”);
    paramMap.put(“version”,”1”);
    User user=xxx. selectUser(paramMap);
}

(2)使用#{arg0},#{arg1}...或#{param1},#{param2}

细心的小伙伴遇到类似错误时可能会发现错误日志里有类似的提醒:

Parameter ‘id’ not found. Available parameters are [arg1, arg0, param1, param2] 

没错,就是把sql代码中#{id}和#{version}改为#{arg0}或者#{param1}等等:(注意:arg下标从0开始,param下标从1开始

    Dao层:

public int selectUser(Long id, int version);

    Mapper.xml:

<update id="selectUser">
        update table_name
        set xxx
        where id = #{arg0}
        and version = #{arg1}
 </update>

(3)定义一个实体类来承载多个参数

    pojo(实体类):

public class Param(){
private Long id; private int version; -------getter and setter------- }

    DAO层:

public int selectUser(Param p);

    Mapper.xml:同(1)

(4)使用@Param注解

    DAO层:

public int selectUser(@Param("id") Long id, @Param("version") int version);

    Mapper.xml同(1)

 

这四种方法中,个人认为第四种方法最好,使用@Param注解能让开发者看到dao层方法就知道该传什么样的参数,比较直观。

选择上述四种方法任意一种,问题解决。

三、结语

与其说问题已经解决,不如说只是代码不报错了而已。留给我的问题是:为嘛参数传递格式有问题,会报空指针错误?为嘛对象正常,只有调用属性的getter方法才会报错?仍在思考,希望路过的大神指导一二。

 

Mybatis如何传递多个参数——一个莫名空指针错误引起的思考

标签:and   hash   一个   重入   理解   available   业务   前言   参数   

原文地址:https://www.cnblogs.com/dongxiaoxuan/p/9611996.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!