エンターテイメント!!

遊戯王好きのJavaエンジニアのブログ。バーニングソウルを会得する特訓中。

SpringでMirageSQLをAutowiredでDIして使う

背景

久しぶりに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とかやってみて、かなり手こずってしまった。

作成したもの

GitHub - suzaku-tec/GaleWing

参考

Integration · mirage-sql/mirage Wiki · GitHub

雑記

最近の俺、台パンしすぎじゃね?