Mybatisがプライマリ・キー機能を同時に返す2つの方法を追加
26804 ワード
Mybatisはプライマリ・キー機能を追加して返します
本人はMybatis 3.Xのバージョンを使用しています
公式ドキュメントには、次の2つの方法があります. データベースがプライマリ・キーを自動的に生成するフィールドをサポートしていない場合.サブラベル
例
エンティティクラスとmapperインタフェースレイヤのコードを省略し、xmlファイルのコードのみを例として示します.
ここでは、2つの方法
テストクラスの下での方法と結果を示します.
結果は
確かに自己増加のプライマリ・キーが返されていることがわかります.
ソースコード
mybatisのKeyGeneratorインタフェースは、2つの方法を提供しています.1つは、実行前が実行後であり、上記の例では、プライマリ・キーは挿入後に得られるため、
このインタフェースには3つの実装クラスがあり、デフォルトでは
mybatisの公式ドキュメントでは、
(insertとupdateでのみ使用可能)一意に1つの属性をマークします.MyBatisはgetGeneratedKeysの戻り値またはinsert文のselectKeysサブ要素でキー値を設定します.デフォルト:unset.複数の生成されたカラムを取得する場合は、カンマで区切られたプロパティ名のリストでも構いません.
ソースコードからkeyPropertyも確かに複数の設定をサポートし、挿入操作の前後に統一的に格納することができることが分かった.
プライマリ・キーにsetterメソッドがない場合は、ここでエラーが発生することに注意してください.mybatisは生成したプライマリ・キー情報をエンティティ・クラスに戻すことができません.
本人はMybatis 3.Xのバージョンを使用しています
公式ドキュメントには、次の2つの方法があります.
useGeneratedKeys
:(insertとupdateのみで使用)これにより、データベース内で生成されたプライマリ・キー(たとえば、MySQLやSQLサーバのようなリレーショナル・データベース管理システムの自動インクリメント・フィールド)を取り出すには、JDBCのgetGeneratedKeysメソッドを使用します.デフォルト値はfalseです.データベースがプライマリ・キーを自動的に生成するフィールド(MySQLやSQL Serverなど)をサポートしている場合は、useGeneratedKeys="true"を設定してkeyPropertyをターゲット・プロパティに設定すればOKです.
を使用して実装できます.例
エンティティクラスとmapperインタフェースレイヤのコードを省略し、xmlファイルのコードのみを例として示します.
<mapper namespace="com.mirt.mybatis_demo.mapper.AutoIncrementMapper">
<resultMap id="BaseResult" type="com.mirt.mybatis_demo.entity.AutoIncrementEntity">
<result column="id" property="id"/>
<result column="comment" property="comment"/>
<result column="create_time" property="createTime"/>
resultMap>
<insert id="saveOneByUseGeneratedKeys" useGeneratedKeys="true" keyProperty="id">
insert into auto_increment_table (comment, create_time) values (#{comment},now());
insert>
<insert id="saveOneBySelectKey" parameterType="com.mirt.mybatis_demo.entity.AutoIncrementEntity">
<selectKey resultType="int" order="AFTER" keyProperty="id">
SELECT LAST_INSERT_ID();
selectKey>
insert into auto_increment_table (comment, create_time) values (#{comment},now());
insert>
mapper>
ここでは、2つの方法
saveOneByUseGeneratedKeys
、saveOneBySelectKey
を定義し、公式に与えられた2つの方法が実行可能であるかどうかを示す.テストクラスの下での方法と結果を示します.
@Test
public void saveOneByUseGeneratedKeys() {
AutoIncrementEntity aie = new AutoIncrementEntity();
aie.setComment("useGeneratedKeys");
boolean res = autoIncrementMapper.saveOneByUseGeneratedKeys(aie) > 0;
if (res) {
System.out.println(aie);
}else {
System.out.println("insert fail");
}
}
@Test
public void saveOneBySelectKey() {
AutoIncrementEntity aie = new AutoIncrementEntity();
aie.setComment("selectKey");
boolean res = autoIncrementMapper.saveOneByUseGeneratedKeys(aie) > 0;
if (res) {
System.out.println(aie);
}else {
System.out.println("insert fail");
}
}
結果は
{id:1}
{id:2}
確かに自己増加のプライマリ・キーが返されていることがわかります.
ソースコード
package org.apache.ibatis.executor.keygen;
import java.sql.Statement;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
public interface KeyGenerator {
void processBefore(Executor var1, MappedStatement var2, Statement var3, Object var4);
void processAfter(Executor var1, MappedStatement var2, Statement var3, Object var4);
}
mybatisのKeyGeneratorインタフェースは、2つの方法を提供しています.1つは、実行前が実行後であり、上記の例では、プライマリ・キーは挿入後に得られるため、
processAfter
という方法が使用されています.このインタフェースには3つの実装クラスがあり、デフォルトでは
Jdbc3KeyGenerator
という実装クラスが使用されています. public void processAfter(Executor executor, MappedStatement ms, Statement stmt, Object parameter) {
this.processBatch(ms, stmt, this.getParameters(parameter));
}
public void processBatch(MappedStatement ms, Statement stmt, Collection<Object> parameters) {
ResultSet rs = null;
try {
rs = stmt.getGeneratedKeys();
Configuration configuration = ms.getConfiguration();
TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
String[] keyProperties = ms.getKeyProperties(); // keyproperties
ResultSetMetaData rsmd = rs.getMetaData();
TypeHandler<?>[] typeHandlers = null;
MetaObject metaParam;
if (keyProperties != null && rsmd.getColumnCount() >= keyProperties.length) {
for(Iterator var10 = parameters.iterator(); var10.hasNext(); this.populateKeys(rs, metaParam, keyProperties, typeHandlers)) {
Object parameter = var10.next();
if (!rs.next()) {
break;
}
metaParam = configuration.newMetaObject(parameter);
if (typeHandlers == null) {
typeHandlers = this.getTypeHandlers(typeHandlerRegistry, metaParam, keyProperties, rsmd);
}
}
}
} catch (Exception var20) {
throw new ExecutorException("Error getting generated key or setting result to parameter object. Cause: " + var20, var20);
} finally {
if (rs != null) {
try {
rs.close();
} catch (Exception var19) {
;
}
}
}
}
//
private void populateKeys(ResultSet rs, MetaObject metaParam, String[] keyProperties, TypeHandler<?>[] typeHandlers) throws SQLException {
for(int i = 0; i < keyProperties.length; ++i) {
String property = keyProperties[i];
TypeHandler<?> th = typeHandlers[i];
if (th != null) {
Object value = th.getResult(rs, i + 1);
metaParam.setValue(property, value);
}
}
}
mybatisの公式ドキュメントでは、
keyPropwety
について次のように説明されています.(insertとupdateでのみ使用可能)一意に1つの属性をマークします.MyBatisはgetGeneratedKeysの戻り値またはinsert文のselectKeysサブ要素でキー値を設定します.デフォルト:unset.複数の生成されたカラムを取得する場合は、カンマで区切られたプロパティ名のリストでも構いません.
ソースコードからkeyPropertyも確かに複数の設定をサポートし、挿入操作の前後に統一的に格納することができることが分かった.
プライマリ・キーにsetterメソッドがない場合は、ここでエラーが発生することに注意してください.mybatisは生成したプライマリ・キー情報をエンティティ・クラスに戻すことができません.