Menggunakan Java dan JDBC dengan Azure Database for MySQL - Server Fleksibel

BERLAKU UNTUK: Azure Database for MySQL - Server Fleksibel

Topik ini menunjukkan pembuatan aplikasi sampel yang menggunakan Java dan JDBC untuk menyimpan dan mengambil informasi di server fleksibel Azure Database for MySQL.

JDBC adalah Java API standar untuk terhubung ke database hubungan tradisional.

Dalam artikel ini, kita akan menyertakan dua metode autentikasi: Autentikasi Microsoft Entra dan autentikasi MySQL. Tab Tanpa Kata Sandi memperlihatkan autentikasi Microsoft Entra dan tab Kata Sandi memperlihatkan autentikasi MySQL.

Autentikasi Microsoft Entra adalah mekanisme untuk menyambungkan ke server fleksibel Azure Database for MySQL menggunakan identitas yang ditentukan dalam ID Microsoft Entra. Dengan autentikasi Microsoft Entra, Anda dapat mengelola identitas pengguna database dan layanan Microsoft lain di lokasi pusat, yang menyederhanakan manajemen izin.

Autentikasi MySQL menggunakan akun yang disimpan di MySQL. Jika Anda memilih untuk menggunakan kata sandi sebagai kredensial untuk akun, kredensial ini akan disimpan dalam user tabel. Karena kata sandi ini disimpan di MySQL, Anda harus mengelola rotasi kata sandi sendiri.

Prasyarat

Menyiapkan lingkungan kerja

Pertama, gunakan perintah berikut untuk menyiapkan beberapa variabel lingkungan.

export AZ_RESOURCE_GROUP=database-workshop
export AZ_DATABASE_NAME=<YOUR_DATABASE_NAME>
export AZ_LOCATION=<YOUR_AZURE_REGION>
export AZ_MYSQL_AD_NON_ADMIN_USERNAME=demo-non-admin
export AZ_USER_IDENTITY_NAME=<YOUR_USER_ASSIGNED_MANAGED_IDENTITY_NAME>
export CURRENT_USERNAME=$(az ad signed-in-user show --query userPrincipalName -o tsv)
export CURRENT_USER_OBJECTID=$(az ad signed-in-user show --query id -o tsv)

Ganti tempat penampung dengan nilai berikut, yang digunakan di seluruh artikel ini:

  • <YOUR_DATABASE_NAME>: Nama instans server fleksibel Azure Database for MySQL Anda, yang harus unik di seluruh Azure.
  • <YOUR_AZURE_REGION>: Wilayah Azure yang akan Anda gunakan. Anda dapat menggunakan eastus secara default, tetapi kami menyarankan agar Anda mengonfigurasi wilayah yang lebih dekat ke tempat tinggal Anda. Anda dapat melihat daftar lengkap wilayah yang tersedia dengan memasukkan az account list-locations.
  • <YOUR_USER_ASSIGNED_MANAGED_IDENTITY_NAME>: Nama server identitas terkelola yang ditetapkan pengguna Anda, yang harus unik di seluruh Azure.

Selanjutnya, buat grup sumber daya:

az group create \
    --name $AZ_RESOURCE_GROUP \
    --location $AZ_LOCATION \
    --output tsv

Membuat instans Azure Database for MySQL

Membuat instans server fleksibel Azure Database for MySQL dan menyiapkan pengguna admin

Hal pertama yang Anda buat adalah instans server fleksibel Azure Database for MySQL terkelola.

Catatan

Anda dapat membaca informasi lebih rinci tentang membuat server MySQL di Membuat instans server fleksibel Azure Database for MySQL dengan menggunakan portal Azure.

Jika Anda menggunakan Azure CLI, jalankan perintah berikut untuk memastikannya memiliki izin yang memadai:

az login --scope https://graph.microsoft.com/.default

Jalankan perintah berikut untuk membuat server:

az mysql flexible-server create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name $AZ_DATABASE_NAME \
    --location $AZ_LOCATION \
    --yes \
    --output tsv

Jalankan perintah berikut untuk membuat identitas yang ditetapkan pengguna untuk menetapkan:

az identity create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name $AZ_USER_IDENTITY_NAME

Penting

