2

mybatisのバッチステートメントがタイムアウトになりました。ステートメントを定期的にフラッシュすることで、データベースに送信する負荷を抑制したいと思います。iBATISでは、次のようなコールバックを使用しました。

        sqlMapClientTemplate.execute(new SqlMapClientCallback<Integer>() {
            @Override
            public Integer doInSqlMapClient(SqlMapExecutor executor)
                    throws SQLException {
                executor.startBatch();
                int tally = 0;
                for (Foo foo: foos) {
                        executor.insert("FooSql.insertFoo",foo.getData());
                        /* executes batch when > MAX_TALLY */
                    tally = BatchHelper.updateTallyOnMod(executor, tally);
                }
                return executor.executeBatch();
            }
        });

mybatisでこれを行うためのより良い方法はありますか?または、SqlSessionCallbackで同じタイプのことを行う必要がありますか?これは面倒です。私が本当にやりたいのは、N個のバッチステートメントをすべてフラッシュするようにプロジェクトを構成することです。

4

2 に答える 2

3

何の回答も得られなかったので、決めた解決策を共有します。

Mybatisは、ステートメントフラッシングへの直接アクセスを提供します。SqlSessionを自動配線し、Guavaを使用してコレクションを管理可能なチャンクに分割し、各チャンクの後にステートメントをフラッシュしました。

Iterable<List<Foo>> partitions = Iterables.partition(foos, MAX_TALLY);
for (List<Foo> partition : partitions) {
    for (Foo foo : partition) {
        mapper.insertFoo(foo);
    }
    sqlSession.flushStatements();
}
于 2013-02-26T22:02:06.160 に答える
2

返信が遅れて申し訳ありませんが、私は今この質問に出くわしました。しかし、うまくいけば、それは同様の問題を抱えている他の人を助けるでしょう。

SqlSessionを明示的に自動配線する必要はありません。マッパーインターフェイス自体を使用できます。マッパーインターフェイスで、@Flushアノテーションが付けられ、戻りタイプが。のメソッドを定義するだけですList<BatchResult>。マッパーインターフェイスのメソッドの例を次に示します。

@Flush
List<BatchResult> flushBatchedStatements();

次に、次のようにマッパーオブジェクトでこのメソッドを呼び出すだけです。

Iterable<List<Foo>> partitions = Iterables.partition(foos, MAX_TALLY);
for (List<Foo> partition : partitions)
{
    for (Foo foo : partition)
    {
        mapper.insertFoo(foo);
    }
    mapper.flushBatchedStatements(); //this call will flush the all statements batched upto this point, into the table.
}

マッパーインターフェイスを介したこのタイプのステートメントフラッシュをサポートするために、マッパーXMLファイルに特別なものを追加する必要はないことに注意してください。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" >

<mapper namespace=".....">

    <insert id="bulkInsertIntoTable" parameterType="myPackage.Foo">

        insert into MyDatabaseTable(col1, col2, col3)
        values
        ( #{fooObj.data1}, #{fooObj.data2}, #{fooObj.data3} )

    </insert>

</mapper>

必要なのは、MyBatis3.3以降を使用することだけです。MyBatisWebサイトのMyBatisドキュメントの状態は次のとおりです。

このアノテーションを使用すると、マッパーインターフェイスで定義されたメソッドを介してSqlSession#flushStatements()を呼び出すことができます(MyBatis 3.3以降)

詳細については、MyBatisの公式ドキュメントサイトをご覧ください:
http ://www.mybatis.org/mybatis-3/java-api.html

于 2018-07-27T23:13:58.357 に答える