Red Hat で Java 関連を担当している伊藤ちひろです。
本記事は、Jakarta EE 10と一緒に MyBatis を使う方法を紹介します。 MyBatis 自体の使い方は説明しません。 Jakarta EE 10で MyBatis を使う方法に焦点をあてます。
MyBatis は Java SE や Jakarta EE の仕様と連携できます。 本記事では以下の構成で MyBatis を使ってみます。
- MyBatis を Contexts and Dependency Injection (CDI) で使えるようにする
- トランザクション管理は Jakarta Transactions
- コネクション管理はAPサーバから javax.sql.DataSource を提供
サンプルは JBoss EAP 8.0 で動作を確認しています。 サンプルはこちら
プロジェクトの設定
MyBatis を CDI と組み合わせて使うには、mybatis
とmybatis-cdi
という2つの依存を追加します。
これらはどちらもorg.mybatis
というグループIDです。
アプリケーションのpom.xml
に以下のように追記します。
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-cdi</artifactId> <version>2.1.0</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.16</version> </dependency>
設定ファイル
次に、MyBatisの設定ファイルです。 ここでは、以下を設定します。
- トランザクションのライフサイクル管理をアプリケーションサーバに任せる(transactionManager要素)
- データソースをアプリケーションサーバに定義済みのものを使う (dataSource要素)
アプリケーションサーバで、data_source
プロパティに設定してあるデータソースを作成する必要があります。
また、あとのステップで設定が正しく行われたかどうかを確認するため、ログを出力するように設定しています。
src/main/resources/mybatis-config.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <settings> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings> <environments default="Postgres"> <environment id="Postgres"> <transactionManager type="MANAGED"/> <dataSource type="JNDI"> <property name="data_source" value="java:jboss/datasources/PostgreSQLDS"/> </dataSource> </environment> </environments> <mappers> <!-- マッパーファイルの一覧を記述 --> </mappers> </configuration>
ファクトリ
最後に、MyBatis のクライアントを CDI で使えるようにするため、CDI の Producerを作成します。
この Producer は org.apache.ibatis.session.SqlSessionFactory
を作成します。
複数のデータベースにアクセスする場合は、Producer に限定子(Qualifier) を設定することで、SqlSessionFactory
を使い分けられるようにします。
以下は、Producer のサンプルコードです。 上述の設定ファイルを使用しています。
package org.example; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.Dependent; import jakarta.enterprise.inject.Produces; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.mybatis.cdi.SessionFactoryProvider; import java.io.IOException; import java.io.InputStream; @Dependent public class SqlSessionFactoryProducer { @Produces @ApplicationScoped @SessionFactoryProvider public SqlSessionFactory produceFactory() throws IOException { InputStream fileStream = Resources.getResourceAsStream("mybatis-config.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(fileStream); return sqlSessionFactory; } }
動作確認
Producer で SqlSessionFactory
を作成できたかどうか確認します。
アプリケーションをデプロイすると以下のようなログが出力されれば成功です。
もし、先頭の 2 行だけが出力され、最後の Managed SqlSession:
の行が出力されていない場合は失敗です。
21:22:11,832 INFO [org.mybatis.cdi.MybatisExtension] (MSC service thread 1-8) MyBatis CDI Module - SqlSessionFactory producer SqlSessionFactoryProducer.produceFactory 21:22:11,851 INFO [org.mybatis.cdi.MybatisExtension] (MSC service thread 1-8) MyBatis CDI Module - Activated 21:22:11,851 INFO [org.mybatis.cdi.MybatisExtension] (MSC service thread 1-8) MyBatis CDI Module - Managed SqlSession: org.apache.ibatis.session.SqlSession, org.apache.ibatis.session.SqlSession
MyBatisを使う
ログがきちんと出力されるようになったら、org.apache.ibatis.session.SqlSession
のオブジェクトを DI できます。
これは、CDI で普通に @Inject
を付けて DI します。
package org.example; import jakarta.inject.Inject; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.Produces; import jakarta.ws.rs.core.MediaType; import org.apache.ibatis.session.SqlSession; import java.util.List; @Path("/hello") public class HelloResource { @Inject SqlSession sqlSession; @GET @Produces(MediaType.APPLICATION_JSON) public List<SampleEntity> hello() { return sqlSession.selectList("findList"); } }
参考:Java EE + iBATIS から Jakarta EE + MyBatis への移行
MyBatis の前身である iBATIS は、未だに Java EE と一緒によく使われています。 iBATIS から MyBatis へ移行する場合は、以下が必要です。
- 使用するクラスとメソッドの変更
- マッパーファイルの変更
使用するクラスはcom.ibatis.sqlmap.client.SqlMapClient
から org.apache.ibatis.session.SqlSession
に変わります。
メソッドも変わるため、Javadocを見ながら適切なものへ変更していきましょう。
既存のマッパーファイルが多い場合には手作業で変換するのは大変です。 そのため、変換ツールが公式から公開されています。 また、公式以外でも変換ツールを公開されている方もいらっしゃいました。
- GitHub - mybatis/ibatis2mybatis: Tool to convert iBATIS 2 xml files to MyBatis3
- GitHub - ogasada/ibatisToMyBatis3: The tool converts sqlmap files for iBatis to MyBatis3.
私が使った感想としては、マッパーファイルが古すぎるとどちらも変換できませんでした。
これは、マッパーファイルのDOCTYPE要素に記載されているDTDのホスト名が異なるためでした。
この問題に遭遇した場合はホスト名の部分を ibatis.apache.org
に変更してから変更してください。