Setelah membuat identitas yang ditetapkan pengguna, minta Administrator Global atau Administrator Peran Istimewa Anda untuk memberikan izin berikut untuk identitas ini: User.Read.All, GroupMember.Read.All, dan Application.Read.ALL. Untuk informasi selengkapnya, lihat bagian Izin autentikasi Direktori Aktif.

Jalankan perintah berikut untuk menetapkan identitas ke server fleksibel Azure Database for MySQL untuk membuat admin Microsoft Entra:

az mysql flexible-server identity assign \
    --resource-group $AZ_RESOURCE_GROUP \
    --server-name $AZ_DATABASE_NAME \
    --identity $AZ_USER_IDENTITY_NAME

Jalankan perintah berikut untuk mengatur pengguna admin Microsoft Entra:

az mysql flexible-server ad-admin create \
    --resource-group $AZ_RESOURCE_GROUP \
    --server-name $AZ_DATABASE_NAME \
    --display-name $CURRENT_USERNAME \
    --object-id $CURRENT_USER_OBJECTID \
    --identity $AZ_USER_IDENTITY_NAME

Penting

Saat mengatur administrator, pengguna baru ditambahkan ke instans server fleksibel Azure Database for MySQL dengan izin administrator penuh. Hanya satu admin Microsoft Entra yang dapat dibuat per instans server fleksibel Azure Database for MySQL dan pilihan yang lain yang akan menimpa admin Microsoft Entra yang ada yang dikonfigurasi untuk server.

Perintah ini membuat instans server fleksibel Azure Database for MySQL kecil dan mengatur admin Direktori Aktif ke pengguna yang masuk.

Instans server fleksibel Azure Database for MySQL yang Anda buat memiliki database kosong yang disebut flexibleserverdb.

Memiliki masalah? Beri tahu kami.

Mengonfigurasi aturan firewall untuk instans server fleksibel Azure Database for MySQL Anda

Instans server fleksibel Azure Database for MySQL diamankan secara default. Mereka memiliki firewall yang tidak mengizinkan koneksi masuk.

Anda dapat melewati langkah ini jika Anda menggunakan Bash karena flexible-server create perintah sudah mendeteksi alamat IP lokal Anda dan mengaturnya di server MySQL.

Jika Anda menyambungkan ke instans server fleksibel Azure Database for MySQL dari Subsistem Windows untuk Linux (WSL) di komputer Windows, Anda harus menambahkan ID host WSL ke firewall Anda. Dapatkan alamat IP komputer host Anda dengan menjalankan perintah berikut di WSL:

sudo cat /etc/resolv.conf

Salin alamat IP dengan mengikuti istilah nameserver, lalu gunakan perintah berikut untuk mengatur variabel lingkungan untuk Alamat IP WSL:

AZ_WSL_IP_ADDRESS=<the-copied-IP-address>

Kemudian, gunakan perintah berikut untuk membuka firewall server ke aplikasi berbasis WSL Anda:

az mysql flexible-server firewall-rule create \
    --resource-group $AZ_RESOURCE_GROUP \
    --name $AZ_DATABASE_NAME \
    --start-ip-address $AZ_WSL_IP_ADDRESS \
    --end-ip-address $AZ_WSL_IP_ADDRESS \
    --rule-name allowiprange \
    --output tsv

Mengonfigurasikan database MySQL

Buat database baru bernama demo dengan menjalankan perintah berikut ini:

az mysql flexible-server db create \
    --resource-group $AZ_RESOURCE_GROUP \
    --database-name demo \
    --server-name $AZ_DATABASE_NAME \
    --output tsv

Membuat pengguna non-admin MySQL dan memberikan izin

Selanjutnya, buat pengguna non-admin dan berikan semua izin pada database ke demo dalamnya.

Catatan

Anda dapat membaca informasi selengkapnya tentang membuat pengguna MySQL di Membuat pengguna di Azure Database for MySQL.

Buat skrip SQL yang disebut create_ad_user.sql untuk membuat pengguna non-admin. Tambahkan konten berikut dan simpan secara lokal:

export AZ_MYSQL_AD_NON_ADMIN_USERID=$CURRENT_USER_OBJECTID

cat << EOF > create_ad_user.sql
SET aad_auth_validate_oids_in_tenant = OFF;

CREATE AADUSER '$AZ_MYSQL_AD_NON_ADMIN_USERNAME' IDENTIFIED BY '$AZ_MYSQL_AD_NON_ADMIN_USERID';

