Azure SQL Database で Java と JDBC を使用する
適用対象: Azure SQL データベース
このトピックでは、Java と JDBC を使って Azure SQL Database で情報を格納および取得するサンプル アプリケーションを作成する方法を説明します。
JDBC は、従来のリレーショナル データベースに接続するための標準の Java API です。
前提条件
- Azure アカウント。 所有していない場合は、無料試用版を入手してください。
- Azure Cloud Shell または Azure CLI。 Azure Cloud Shell をお勧めします。これにより、自動的にログインし、必要なすべてのツールにアクセスできるようになります。
- サポートされている Java 開発キット、バージョン 8 (Azure Cloud Shell に含まれます)。
- Apache Maven ビルド ツール。
作業環境を準備する
入力ミスを少なくし、特定のニーズに応じて以下の構成をカスタマイズしやすくするために、ここでは環境変数を使用します。
次のコマンドを使用して環境変数を設定します。
AZ_RESOURCE_GROUP=database-workshop
AZ_DATABASE_NAME=<YOUR_DATABASE_NAME>
AZ_LOCATION=<YOUR_AZURE_REGION>
AZ_SQL_SERVER_USERNAME=demo
AZ_SQL_SERVER_PASSWORD=<YOUR_AZURE_SQL_PASSWORD>
AZ_LOCAL_IP_ADDRESS=<YOUR_LOCAL_IP_ADDRESS>
プレースホルダーは、この記事全体で使用される次の値に置き換えてください。
<YOUR_DATABASE_NAME>
:Azure SQL Database サーバーの名前。 Azure 全体で一意である必要があります。<YOUR_AZURE_REGION>
:使用する Azure リージョン。 既定でeastus
を使用できますが、居住地に近いリージョンを構成することをお勧めします。 「az account list-locations
」を入力すると、使用可能なリージョンの完全な一覧を表示できます。<AZ_SQL_SERVER_PASSWORD>
:Azure SQL Database サーバーのパスワード。 パスワードは 8 文字以上にする必要があります。 これには、英大文字、英小文字、数字 (0 から 9)、英数字以外の文字 (!、$、#、% など) のうち、3 つのカテゴリの文字が含まれている必要があります。<YOUR_LOCAL_IP_ADDRESS>
:ローカル コンピューターの IP アドレス。そこから、Java アプリケーションを実行します。 これを確認する簡単な方法は、ブラウザーで whatismyip.akamai.comにアクセスすることです。
次に、リソース グループを作成するには、次のコマンドを使用します。
az group create \
--name $AZ_RESOURCE_GROUP \
--location $AZ_LOCATION \
| jq
注意
jq
ユーティリティを使用し、JSON データを表示し、より読みやすくします。 このユーティリティは既定で Azure Cloud Shell にインストールされます。 このツールを使用しない場合は、使用するすべてのコマンドの | jq
の部分を削除しても問題ありません。
データベースの作成
最初に作成するのは、Azure SQL Database 用マネージド論理サーバーです。
Azure Cloud Shell で次のコマンドを実行します。
az sql server create \
--resource-group $AZ_RESOURCE_GROUP \
--name $AZ_DATABASE_NAME \
--location $AZ_LOCATION \
--admin-user $AZ_SQL_SERVER_USERNAME \
--admin-password $AZ_SQL_SERVER_PASSWORD \
| jq
このコマンドを実行すると、データベースの論理サーバーが作成されます。
サーバーのファイアウォール規則を構成する
Azure SQL Database には受信接続を一切許可しないファイアウォールがあるので、既定でセキュリティ保護されています。 データベースを使用できるようにするには、データベース サーバーにアクセスするためのローカル IP アドレスを許可するファイアウォール規則を追加する必要があります。
この記事の冒頭でローカル IP アドレスを構成したので、次のコマンドを実行してサーバーのファイアウォールを開くことができます。
az sql server firewall-rule create \
--resource-group $AZ_RESOURCE_GROUP \
--name $AZ_DATABASE_NAME-database-allow-local-ip \
--server $AZ_DATABASE_NAME \
--start-ip-address $AZ_LOCAL_IP_ADDRESS \
--end-ip-address $AZ_LOCAL_IP_ADDRESS \
| jq
データベースを構成する
先ほど作成したサーバーは空です。 Java アプリケーションで使用できるデータベースはありません。 次のコマンドを実行し、demo
という名前の新しいデータベースを作成します。
az sql db create \
--resource-group $AZ_RESOURCE_GROUP \
--name demo \
--server $AZ_DATABASE_NAME \
| jq
新しい Java プロジェクトを作成する
任意の IDE を使用して新しい Java プロジェクトを作成し、そのルート ディレクトリに pom.xml
ファイルを追加します。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>12.4.2.jre11</version>
</dependency>
</dependencies>
</project>
このファイルは、以下を使用するようにプロジェクトを構成する Apache Maven です。
- Java 17
- 最近の Java 用 SQL Server ドライバー
Azure SQL Database に接続するための構成ファイルを準備する
src/main/resources/application.properties ファイルを作成して、以下を追加します。
url=jdbc:sqlserver://$AZ_DATABASE_NAME.database.windows.net:1433;database=demo;encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;
user=demo@$AZ_DATABASE_NAME
password=$AZ_SQL_SERVER_PASSWORD
- 2 つの
$AZ_DATABASE_NAME
変数を、この記事の冒頭で構成した値に置き換えます。 $AZ_SQL_SERVER_PASSWORD
変数を、この記事の冒頭で構成した値で置き換えます。
データベース スキーマを生成する SQL ファイルを作成する
データベース スキーマを作成するためには、src/main/resources/schema.sql
ファイルを使用します。 このファイルを次の内容で作成します。
DROP TABLE IF EXISTS todo;
CREATE TABLE todo (id INT PRIMARY KEY, description VARCHAR(255), details VARCHAR(4096), done BIT);
アプリケーションをコーディングする
データベースに接続する
次に、JDBC を使用して Azure SQL Database のデータを格納および取得する Java コードを追加します。
次のコードを含んだ src/main/java/com/example/demo/DemoApplication.java ファイルを作成します。
package com.example.demo;
import java.sql.*;
import java.util.*;
import java.util.logging.Logger;
public class DemoApplication {
private static final Logger log;
static {
System.setProperty("java.util.logging.SimpleFormatter.format", "[%4$-7s] %5$s %n");
log =Logger.getLogger(DemoApplication.class.getName());
}
public static void main(String[] args) throws Exception {
log.info("Loading application properties");
Properties properties = new Properties();
properties.load(DemoApplication.class.getClassLoader().getResourceAsStream("application.properties"));
log.info("Connecting to the database");
Connection connection = DriverManager.getConnection(properties.getProperty("url"), properties);
log.info("Database connection test: " + connection.getCatalog());
log.info("Create database schema");
Scanner scanner = new Scanner(DemoApplication.class.getClassLoader().getResourceAsStream("schema.sql"));
Statement statement = connection.createStatement();
while (scanner.hasNextLine()) {
statement.execute(scanner.nextLine());
}
/*
Todo todo = new Todo(1L, "configuration", "congratulations, you have set up JDBC correctly!", true);
insertData(todo, connection);
todo = readData(connection);
todo.setDetails("congratulations, you have updated data!");
updateData(todo, connection);
deleteData(todo, connection);
*/
log.info("Closing database connection");
connection.close();
}
}
この Java コードは、SQL Server データベースに接続するため、またデータを格納するスキーマを作成するために、先ほど作成した application.properties ファイルと schema.sql ファイルを使用します。
このファイルを見るとわかるように、データの挿入、読み取り、更新、削除のためのメソッドがコメント化されています。これらのメソッドのコードは、この記事の中で後から作成します。それぞれのメソッドが完成したら都度、コメント解除することができます。
注意
データベースの資格情報は、application.properties ファイルの user プロパティと password プロパティに格納されます。 プロパティ ファイルは引数として渡されるため、これらの資格情報は DriverManager.getConnection(properties.getProperty("url"), properties);
を実行するときに使用されます。
以後、このメイン クラスは、次の任意のツールを使用して実行することができます。
- IDE を使用する場合: DemoApplication クラスを右クリックして実行します。
- Maven を使用する場合:
mvn package exec:java -Dexec.mainClass="com.example.demo.DemoApplication"
を実行することによってアプリケーションを実行できます。
次のコンソール ログが示すように、このアプリケーションは、Azure SQL Database に接続してデータベース スキーマを作成した後、接続を閉じます。
[INFO ] Loading application properties
[INFO ] Connecting to the database
[INFO ] Database connection test: demo
[INFO ] Create database schema
[INFO ] Closing database connection
ドメイン クラスを作成する
DemoApplication
クラスの横に新しい Todo
Java クラスを作成し、以下のコードを追加します。
package com.example.demo;
public class Todo {
private Long id;
private String description;
private String details;
private boolean done;
public Todo() {
}
public Todo(Long id, String description, String details, boolean done) {
this.id = id;
this.description = description;
this.details = details;
this.done = done;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getDetails() {
return details;
}
public void setDetails(String details) {
this.details = details;
}
public boolean isDone() {
return done;
}
public void setDone(boolean done) {
this.done = done;
}
@Override
public String toString() {
return "Todo{" +
"id=" + id +
", description='" + description + '\'' +
", details='" + details + '\'' +
", done=" + done +
'}';
}
}
このクラスは、schema.sql スクリプトを実行する際に作成した todo
テーブルにマップされるドメイン モデルです。
データの挿入
src/main/java/DemoApplication.java ファイルの main メソッドの後に、データベースにデータを挿入するための次のメソッドを追加します。
private static void insertData(Todo todo, Connection connection) throws SQLException {
log.info("Insert data");
PreparedStatement insertStatement = connection
.prepareStatement("INSERT INTO todo (id, description, details, done) VALUES (?, ?, ?, ?);");
insertStatement.setLong(1, todo.getId());
insertStatement.setString(2, todo.getDescription());
insertStatement.setString(3, todo.getDetails());
insertStatement.setBoolean(4, todo.isDone());
insertStatement.executeUpdate();
}
これで、main
メソッドの次の 2 つの行のコメントを解除できます。
Todo todo = new Todo(1L, "configuration", "congratulations, you have set up JDBC correctly!", true);
insertData(todo, connection);
メイン クラスを実行すると、次の出力が生成されるはずです。
[INFO ] Loading application properties
[INFO ] Connecting to the database
[INFO ] Database connection test: demo
[INFO ] Create database schema
[INFO ] Insert data
[INFO ] Closing database connection
データの読み取り
先ほど挿入したデータを読み取って、コードが正しく動作することを確認しましょう。
src/main/java/DemoApplication.java ファイルの insertData
メソッドの後に、データベースからデータを読み取るための次のメソッドを追加します。
private static Todo readData(Connection connection) throws SQLException {
log.info("Read data");
PreparedStatement readStatement = connection.prepareStatement("SELECT * FROM todo;");
ResultSet resultSet = readStatement.executeQuery();
if (!resultSet.next()) {
log.info("There is no data in the database!");
return null;
}
Todo todo = new Todo();
todo.setId(resultSet.getLong("id"));
todo.setDescription(resultSet.getString("description"));
todo.setDetails(resultSet.getString("details"));
todo.setDone(resultSet.getBoolean("done"));
log.info("Data read from the database: " + todo.toString());
return todo;
}
これで、main
メソッドの次の行のコメントを解除できます。
todo = readData(connection);
メイン クラスを実行すると、次の出力が生成されるはずです。
[INFO ] Loading application properties
[INFO ] Connecting to the database
[INFO ] Database connection test: demo
[INFO ] Create database schema
[INFO ] Insert data
[INFO ] Read data
[INFO ] Data read from the database: Todo{id=1, description='configuration', details='congratulations, you have set up JDBC correctly!', done=true}
[INFO ] Closing database connection
データの更新
先ほど挿入したデータを更新しましょう。
引き続き src/main/java/DemoApplication.java ファイルの readData
メソッドの後に、データベース内のデータを更新するための次のメソッドを追加します。
private static void updateData(Todo todo, Connection connection) throws SQLException {
log.info("Update data");
PreparedStatement updateStatement = connection
.prepareStatement("UPDATE todo SET description = ?, details = ?, done = ? WHERE id = ?;");
updateStatement.setString(1, todo.getDescription());
updateStatement.setString(2, todo.getDetails());
updateStatement.setBoolean(3, todo.isDone());
updateStatement.setLong(4, todo.getId());
updateStatement.executeUpdate();
readData(connection);
}
これで、main
メソッドの次の 2 つの行のコメントを解除できます。
todo.setDetails("congratulations, you have updated data!");
updateData(todo, connection);
メイン クラスを実行すると、次の出力が生成されるはずです。
[INFO ] Loading application properties
[INFO ] Connecting to the database
[INFO ] Database connection test: demo
[INFO ] Create database schema
[INFO ] Insert data
[INFO ] Read data
[INFO ] Data read from the database: Todo{id=1, description='configuration', details='congratulations, you have set up JDBC correctly!', done=true}
[INFO ] Update data
[INFO ] Read data
[INFO ] Data read from the database: Todo{id=1, description='configuration', details='congratulations, you have updated data!', done=true}
[INFO ] Closing database connection
データの削除
最後に、先ほど挿入したデータを削除しましょう。
引き続き src/main/java/DemoApplication.java ファイルの updateData
メソッドの後に、データベース内のデータを削除するための次のメソッドを追加します。
private static void deleteData(Todo todo, Connection connection) throws SQLException {
log.info("Delete data");
PreparedStatement deleteStatement = connection.prepareStatement("DELETE FROM todo WHERE id = ?;");
deleteStatement.setLong(1, todo.getId());
deleteStatement.executeUpdate();
readData(connection);
}
これで、main
メソッドの次の行のコメントを解除できます。
deleteData(todo, connection);
メイン クラスを実行すると、次の出力が生成されるはずです。
[INFO ] Loading application properties
[INFO ] Connecting to the database
[INFO ] Database connection test: demo
[INFO ] Create database schema
[INFO ] Insert data
[INFO ] Read data
[INFO ] Data read from the database: Todo{id=1, description='configuration', details='congratulations, you have set up JDBC correctly!', done=true}
[INFO ] Update data
[INFO ] Read data
[INFO ] Data read from the database: Todo{id=1, description='configuration', details='congratulations, you have updated data!', done=true}
[INFO ] Delete data
[INFO ] Read data
[INFO ] There is no data in the database!
[INFO ] Closing database connection
結論とリソースのクリーンアップ
お疲れさまでした。 JDBC を使用して、Azure SQL Database でデータを格納および取得する Java アプリケーションを作成しました。
このクイックスタートで使用したすべてのリソースをクリーンアップするには、次のコマンドを使用してリソース グループを削除します。
az group delete \
--name $AZ_RESOURCE_GROUP \
--yes