背景
久しぶりにJavaで何か作りたくなって、とりあえずDBアクセス絡みの機能を実装した。
その際、今風にDIしたいと思って色々調べてたりしてたら、かなり手間取ったのでまとめる。
環境
IntelliJ IDEA 2021.2 (Community Edition) ビルド #IC-212.4746.92、ビルド日 July 27, 2021 ランタイムバージョン: 11.0.11+9-b1504.13 amd64 VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o. Windows 10 10.0 GC: ParNew, ConcurrentMarkSweep Memory: 2002M Cores: 4 Registry: debugger.watches.in.variables=false Non-Bundled Plugins: color.scheme.GitHub 3 (1.2.1), com.intellij.ja (212.231), com.karateca.jstoolbox (1.10), com.nerdscorner.android.plugin.github (2.1.1), net.seesharpsoft.intellij.plugins.csv (2.17.1), com.codestream.jetbrains-codestream (11.0.12+180), mobi.hsz.idea.gitignore (4.2.0), SpringBootGen (1.0), String Manipulation (8.15.203.000.3), org.sonarlint.idea (5.2.0.35150), ru.adelf.idea.dotenv (2021.3.0.212), com.intellij.lang.jsgraphql (3.0.0) Kotlin: 212-1.5.10-release-IJ4746.92
悩んだところ
miragesql-integration
DIの概念はある程度知っていて、どうすればいいかもだいたい把握しているのだが、Mirage-SQLをDIするのに必要なライブラリが何なのか分からずに色々試行錯誤して1周間が過ぎた。。。
早く公式サイトのドキュメントを見るべきだった。
見たら、思いっきりmiragesql-integration
が必要だと書いてあった。。。
com.miragesql:miragesql
だけでDIできないかと四苦八苦していた自分がアホらしかった。。。
とりあえず、以下の設定を入れ込んだ。
dependencies { implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-web' testImplementation 'org.springframework.boot:spring-boot-starter-test' implementation 'com.miragesql:miragesql:2.1.0' implementation 'org.xerial:sqlite-jdbc:3.36.0.1' // https://mvnrepository.com/artifact/be.ceau/opml-parser implementation 'be.ceau:opml-parser:2.2.0' // https://mvnrepository.com/artifact/org.apache.commons/commons-dbcp2 implementation 'org.apache.commons:commons-dbcp2:2.9.0' // https://mvnrepository.com/artifact/org.springframework/spring-jdbc implementation 'org.springframework:spring-jdbc:5.3.9' implementation 'com.miragesql:miragesql-integration:2.1.0' }
AppConfig
そういえば、設定をJavaのソースで書けると何かで覚えたので、やってみることに。
ここが、結構悩んだ。
DIでやっていることは理解していたので、@Bean
付けてインスタンス返すだけだろ?余裕余裕って思ってたけど、設定が必要なプロパティを見逃したり、全然別のクラスを使ってたりと、公式ドキュメントに書かれてること以外のことをやろうとして、実行時エラーでドツボにハマっていた。。。
別日に設定を見直すところからやったら、すんなり解けて、台パンした。。。
面倒臭いので、設定ファイル晒す。
公式サイト、import文の記載がないので、たまたま同じクラス名のやつがあると、間違えたときに原因が分からなくて、結構詰まってた。
package com.example.GaleWings; import com.miragesql.miragesql.SqlManagerImpl; import com.miragesql.miragesql.dialect.SQLiteDialect; import com.miragesql.miragesql.integration.spring.SpringConnectionProvider; import org.apache.commons.dbcp2.BasicDataSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import javax.sql.DataSource; @Configuration public class AppConfig { @Bean(destroyMethod = "close") public DataSource dataSource() { BasicDataSource dataSource = new BasicDataSource(); dataSource.setDriverClassName("org.sqlite.JDBC"); dataSource.setUrl("jdbc:sqlite:library.db"); dataSource.setUsername(""); dataSource.setPassword(""); return dataSource; } @Bean public DataSourceTransactionManager transactionManager() { DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(); dataSourceTransactionManager.setDataSource(dataSource()); return dataSourceTransactionManager; } @Bean public SpringConnectionProvider connectionProvider() { SpringConnectionProvider springConnectionProvider = new SpringConnectionProvider(); springConnectionProvider.setTransactionManager(transactionManager()); return springConnectionProvider; } @Bean public SQLiteDialect dialect() { SQLiteDialect dialect = new SQLiteDialect(); return dialect; } @Bean public SqlManagerImpl sqlManager() { SqlManagerImpl sqlManager = new SqlManagerImpl(); sqlManager.setConnectionProvider(connectionProvider()); sqlManager.setDialect(dialect()); return sqlManager; } }
完成後の感想
なんとか動くようになって、ホッとした。。。
最近は、Javaやることが滅多になかったからな。
もしくは、あったけど、1世代古い開発環境だったりで、チャレンジングなことができなかったからな。
久しぶりにDIとかやってみて、かなり手こずってしまった。
作成したもの
参考
Integration · mirage-sql/mirage Wiki · GitHub
雑記
最近の俺、台パンしすぎじゃね?