GRANT ALL PRIVILEGES ON demo.* TO '$AZ_MYSQL_AD_NON_ADMIN_USERNAME'@'%';

FLUSH privileges;

EOF

Kemudian, gunakan perintah berikut untuk menjalankan skrip SQL untuk membuat pengguna non-admin Microsoft Entra:

mysql -h $AZ_DATABASE_NAME.mysql.database.azure.com --user $CURRENT_USERNAME --enable-cleartext-plugin --password=$(az account get-access-token --resource-type oss-rdbms --output tsv --query accessToken) < create_ad_user.sql

Sekarang gunakan perintah berikut untuk menghapus file skrip SQL sementara:

rm create_ad_user.sql

Membuat proyek Java baru

Menggunakan IDE favorit Anda, buat proyek Java baru, dan tambahkan file pom.xml di direktori akarnya:

<?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>1.8</java.version>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.30</version>
        </dependency>
        <dependency>
            <groupId>com.azure</groupId>
            <artifactId>azure-identity-extensions</artifactId>
            <version>1.0.0</version>
        </dependency>
    </dependencies>
</project>

File ini adalah file Apache Maven yang mengonfigurasi proyek Anda untuk digunakan:

  • Java 8
  • Driver MySQL terbaru untuk Java

Menyiapkan file konfigurasi untuk menghubungkan ke Azure Database for MySQL

Jalankan skrip berikut di direktori akar proyek untuk membuat file src/main/resources/database.properties dan tambahkan detail konfigurasi:

mkdir -p src/main/resources && touch src/main/resources/database.properties

cat << EOF > src/main/resources/database.properties
url=jdbc:mysql://${AZ_DATABASE_NAME}.mysql.database.azure.com:3306/demo?sslMode=REQUIRED&serverTimezone=UTC&defaultAuthenticationPlugin=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin&authenticationPlugins=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin
user=${AZ_MYSQL_AD_NON_ADMIN_USERNAME}
EOF

Catatan

Jika Anda menggunakan kelas Mysql Koneksi ionPoolDataSource sebagai sumber data di aplikasi Anda, hapus "defaultAuthenticationPlugin=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin" di url.

mkdir -p src/main/resources && touch src/main/resources/database.properties

cat << EOF > src/main/resources/database.properties
url=jdbc:mysql://${AZ_DATABASE_NAME}.mysql.database.azure.com:3306/demo?sslMode=REQUIRED&serverTimezone=UTC&authenticationPlugins=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin
user=${AZ_MYSQL_AD_NON_ADMIN_USERNAME}
EOF

Catatan

Properti url konfigurasi telah ?serverTimezone=UTC ditambahkan untuk memberi tahu driver JDBC untuk menggunakan format tanggal UTC (atau Waktu Universal Terkoordinasi) saat menyambungkan ke database. Jika tidak, server Java Anda tidak akan menggunakan format tanggal yang sama dengan database, yang akan mengakibatkan kesalahan.

Membuat file SQL untuk menghasilkan skema database

Anda akan menggunakan file src/main/resources/schema.sql untuk membuat skema database. Buat file tersebut dengan konten berikut:

DROP TABLE IF EXISTS todo;
CREATE TABLE todo (id SERIAL PRIMARY KEY, description VARCHAR(255), details VARCHAR(4096), done BOOLEAN);

Kodekan aplikasi

Sambungkan ke database

Selanjutnya, tambahkan kode Java yang akan menggunakan JDBC untuk menyimpan dan mengambil data server dari MySQL Anda.

Buat file src/main/java/DemoApplication.java dan tambahkan konten berikut:

package com.example.demo;

import com.mysql.cj.jdbc.AbandonedConnectionCleanupThread;

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("database.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();
        AbandonedConnectionCleanupThread.uncheckedShutdown();
    }
}

Memiliki masalah? Beri tahu kami.

Kode Java ini akan menggunakan database.properties dan file schema.sql yang Anda buat sebelumnya, untuk menyambungkan ke instans server fleksibel Azure Database for MySQL dan membuat skema yang akan menyimpan data Anda.

