Spring + mybatisなコンポーネントライブラリを作成する方法
Spring + mybatisを使った開発用に、DBの自動テスト用ユーティリティを作成しました
DbTestUtil https://github.com/naosim/DbTestUtil
SQL文をサクッと実行したりできます
このユーティリティでは
Spring(DI)とmybatisを使ったコンポーネントをライブラリ化してますが、設定周りが結構大変だったのでメモ
DI対象
今回作ったライブラリのDI対象は以下の2つ
DbTestComponent
https://github.com/naosim/DbTestUtil/blob/master/src/main/java/com/naosim/dbtestutil/DbTestComponent.java
内部でDbTestQueryMapperをDIしてます
DbTestQueryMapper
https://github.com/naosim/DbTestUtil/blob/master/src/main/java/com/naosim/dbtestutil/db/DbTestQueryMapper.java
mybatisのマッパー。DDLはxmlではなくアノテーションで書いてます
ComponentとMapperをDIする
DbTestScanConfiguration
DbTestComponentと同列にDbTestScanConfigurationというクラスを作り、DbTestComponentとDbTestQueryMapperがDIできるようにします
package com.naosim.dbtestutil; import org.mybatis.spring.annotation.MapperScan; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan("com.naosim.dbtestutil") @MapperScan("com.naosim.dbtestutil.db") public class DbTestScanConfiguration { }
私はMapperScanを書き忘れててハマりました。。お忘れなく
ConfigurationをDIの対象にする
DbTestScanConfigurationを作っただけの場合、ライブラリを使う側がDbTestScanConfigurationへのパスを指定する必要があります。それだと面倒なので、自動的にパスが通るようにします
そのためにspring.factories
というファイルを作ります
src/main/resources/META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.naosim.dbtestutil.DbTestScanConfiguration
これで自動的に読み込まれます
ここまででコード側の修正は終了
最終的なファイル構成はこんな感じです
次はgradleの設定
build.gradleでゆるい依存を書く
ゆるいってなんだよ!て感じですが、ホントにゆるい依存を書きます
具体的にはspringとmybatisにcomplieOnlyで依存させます
dependencies { compileOnly group: 'org.springframework', name: 'spring-context', version: '5.0.5.RELEASE' compileOnly group: 'org.mybatis', name: 'mybatis', version: '3.4.6' compileOnly group: 'org.mybatis', name: 'mybatis-spring', version: '1.3.2' // ... }
なぜゆるい依存にするか
少しウンチク
なぜゆるい依存にするかというと、このライブラリのせいで使う側のspringやmybatisのバージョンが上がってしまうのを防ぐためです。gradleは依存先で同じライブラリが別のバージョンで依存していた場合に新しい方を採用する仕様なので、私が作ったライブラリが使う側のプロジェクトで使うspring等のバージョンをあげてしまう可能性があります。
ちょっとそれは怖いので。。compileOnlyで逃げます。。
あるべき姿としては、作ったライブラリが動作する最低バージョンを探してそれを指定することなんだろうけど、めんどうなので。。
テスト用の依存を追加する
次はテスト
上記でゆるい依存はしましたがそれでは実行できないので、テストではちゃんと依存を書きます
build.gradle
dependencies { compileOnly group: 'org.springframework', name: 'spring-context', version: '5.0.5.RELEASE' compileOnly group: 'org.mybatis', name: 'mybatis', version: '3.4.6' compileOnly group: 'org.mybatis', name: 'mybatis-spring', version: '1.3.2' // test testCompile 'org.codehaus.groovy:groovy-all:2.3.11' testCompile group: 'junit', name: 'junit', version: '4.12' testCompile group: 'org.spockframework', name: 'spock-core', version: '1.1-groovy-2.4' testCompile group: 'org.spockframework', name: 'spock-spring', version: '1.1-groovy-2.4' // spring testCompile group: 'org.springframework', name: 'spring-context', version: '5.0.5.RELEASE' testCompile("org.springframework.boot:spring-boot-starter-web:2.0.1.RELEASE") testCompile group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: '2.0.0.RELEASE' // mybatis testCompile group: 'org.mybatis', name: 'mybatis', version: '3.4.6' testCompile group: 'org.mybatis.spring.boot', name: 'mybatis-spring-boot-starter', version: '1.3.1' testCompile group: 'org.xerial', name: 'sqlite-jdbc', version: '3.21.0.1' compileOnly group: 'org.mybatis', name: 'mybatis-spring', version: '1.3.2' testCompileOnly group: 'org.projectlombok', name: 'lombok', version: '1.16.20' }
ぶっちゃけテストは誰にも迷惑かけないのでライブラリをガンガン追加してます。不要なのもあるかも
テストコード側にApplicationクラスを作る
今回はライブラリのためmain側にApplicationクラスがありません。それだとテストができないのでテスト側に作ります
src/test/java/com/naosim/dbtestutil/Application.java ※テスト側ですよ!
package com.naosim.dbtestutil; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
必要に応じてresourcesも設定する
今回はsqliteを使うのでこんな感じ
src/test/resouces/application.properties
# spring.datasource.driverClassName="org.sqlite.JDBC" jdbc.driver=org.sqlite.JDBC spring.datasource.url = jdbc:sqlite:test.db
以上!あとはテストして公開するだけ!
ライブラリをいっぱい作ろう!