1.mybatis 源码selectKey 赋值未生效,为什么?
2.Mybatis中selectlast_insert_id()-返回插入数据行的源码id
mybatis selectKey 赋值未生效,为什么?
使用Mybatis在Insert User表时,源码通过selectKey获取LAST_INSERT_ID()并赋值给user的源码id属性,却发现id属性值未被正确设置,源码获取结果始终为0,源码分层公式源码与会话LAST_INSERT_ID()明显不符。源码文章开始探讨此问题的源码可能原因。
首先,源码问题可能出现在未执行SELECT LAST_INSERT_ID() SQL语句或默认使用了id属性的源码long类型值0。其次,源码Mybatis的源码SelectKeyGenerator处理selectKey标签时,通过keyExecutor查询值为[],源码表明查询没有问题,源码问题则可能在于setValue方法的源码delphi的控件源码处理。
进一步深入,setValue最终执行于MapWrapper#set方法,该方法只在map中添加了一个键值对,而Mybatis在设置字段值时应通过反射调用对象的set方法。同时,发现ObjectWrapper有一个实现类BeanWrapper,其set方法通过反射设置字段值,centos编译源码qt这与预期相符。由此推测,问题可能发生在决策ObjectWrapper的阶段,导致id属性值未被正确设置。
深入代码逻辑,实际执行流程中,object类型为MapperMethod.ParamMap,支付成功跳转源码走到了Map分支,而非预期的else逻辑。MapperMethod.ParamMap是在MapperMethod执行过程中,将Java对象参数转换为SQL命令行参数生成的。由于Mapper方法参数标注了@Param注解,导致生成的是MapperMethod.ParamMap,进而影响了MetaObject的苹果算命app源码获取,错误地决策为MapWrapper,从而导致setValue方法未正确设置属性值。
总结问题根源,使用不规范的参数标注导致了错误的类型决策,进而影响了属性值的正确设置。解决方案是去除方法上的@Param注解,以恢复正常运行。
Mybatis中selectlast_insert_id()-返回插入数据行的id
last_insert_id的正确姿势
业务中,我们经常需要获取插入数据行的id,可以进行如下操作:
单元测试方法
@TestpublicvoidtestLastInsertId(){ Studentrecord=newStudent();record.setStuCode("");record.setStuName("老王");record.setStuSex("男");record.setStuAge();record.setStuDept("计科");intid=studentMapper.insert(record);LonglastId=record.getId();System.out.println(lastId);}Dao接口方法
intinsert(Studentrecord);Dao接口对应的xml文件
<insertid="insert"parameterType="org.balloon.model.entity.Student"><!--将insert插入的数据的主键返回到Student对象中;selectlast_insert_id():得到刚insert进去记录的主键值,只适用于自增主键;keyProperty:将查询到的主键值,设置到parameterType指定的对象的那个属性order:selectlast_insert_id()执行顺序,相对于insert语句来说它的执行顺序;resultType:指定selectlast_insert_id()的结果类型,也就是id的类型。--><selectKeykeyProperty="id"order="AFTER"resultType="java.lang.Long">SELECTLAST_INSERT_ID()</selectKey>insertintostudent(stu_code,stu_name,stu_sex,stu_age,stu_dept)values(#{ stuCode,jdbcType=VARCHAR},#{ stuName,jdbcType=VARCHAR},#{ stuSex,jdbcType=VARCHAR},#{ stuAge,jdbcType=INTEGER},#{ stuDept,jdbcType=VARCHAR})</insert>注意:selectlast_insert_id()返回的id值封装在入参record中,通过record.getId()获取,而不是insert方法的返回值!
除此之外,我们还有别的方法可以获取插入数据行的id,只需要改一下对应的xml,如下:
<insertid="insert"parameterType="org.balloon.model.entity.Student"useGeneratedKeys="true"keyProperty="id">insertintostudent(stu_code,stu_name,stu_sex,stu_age,stu_dept)values(#{ stuCode,jdbcType=VARCHAR},#{ stuName,jdbcType=VARCHAR},#{ stuSex,jdbcType=VARCHAR},#{ stuAge,jdbcType=INTEGER},#{ stuDept,jdbcType=VARCHAR})</insert>last_insert_id的突然失效大多数时候在Dao接口上我们会使用@Param注解定义入参,方便传递多个参数和设置别名,然而再通过record.getId()获取插入数据行的id值时却为null?
intinsert(@Param("record")Studentrecord);此时,不用担心,我们只需要重新指定映射到的属性字段就好啦:(id->record.id)
<insertid="insert"parameterType="org.balloon.model.entity.Student"><selectKeykeyProperty="record.id"order="AFTER"resultType="java.lang.Long">SELECTLAST_INSERT_ID()</selectKey>insertintostudent(stu_code,stu_name,stu_sex,stu_age,stu_dept)values(#{ record.stuCode,jdbcType=VARCHAR},#{ record.stuName,jdbcType=VARCHAR},#{ record.stuSex,jdbcType=VARCHAR},#{ record.stuAge,jdbcType=INTEGER},#{ record.stuDept,jdbcType=VARCHAR})</insert>或
<insertid="insert"parameterType="org.balloon.model.entity.Student"useGeneratedKeys="true"keyProperty="record.id">insertintostudent(stu_code,stu_name,stu_sex,stu_age,stu_dept)values(#{ record.stuCode,jdbcType=VARCHAR},#{ record.stuName,jdbcType=VARCHAR},#{ record.stuSex,jdbcType=VARCHAR},#{ record.stuAge,jdbcType=INTEGER},#{ record.stuDept,jdbcType=VARCHAR})</insert>last_insert_id的并发问题selectlast_insert_id()是否存在并发问题呐,如果有两个连接,它们几乎同时做了插入操作,然后分别进行了查插入id,此时会得到两个相同的id值么?
结论:对于同一个connection对象,selectlast_insert_id()无并发问题!