Dalam file ini, Anda dapat melihat bahwa kami mengomentari metode untuk menyisipkan, membaca, memperbarui, dan menghapus data: Anda akan mengodekan metode tersebut di sisa artikel ini, dan Anda akan dapat membatalkan komentar satu demi satu.

Catatan

Kredensial database disimpan di properti pengguna dan kata sandi file database.properties. Informasi masuk tersebut digunakan saat mengeksekusi DriverManager.getConnection(properties.getProperty("url"), properties);, karena file properti diberikan sebagai argumen.

Catatan

Baris AbandonedConnectionCleanupThread.uncheckedShutdown(); di bagian akhir adalah perintah khusus driver MySQL untuk menghancurkan utas internal saat mematikan aplikasi. Ini dapat diabaikan dengan aman.

Anda sekarang dapat menjalankan kelas utama ini dengan alat favorit Anda:

  • Menggunakan IDE Anda, Anda akan dapat mengklik kanan pada kelas DemoApplication dan menjalankannya.
  • Menggunakan Maven, Anda dapat menjalankan aplikasi dengan mengeksekusi: mvn exec:java -Dexec.mainClass="com.example.demo.DemoApplication".

Aplikasi harus terhubung ke instans server fleksibel Azure Database for MySQL, membuat skema database, lalu menutup koneksi, seperti yang akan Anda lihat di log konsol:

[INFO   ] Loading application properties
[INFO   ] Connecting to the database
[INFO   ] Database connection test: demo
[INFO   ] Create database schema
[INFO   ] Closing database connection

Membuat kelas domain

Tambahkan kelas Java Todo baru, di samping kelas DemoApplication, dan tambahkan kode berikut:

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 +
                '}';
    }
}

Kelas ini adalah model domain yang dipetakan pada tabel todo yang Anda buat saat menjalankan skrip schema.sql.

Memasukkan data ke Azure Database for MySQL

Dalam file src/main/java/DemoApplication.java, setelah metode utama, tambahkan metode berikut untuk menyisipkan data ke dalam database:

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();
}

Anda sekarang dapat membatalkan penguraian dua baris berikut di dalam metode main:

Todo todo = new Todo(1L, "configuration", "congratulations, you have set up JDBC correctly!", true);
insertData(todo, connection);

Menjalankan kelas utama sekarang harus menghasilkan keluaran berikut:

[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

Membaca data dari Azure Database for MySQL

Selanjutnya, baca data yang sebelumnya disisipkan untuk memvalidasi bahwa kode Anda berfungsi dengan benar.

Dalam file src/main/java/DemoApplication.java, setelah metode insertData, tambahkan metode berikut untuk membaca data dari database:

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;
}

Anda sekarang dapat menghapus komentar pada dua baris berikut di dalam metode main:

todo = readData(connection);

Menjalankan kelas utama sekarang harus menghasilkan keluaran berikut:

[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

Memiliki masalah? Beri tahu kami.

Memperbarui data di server fleksibel Azure Database for MySQL

Selanjutnya, perbarui data yang sebelumnya Anda sisipkan.

Masih dalam file src/main/java/DemoApplication.java, setelah metode readData, tambahkan metode berikut untuk memperbarui data di dalam database:

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);
}

Anda sekarang dapat membatalkan penguraian dua baris berikut di dalam metode main:

todo.setDetails("congratulations, you have updated data!");
updateData(todo, connection);

Menjalankan kelas utama sekarang harus menghasilkan keluaran berikut:

[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

Menghapus data di server fleksibel Azure Database for MySQL

Terakhir, hapus data yang sebelumnya Anda sisipkan.

Masih dalam file src/main/java/DemoApplication.java, setelah metode updateData, tambahkan metode berikut untuk memperbarui data di dalam database:

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);
}

Anda sekarang dapat menghapus komentar pada dua baris berikut di dalam metode main:

deleteData(todo, connection);

Menjalankan kelas utama sekarang harus menghasilkan keluaran berikut:

[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

Membersihkan sumber daya

Selamat! Anda telah membuat aplikasi Java yang menggunakan JDBC untuk menyimpan dan mengambil data dari server fleksibel Azure Database for MySQL.

Untuk membersihkan semua sumber daya yang digunakan selama mulai cepat ini, hapus grup sumber daya menggunakan perintah berikut:

az group delete \
    --name $AZ_RESOURCE_GROUP \
    --yes

Langkah berikutnya