タイガー!タイガー!じれったいぞー!(SE編)

AS400, Java, JavaEE, JSF等の開発、習慣など。日々の気づきをまとめたブログ(備忘録)

【Mybatis】DBアクセス速度改善(DBセッション制御)

Mybatisを実装したJavaのコンソールアプリ開発を行っています。

RDBは、DB2 for i(旧AS400)。

CSVEXCELファイルの大量のデータを裁かなければならないケースも多く、その場合、処理時間が長くなってしまいがちです。

これまでのやり方は、ACSのデータ転送機能を使って、ExcelファイルをAS400のテンポラリーテーブルに格納し、RPGプログラムで更新処理を行うものでした。

確かにこのやり方は、爆速です!!

しかし、このRPGプログラムがどんどん属人化アイテムとなってきているのが正直なところ。

JDBC/ODBC経由でのDB処理では、そのスピードは期待できないのですが、Javaの書き方が悪くて無駄に時間をかけてしまっていたので、その反省を込めて記録しておきます。

改善前

  • 簡単なサンプルですが、ざっくり言うと、RDBアクセスするメソッドの中で、SqlSession を生成していました。
  • メソッドの実行時にRDBにログインし、終了時にログアウトされていました。メソッドの実行回数が増えれば増えるほど、処理の実行時間が長くなっていました。
public Item fetchItemByItemModel(String itemModel) throws IOException {
    try (InputStream in = AbstractDao.class.getResourceAsStream("/mybatis-config.xml")) {
        //設定ファイルより SqlSessionFactory を生成(実際は、アプリケーション実行中は使いまわし可能)
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        
        //SqlSessionFactoryより SqlSession を生成
        try (SqlSession session = factory.openSession()) {
            ItemMapper mapper = session.getMapper(ItemMapper.class);
            // Mapper(xmlファイル)に定義されたSQL文が実行される
            return mapper.fetchItemByItemModel(itemModel); //SqlSessionがクローズされる
        }
    }
}

改善後

  • アプリケーションが準備した SqlSessionFactory を渡して、SqlSession を生成するメソッドを準備しました。
  • 一連の処理の開始時に SqlSession を生成し、それを処理終了まで使い続けるように改変しました。
  • 一連の処理の中でRDBにアクセスするためのメソッドすべてに SqlSession を渡すことにしました。
public static SqlSession createSession(SqlSessionFactory factory) {
    return factory.openSession();
}

public Item fetchItemByItemModel(SqlSession session, String itemModel) throws PersistenceException {
    ItemMapper mapper = session.getMapper(ItemMapper.class);
    return mapper.fetchItemByItemModel(itemModel);
}

結果

  • これにより、1つのセッション内で処理を完結できるようになりました。
  • 単純なコンソールアプリケーションなので、この方法でも今のところ問題は起きていません。

かなりMybatisの基本的な話でしたが、バッチ処理系のアプリとはいえ、最速で正常終了できるように努力していきたいところですね。