0
0

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

Last updated at Posted at 2024-04-04

概要

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

パスワード無し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

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

JackcessOpenerInterfaceの実装

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

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クラス

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

こんな風に接続できて値とれるのですが、大量の警告が…。
image.png

この警告が

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

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

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

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

下記状態で作ったaccdbに接続すると警告出てしまいます。
image.png

下記のように変更して、さらに『最適化修復』をすれば警告は出なくなります。
image.png

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

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

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

蛇足

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

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

バージョン

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

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0