MyBatis注解開發(fā)-@Insert和@InsertProvider的使用
@Insert和@InsertProvider的使用
首先,在mybatis-generator.xml中配置返回主鍵
UserMapper中的
@SelectKey
:返回主鍵,具體解釋見下面說明@InsertProvider
:type指明SQL工廠類,method是工廠類里對應的方法
@SelectKey注解源碼
statement
是要運行的SQL語句,它的返回值通過resultType來指定before表示查詢語句statement運行的時機keyProperty
表示查詢結果賦值給代碼中的哪個對象,keyColumn表示將查詢結果賦值給數(shù)據庫表中哪一列keyProperty
和keyColumn都不是必需的,有沒有都可以before=true
,插入之前進行查詢,可以將查詢結果賦給keyProperty和-keyColumn,賦給keyColumn相當于更改數(shù)據庫befaore=false
,先插入,再查詢,這時只能將結果賦給keyProperty- 賦值給
keyProperty
用來“讀”數(shù)據庫,賦值給keyColumn用來寫數(shù)據庫
selectKey的兩大作用:
- 1、生成主鍵;
- 2、獲取剛剛插入數(shù)據的主鍵。
注意:在MYSQL 中 , order是AFTER , 因為當前及記錄的主鍵值在insert語句執(zhí)行成功之后才能拿到 , 而在ORACLE中 ,oder是BEFORE , 因為ORACLE需要先從序列取到值 , 再將其作為主鍵插入到數(shù)據庫
另外,附上UserMapper.xml形式的返回主鍵方法
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- 實體類的映射文件 namespace 指定接口的類全名 --> <mapper namespace="com.wzl.dao.UserMapper"> <!-- 方案一: 這表的主鍵必須是自增長的 auto_increment useGeneratedKeys="true" 讓自增長的主鍵開啟返回功能 keyColumn="id" user表中主鍵列 keyProperty="id" user實體主鍵屬性 注意:支持主鍵自增類型的數(shù)據庫 MySQL 和 SqlServer , oracle不支持 --> <insert id="addUser" useGeneratedKeys="true" keyColumn="id" keyProperty="id"> insert into user values(null,#{user.username},#{user.birthday},#{user.sex},#{user.address}) </insert> <!-- 方案二: <selectKey> keyColumn="id" user表中主鍵列 keyProperty="id" user實體主鍵屬性 resultType="int" user實體主鍵屬性類型 order="AFTER" 表示此標簽內部sql語句在insert執(zhí)行之前(執(zhí)行),還是之后執(zhí)行(執(zhí)行) AFTER 之后執(zhí)行【在自增主鍵時】 BEFORE 之前執(zhí)行【使用指定主鍵時】 在MYSQL 中 , order是AFTER , 因為當前及記錄的主鍵值在insert語句執(zhí)行成功之后才能拿到 , 而在ORACLE中 ,oder是BEFORE , 因為ORACLE需要先從序列取到值 , 再將其作為主鍵插入到數(shù)據庫 --> <insert id="addUser2"> <selectKey keyColumn="id" keyProperty="id" resultType="int" order="AFTER"> SELECT LAST_INSERT_ID() </selectKey> insert into user values(null, #{username},#{birthday},#{sex},#{address}) </insert> </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........
注解是如下這個樣子的
@InsertProvider(method = "insertlist",type=SqlProvider.class) ?public int insertInnerTable(List list,String dbTable);
思路是要寫一個通用的插入一個集合的方法,但是在執(zhí)行的時候就報了上面的錯誤。在網上查資料未果。
于是只能自己動手,豐衣足食了。
一步步跟斷點,跟到mybatis了報錯的方法中,發(fā)現(xiàn)了如下的代碼
try { ? ? ? this.sqlSourceParser = new SqlSourceBuilder(config); ? ? ? this.providerType = (Class<?>) provider.getClass().getMethod("type").invoke(provider); ? ? ? providerMethodName = (String) provider.getClass().getMethod("method").invoke(provider); ? ? ? for (Method m : this.providerType.getMethods()) { ? ? ? ? if (providerMethodName.equals(m.getName())) { ? ? ? ? ? if (m.getParameterTypes().length < 2 ? ? ? ? ? ? ? && m.getReturnType() == String.class) { ? ? ? ? ? ? this.providerMethod = m; ? ? ? ? ? ? this.providerTakesParameterObject = m.getParameterTypes().length == 1; ? ? ? ? ? } ? ? ? ? } ? ? ? } ? ? } catch (Exception e) { ? ? ? throw new BuilderException("Error creating SqlSource for SqlProvider. ?Cause: " + e, e); ? ? }
注意標黃的位置,終于發(fā)現(xiàn)導致錯誤的罪魁禍首了,原來是這里限制了參數(shù)的個數(shù),不能操作兩個參數(shù)的啊。
于是將方法以及注解改為如下形式
@InsertProvider(method = "insert",type=SqlProvider.class) ?public int insert(SqlContext sqlContext);
在SqlProvider中對應的方法為
public String insert(SqlContext sqlContext){ ? ? ? ........ }
至此問題解決!
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
MyBatis映射文件resultMap元素中使用多個association的方法
這篇文章主要介紹了MyBatis映射文件resultMap元素中使用多個association的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-03-03