标签: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