Spring Bootフレームワークを利用したアプリケーションでMyBatisを利用する際、DBにアクセスするDataSource等のBean定義を自動的に行うことができるが、この機能を利用せず、手動でDBアクセス処理を定義しMyBatisを利用することもできる。
今回は、手動でDBアクセス処理を定義しMyBatisを利用してみたので、共有する。
前提条件
下記記事の実装が完了していること。
作成したサンプルプログラム(Azure Functions側)の内容
作成したサンプルプログラム(Azure Functions側)の構成は以下の通り。なお、App Services側のソースコードは修正していない。

なお、上記の赤枠は、前提条件のプログラムから追加・変更したプログラムである。
<2021年4月13日 追記>
spring-cloud-function-dependenciesのバージョンは、2021年3月16日にリリースしたバージョン3.1.2を利用すると、1つのAzure Functions内に複数のファンクションを含む場合の不具合が解消できている。
その場合、Handlerクラスの継承するクラスを「AzureSpringBootRequestHandler」クラスから「FunctionInvoker」クラスに変更する。
spring-cloud-function-dependenciesの3.1.2を利用した実装サンプルは、以下の記事を参照のこと。
DB接続定義は、以下のXMLで定義している。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="sqldb">
<!-- 接続先DB毎にenvironment要素を記載する -->
<environment id="sqldb">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
<property name="url" value="jdbc:sqlserver://azure-db-purinit.database.windows.net:1433;database=azureSqlDatabase;columnEncryptionSetting=Enabled"/>
<property name="username" value="purinit@azure-db-purinit"/>
<property name="password" value="(DBのパスワード)"/>
</dataSource>
</environment>
</environments>
<!-- 参照するMapperのXMLファイル名を記載する -->
<mappers>
<mapper resource="com/example/mybatis/UserPassMapper.xml" />
</mappers>
</configuration>また、application.propertiesのDB接続設定は不要になるため、削除している。
# Key Vaultへの設定 keyVaultClientId=cdbb5434-e455-4885-b2e6-911f78c4264b keyVaultClientKey=(サービスプリンシパルのパスワード)
さらに、DB接続定義(mybatis-config.xml)を読み込み、SqlSessionファクトリを生成し返却する処理を、以下のユーティリティクラスで定義している。
package com.example.util;
import java.io.IOException;
import java.io.Reader;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class MyBatisUtil {
/** SqlSessionファクトリ */
private static SqlSessionFactory sqlSessionFactory = null;
static {
try {
// MyBatisの定義ファイルを読み込む
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
// SqlSessionファクトリを生成する
// 第2引数には、MyBatisの定義ファイルの接続するDBを識別するidを指定する
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader, "sqldb");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* SqlSessionファクトリを返却する
* @return SqlSessionファクトリ
*/
public static SqlSessionFactory getSqlSessionFactory(){
return sqlSessionFactory;
}
}
また、Mapperインタフェースはクラスに変更し、@Repositoryアノテーションを付与し、各メソッド内でDBセッションの接続/切断する処理を追加している。
package com.example.mybatis;
import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Repository;
import com.example.mybatis.model.UserPass;
import com.example.util.MyBatisUtil;
@Repository
public class UserPassMapper {
/**
* USER_PASSテーブルからデータを1件取得する.
* @return USER_PASSテーブルからの取得結果
*/
public UserPass selectOne() {
SqlSession session = MyBatisUtil.getSqlSessionFactory().openSession();
UserPass userPass = (UserPass)session.selectOne("selectOne");
session.commit();
session.close();
return userPass;
}
/**
* USER_PASSテーブルのデータを更新する.
* @param userPass 更新対象のUSER_PASSテーブルの値
*/
public void updateUserPass(UserPass userPass) {
SqlSession session = MyBatisUtil.getSqlSessionFactory().openSession();
session.update("updateUserPass", userPass);
session.commit();
session.close();
}
}さらに、Azure Functionsのメインクラスは以下の通りで、@EnableAutoConfigurationアノテーションを付与し、Spring Bootのデータソース自動設定機能を無効にしている。
package com.example;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.Bean;
import com.example.model.GetUserPassParam;
import com.example.model.GetUserPassResult;
import com.example.model.UpdUserPassParam;
import com.example.model.UpdUserPassResult;
import com.example.service.GetUserPassService;
import com.example.service.UpdUserPassService;
import com.microsoft.sqlserver.jdbc.SQLServerColumnEncryptionAzureKeyVaultProvider;
import com.microsoft.sqlserver.jdbc.SQLServerColumnEncryptionKeyStoreProvider;
import com.microsoft.sqlserver.jdbc.SQLServerConnection;
// DB接続を手動管理にするため、Spring Bootのデータソース自動設定機能を無効にする
@SpringBootApplication
@EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class })
public class DemoAzureFunction {
/** keyVaultのクライアントID */
@Value("${keyVaultClientId}")
private String keyVaultClientId;
/** keyVaultのクライアントキー */
@Value("${keyVaultClientKey}")
private String keyVaultClientKey;
/** Key Vaultの認証の接続設定が終わっているかどうかを判定するフラグ */
private static boolean keyVaultProviderFlg = false;
/** USER_PASSデータ取得サービスクラスのオブジェクト */
@Autowired
private GetUserPassService getUserPassService;
/** USER_PASSデータ更新サービスクラスのオブジェクト */
@Autowired
private UpdUserPassService updUserPassService;
public static void main(String[] args) throws Exception {
SpringApplication.run(DemoAzureFunction.class, args);
}
/**
* Key Vaultの認証の接続設定を登録する.
* @throws SQLException SQL例外
*/
@PostConstruct
public void postConstruct() throws SQLException {
if (!keyVaultProviderFlg) {
SQLServerColumnEncryptionAzureKeyVaultProvider akvProvider
= new SQLServerColumnEncryptionAzureKeyVaultProvider(
keyVaultClientId, keyVaultClientKey);
Map<String, SQLServerColumnEncryptionKeyStoreProvider> keyStoreMap
= new HashMap<String, SQLServerColumnEncryptionKeyStoreProvider>();
keyStoreMap.put(akvProvider.getName(), akvProvider);
SQLServerConnection.registerColumnEncryptionKeyStoreProviders(keyStoreMap);
keyVaultProviderFlg = true;
}
}
/**
* USER_PASSテーブルのデータを取得し結果を返却する関数
* @return USER_PASSテーブルデータ取得サービスクラスの呼出結果
*/
@Bean
public Function<GetUserPassParam, GetUserPassResult> getUserPass() {
return getUserPassParam -> getUserPassService.getUserPass(getUserPassParam);
}
/**
* USER_PASSテーブルのデータを更新し結果を返却する関数
* @return USER_PASSテーブルデータ更新サービスクラスの呼出結果
*/
@Bean
public Function<UpdUserPassParam, UpdUserPassResult> updUserPass(){
return updUserPassParam -> updUserPassService.updUserPass(updUserPassParam);
}
}その他のソースコード内容は、以下のサイトを参照のこと。
https://github.com/purin-it/azure/tree/master/always-encrypted-db-manual/demoAzureFunc
サンプルプログラムの実行結果
サンプルプログラムの実行結果は、以下の記事の「サンプルプログラムの実行結果」と同じになる。
要点まとめ
- Spring Bootフレームワークを利用したアプリケーションでMyBatisを利用する際、Spring Bootのデータソース自動設定機能を無効にして、手動でDBアクセス処理を定義しMyBatisを利用することもできる。





