はじめに
この記事は ZOZO #2 Advent Calendar 2022 21日目の記事になります。
今回はDockerを用いてSQLServerの環境をローカルに構築し、それをJavaのアプリケーションから接続しようと思います。
また、テストデータの作成も合わせて行います。
ディレクトリ構成
ディレクトリ構成は以下になります。
今回の記事に関係ないディレクトリやファイルは省略してます。
docker-sqlserver-service
├─script
│ ├─ DDL
│ │ └─ employee.sql(employeeテーブル作成用のファイル)
│ ├─ DML
│ │ └─ insert.sql(employeeテーブルにデータを登録するファイル)
│ └ init.sh(テストデータ作成用のシェルスクリプト)
├── src
│ └─ main
│ ├─ java
│ │ └─ com
│ │ └─ example
│ │ └─ employee
│ │ ├─ EmployeeApplication.java
│ │ └─ EmployeeRepository.java
│ └── resources
│ └─application.properties
├── build.gradle
├── gradlew
├── docker-compose.yml
・
・
・
docker-compose.ymlの設定
設定内容は以下になります。
項目名 | 説明 | 設定値 | 備考 |
---|---|---|---|
image | コンテナのイメージ | 2022-latest | 現状の最新版 |
conainer_name | コンテナ名 | mssql-test | |
ports | ポート | "11433:1433" | ホスト : 11433 コンテナ : 1433 |
ACCEPT_EULA | 使用許諾契約書の承諾 | Y | |
MSSQL_SA_PASSWORD | SA ユーザーのパスワード | h0geHugaPiyo | パスワードポリシー |
MSSQL_PID | SQLServerのエディションまたはプロダクトキー | Express | |
MSSQL_LCID | SQLServer に使用する言語ID | 1041 | 日本語 |
MSSQL_COLLATION | SQLServerの既定の照合順序 | Japanese_CI_AS |
yamlファイルのサンプルは以下です。
version: "3"
services:
mssql:
image: mcr.microsoft.com/mssql/server:2022-latest
container_name: mssql-test
ports:
- "11433:1433"
environment:
- ACCEPT_EULA=Y
- SA_PASSWORD=h0geHugaPiyo
- MSSQL_PID=Express
- MSSQL_LCID=1041
- MSSQL_COLLATION=Japanese_CI_AS
dockerの起動
以下のコマンドを実行してコンテナを起動します。
$ docker-compose up -d
コンテナが起動しているかは以下のコマンドで確認します。
$ docker-compose ps
コンテナの停止・削除は以下のコマンドになります。
$ docker-compose down
テストデータの作成
Microsoft ODBC Driver 18 for SQL Server をインストール(MacOS)
テストデータを作成するシェルスクリプトに必要なドライバーをインストールします。
公式からインストールの部分だけ抜粋してます。
下記のコマンドを1行ずつ実行してください。
詳しく知りたい方は公式ドキュメントをご参考ください。
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
brew tap microsoft/mssql-release https://github.com/Microsoft/homebrew-mssql-release
brew update
HOMEBREW_ACCEPT_EULA=Y brew install msodbcsql18 mssql-tools18
SQLファイルの作成
シェルスクリプトで実行するSQLファイルを作成します。
テーブルの作成をするファイル(employee.sql)
CREATE TABLE employee(
id INT IDENTITY(1,1) not null,
name VARCHAR(20) not null,
created_at datetime,
updated_at datetime,
primary key(id)
);
データを挿入するファイル(insert.sql)
INSERT INTO employee VALUES ('佐藤',getdate(),getdate());
INSERT INTO employee VALUES ('鈴木',getdate(),getdate());
INSERT INTO employee VALUES ('田中',getdate(),getdate());
シェルスクリプトの作成
下記のシェルスクリプトを作成し、実行します。
シェルスクリプトではテーブルの作成とテストデータの挿入を行います。
また、何度でも実行できるように、実行前に作成されているテーブルをDROPしています。
#!/bin/bash
ddl_dir_path="./DDL/*" # DDLのsqlファイルが有るディレクトリを指定
ddl_files=`find $ddl_dir_path -maxdepth 0 -type f -name *.sql` # ディレクトリ内のファイルを取得
user_id="sa"
password="h0geHugaPiyo"
ip_address="127.0.0.1" #localhostでは動かないので注意
port="11433"
# すでにテーブルが作成されていた場合はDROPする
tbl_names=`sqlcmd -S $ip_address,$port -d tempdb -U $user_id -P $password -Q "SET NOCOUNT ON; SELECT name FROM sys.tables" -h -1`
for tbl_name in $tbl_names
do
sqlcmd -S $ip_address,$port -d tempdb -U $user_id -P $password -Q "DROP TABLE ${tbl_name}"
done
# テーブルの作成
for ddl_file in $ddl_files;
do
sqlcmd -S $ip_address,$port -d tempdb -U $user_id -P $password -i $ddl_file -b
#実行結果
res=$?
# -bの返り値が0より大きい場合はエラーとする
if [ $res -gt 0 ]; then
echo $ddl_file "エラー"
exit 1;
else
echo $ddl_file "成功"
fi
done
# テストデータの挿入
dml_dir_path="./DML/*"
dml_files=`find $dml_dir_path -maxdepth 0 -type f -name *.sql`
for dml_file in $dml_files;
do
sqlcmd -S $ip_address,$port -d tempdb -U $user_id -P $password -i $dml_file -b
#実行結果
res=$?
# -bの返り値が0より大きい場合はエラーとする
if [ $res -gt 0 ]; then
echo $ddl_file "エラー"
exit 1;
else
echo $ddl_file "成功"
fi
done
# 挿入したデータの確認
sqlcmd -S $ip_address,$port -d tempdb -U $user_id -P $password -Q "SELECT * FROM employee"
build.gradleの設定
dependenciesに以下を追記し、必要なライブラリをインストールします。
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-devtools'
implementation "org.springframework.boot:spring-boot-starter-jdbc"
implementation 'com.microsoft.sqlserver:mssql-jdbc:11.2.1.jre17'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
application.propertiesの設定
application.propertiesに以下を記載して、アプリケーション側にDBの接続設定を行います。
spring.datasource.url=jdbc:sqlserver://localhost:11433;databaseName=tempdb;encrypt=false;
spring.datasource.username=sa
spring.datasource.password=h0geHugaPiyo
spring.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
アプリケーションの構築
SQLServerのテーブルからデータの一覧を取得するAPIを作成します。
Appication層
package com.example.employee;
import java.util.List;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class EmployeeApplication {
private final EmployeeRepository employeeRepository;
public EmployeeApplication(
EmployeeRepository employeeRepository) {
this.employeeRepository = employeeRepository;
}
public static void main(String[] args) {
SpringApplication.run(EmployeeApplication.class, args);
}
@GetMapping("/employee")
public List getEmployeeList() {
return employeeRepository.getAll();
}
}
Repository層
package com.example.employee;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
@Repository
@RequiredArgsConstructor
public class EmployeeRepository {
private final JdbcTemplate jdbcTemplate;
public List getAll(){
String sql = "SELECT * FROM employee";
List<Map<String, Object>> dateList = jdbcTemplate.queryForList(sql);
List<String> result = new ArrayList<>();
dateList.forEach(
x -> result.add(x.get("id") + "," + x.get("name") + "," + x.get("created_at") + "," + x.get("updated_at"))
);
return result;
}
}
アプリケーションの起動と実行方法
アプリケーションを起動したあとに、APIを実行することでデータベースに挿入したテストデータを取得することができます。
アプリケーションの起動方法
./gradlew bootRun
APIの実行方法
curl http://localhost:8080/employee
実行結果
["1,鈴木,2022-12-05 05:05:16.673,2022-12-05 05:05:16.673","2,田中,2022-12-05 05:05:16.673,2022-12-05 05:05:16.673","3,佐藤,2022-12-05 05:05:16.673,2022-12-05 05:05:16.673"]
おわりに
以上で、Dockerで立ち上げたSQLServerにJavaから接続することができました。
少しでも誰かの役に立てるナレッジとなれば幸いです。
ご意見・ご質問・ご指摘等あれば、コメントで教えていただけますようお願いいたします。
読んでいただきありがとうございました。