SpringBootでMicrosoftAccessのデータベースへの接続は諦めました

# 概要

SpringBoot ⇒ MicrosoftAccessへ接続して、データの取得や更新の処理を作ることを諦めました。
今後似たようなことを検討する時の材料として記事を残します。

# やりたかったこと

MicrosoftAccess（accdbファイル）で作られた古いシステムがありました。
SpringBootでそのシステムが持っているテーブルのデータが必要でした。

また、ちょっとめんどくさい点として、そのaccdbファイルはパスワードでロックされているものでした。

# UCanAccessの存在

まず、『UCanAccess』というjarがあり、それを使うとJAVAからAccessへの接続ができると分かりました。

# build.gradleでjarの用意

build.gradleのdependenciesに下記を追加しました。

```
implementation ('net.sf.ucanaccess:ucanaccess:5.0.1'){
	exclude module: 'commons-logging'
}

implementation ('com.healthmarketscience.jackcess:jackcess-encrypt:4.0.1') {
    exclude module: 'commons-logging'
}
```

下記をやるとGradleがjarを用意してくれました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/1371ffb9-7362-2c20-0c48-2a02fc2a3064.png)

パスワード無しaccdbへ接続するだけならucanaccessのみでOKです。
ですが、パスワード付accdbだと **jackcess-encryptも追加で必要** です。

また、 **commons-loggingを除外** するのもポイントです。
この除外しないとSpring起動時に下記のような警告が出てしまいます。


> Standard Commons Logging discovery in action with spring-jcl: please remove commons-logging.jar from classpath in order to avoid potential conflicts

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/7f20e040-cdc3-2645-9de1-da53c99e960d.png)

UCanAccessもjackcess-encryptもcommons-logging.jarを使っています。
でもそのjarはSpringBootとなんか衝突して良くないから削除した方がいいよって警告です。

# JackcessOpenerInterfaceの実装

jarを用意するだけでは足りず、下記のようなクラスを自作する必要があります。

```java:Dec.java
package com.example.demo;


import java.io.File;
import java.io.IOException;

import com.healthmarketscience.jackcess.Database;
import com.healthmarketscience.jackcess.DatabaseBuilder;
import com.healthmarketscience.jackcess.crypt.CryptCodecProvider;

import net.ucanaccess.jdbc.JackcessOpenerInterface;


//クラス名に縛りは無いです。
//今回はこんな名前にしてみました。
public class Dec implements JackcessOpenerInterface {

	
	@Override
	public Database open(File file, String password) throws IOException {
		DatabaseBuilder db_ = new DatabaseBuilder(file);
		db_.setAutoSync(false);
		db_.setCodecProvider(new CryptCodecProvider(password));
		db_.setReadOnly(false);
		return db_.open();
	}
	
	
}
```

# Controllerクラス

```java:DemoController.java
package com.example.demo;


import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

import jakarta.servlet.http.HttpServletResponse;


@Controller
public class DemoController {
	
	
	@GetMapping("/")
	public void getIndex(HttpServletResponse response) throws IOException {
		
		String url_ = "jdbc:ucanaccess://C:/※フォルダー/dr.accdb;";
		//パスワード付accdbの場合、jackcessOpenerに自作クラスを指定するのがポイント。
		url_ += "jackcessOpener=com.example.demo.Dec;";
		
		//accdbの場合、ユーザー名は空文字でOK。
        String user_ = "";
        String password_ = "※パスワード";
        
      
        try (Connection connection_ = DriverManager.getConnection(url_, user_, password_)) {
        	
        	System.out.println("接続できた");

            String sql_ = "SELECT * FROM t1";
            
            try (Statement statement = connection_.createStatement();
            		ResultSet resultSet = statement.executeQuery(sql_)) {

            	while (resultSet.next()) {
               
                    System.out.println(resultSet.getString("カラム名だにゃん"));
                    
                }
            	
            }
            

        } catch (Exception e_) {
            e_.printStackTrace();
        }
		
		
	}
	
	
}
```

# 接続できるが大量の警告が…

例えばパスワード付accdbのテーブルが下記の時…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/42f8a5d1-e2b0-85e9-6bb5-c8654d61cc0f.png)

こんな風に接続できて値とれるのですが、大量の警告が…。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/121648cb-20fb-da25-77aa-5318eb450211.png)

この警告が

* 何が原因で起きてるのか。
* 無視してよいものかどうか。

が分からず、突っ込んで調べる時間も無かったです。

これが諦めた理由の一つです。

# Accessのデータベース並び順設定によっては更なる警告も

下記状態で作ったaccdbに接続すると警告出てしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/bcf459b7-4e97-0a8d-3b79-05eafe4eac6c.png)

下記のように変更して、さらに『最適化修復』をすれば警告は出なくなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/ed2f85f6-7dc6-8261-82df-85e04fb24503.png)

これについても、『変更して想定外のバグが起きないか』の判断ができず、動作検証の時間もありませんでした。

運悪く対象のaccdbは『日本語 - レガシー』で作られていました…。

これも諦めた理由の一つです。

# 蛇足

別プログラムからAccessに接続するならC#がめちゃくちゃ楽でした。

「JAVAで悪戦苦闘してたのは一体何だったの…」
ってレベルでサクッと動作確認サンプル作れました。

# バージョン

Microsoft Windows [Version 10.0.19045.4170]
JAVA 17.0.8.1
Spring Boot v3.1.10