经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 数据库/运维 » MyBatis » 查看文章
MyBatis注解开发-@Insert和@InsertProvider的使用
来源:jb51  时间:2022/7/4 12:09:18  对本文有异议

@Insert和@InsertProvider的使用

首先,在mybatis-generator.xml中配置返回主键

UserMapper中的

  • @SelectKey:返回主键,具体解释见下面说明
  • @InsertProvider:type指明SQL工厂类,method是工厂类里对应的方法

@SelectKey注解源码

  • statement是要运行的SQL语句,它的返回值通过resultType来指定before表示查询语句statement运行的时机
  • keyProperty表示查询结果赋值给代码中的哪个对象,keyColumn表示将查询结果赋值给数据库表中哪一列
  • keyProperty和keyColumn都不是必需的,有没有都可以
  • before=true,插入之前进行查询,可以将查询结果赋给keyProperty和-keyColumn,赋给keyColumn相当于更改数据库
  • befaore=false,先插入,再查询,这时只能将结果赋给keyProperty
  • 赋值给keyProperty用来“读”数据库,赋值给keyColumn用来写数据库

selectKey的两大作用:

  • 1、生成主键;
  • 2、获取刚刚插入数据的主键。

注意:在MYSQL 中 , order是AFTER , 因为当前及记录的主键值在insert语句执行成功之后才能拿到 , 而在ORACLE中 ,oder是BEFORE , 因为ORACLE需要先从序列取到值 , 再将其作为主键插入到数据库

另外,附上UserMapper.xml形式的返回主键方法

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <!--
  6. 实体类的映射文件
  7. namespace 指定接口的类全名
  8. -->
  9. <mapper namespace="com.wzl.dao.UserMapper">
  10. <!--
  11. 方案一: 这表的主键必须是自增长的 auto_increment
  12. useGeneratedKeys="true" 让自增长的主键开启返回功能
  13. keyColumn="id" user表中主键列
  14. keyProperty="id" user实体主键属性
  15. 注意:支持主键自增类型的数据库 MySQL 和 SqlServer , oracle不支持
  16. -->
  17. <insert id="addUser" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
  18. insert into user values(null,#{user.username},#{user.birthday},#{user.sex},#{user.address})
  19. </insert>
  20. <!--
  21. 方案二: <selectKey>
  22. keyColumn="id" user表中主键列
  23. keyProperty="id" user实体主键属性
  24. resultType="int" user实体主键属性类型
  25. order="AFTER" 表示此标签内部sql语句在insert执行之前(执行),还是之后执行(执行)
  26. AFTER 之后执行【在自增主键时】
  27. BEFORE 之前执行【使用指定主键时】
  28. 在MYSQL 中 , order是AFTER , 因为当前及记录的主键值在insert语句执行成功之后才能拿到 , 而在ORACLE中 ,oder是BEFORE , 因为ORACLE需要先从序列取到值 , 再将其作为主键插入到数据库
  29. -->
  30. <insert id="addUser2">
  31. <selectKey keyColumn="id" keyProperty="id" resultType="int" order="AFTER">
  32. SELECT LAST_INSERT_ID()
  33. </selectKey>
  34. insert into user values(null, #{username},#{birthday},#{sex},#{address})
  35. </insert>
  36. </mapper>

使用InsertProvider注解报错解决过程

目前项目在使用mybatis,并且是使用注解的方式。

在使用InsertProvider注解的时候报了一下的错误:

org.apache.ibatis.builder.BuilderException: Could not find value method on SQL annotation.  Cause: org.apache.ibatis.builder.BuilderException: Error creating SqlSource for SqlProvider. Method........

注解是如下这个样子的

  1. @InsertProvider(method = "insertlist",type=SqlProvider.class)
  2. ?public int insertInnerTable(List list,String dbTable);

思路是要写一个通用的插入一个集合的方法,但是在执行的时候就报了上面的错误。在网上查资料未果。

于是只能自己动手,丰衣足食了。

一步步跟断点,跟到mybatis了报错的方法中,发现了如下的代码

  1. try {
  2. ? ? ? this.sqlSourceParser = new SqlSourceBuilder(config);
  3. ? ? ? this.providerType = (Class<?>) provider.getClass().getMethod("type").invoke(provider);
  4. ? ? ? providerMethodName = (String) provider.getClass().getMethod("method").invoke(provider);
  5. ? ? ? for (Method m : this.providerType.getMethods()) {
  6. ? ? ? ? if (providerMethodName.equals(m.getName())) {
  7. ? ? ? ? ? if (m.getParameterTypes().length < 2
  8. ? ? ? ? ? ? ? && m.getReturnType() == String.class) {
  9. ? ? ? ? ? ? this.providerMethod = m;
  10. ? ? ? ? ? ? this.providerTakesParameterObject = m.getParameterTypes().length == 1;
  11. ? ? ? ? ? }
  12. ? ? ? ? }
  13. ? ? ? }
  14. ? ? } catch (Exception e) {
  15. ? ? ? throw new BuilderException("Error creating SqlSource for SqlProvider. ?Cause: " + e, e);
  16. ? ? }

注意标黄的位置,终于发现导致错误的罪魁祸首了,原来是这里限制了参数的个数,不能操作两个参数的啊。

于是将方法以及注解改为如下形式

  1. @InsertProvider(method = "insert",type=SqlProvider.class)
  2. ?public int insert(SqlContext sqlContext);

在SqlProvider中对应的方法为

  1. public String insert(SqlContext sqlContext){
  2. ? ? ? ........
  3. }

至此问题解决!

以上为个人经验,希望能给大家一个参考,也希望大家多多支持w3xue。 

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号