Quickstart: Connettiti a SQL Server con Java e Maven

Usa il driver Microsoft Java Database Connectivity (JDBC) per SQL Server per collegare un'applicazione Java a database SQL Server, database SQL di Azure o SQL in Fabric. Questo quickstart utilizza Maven per scaricare le dipendenze, legge le impostazioni di connessione dalle variabili di ambiente e verifica il risultato di una query parametrizzata. Non servono AdventureWorks o tabelle di esempio.

Per database SQL di Azure o database SQL in Fabric, usa l'autenticazione Microsoft Entra ID senza memorizzare una password nella tua applicazione. Durante lo sviluppo locale, accedi tramite un browser. Per un'applicazione ospitata in Azure, usa un'identità gestita.

Prerequisiti

Scegliere il database

Usa un database esistente o creane uno utilizzando le seguenti guide. Un database vuoto è sufficiente.

Database Installazione e accesso
Database SQL nell'ambiente Fabric Crea un database SQL e poi segui i requisiti di autenticazione e accesso Fabric. Copia i nomi del server e del database da Impostazioni>. Usa la connessione SQL al database, non il suo endpoint di analisi SQL.
Database SQL di Microsoft Azure Creare un database singolo. Chiedi al tuo amministratore di configurare un amministratore Microsoft Entra e di creare un utente database per la tua identità. Il solo accesso alla sottoscrizione di Azure non concede l'accesso al database.
contenitore di SQL Server Crea un container usando Docker, sqlcmd o l'estensione MSSQL per Visual Studio Code. Usa il nome DNS dell'host container, la porta TCP pubblicata e un login SQL con permesso per connetterti al tuo database.
SQL Server esistente Usa il nome DNS dell'istanza, la porta TCP e un database esistente. Chiedi al tuo amministratore un login SQL con permesso di connettersi.

Le immagini container Linux di SQL Server richiedono un host x86-64 supportato. Su un computer di sviluppo ARM64, esegui questa applicazione Java su un database ospitato o su un container su un host remoto supportato invece di affidarti all'emulazione del container.

Un nuovo container potrebbe usare un certificato di cui il tuo JDK non si fida. Prima di eseguire questo esempio, configura un certificato server e, per un emittente privato, configura il trust store Java. Mantieni attivata anche la validazione dei certificati per le connessioni dei container.

Crea il progetto Maven

Creare una directory denominata jdbc-quickstart. In quella directory, crea pom.xml con i seguenti contenuti. Maven gestisce il percorso delle classi; non è necessario scaricare manualmente file Java archive (JAR).

<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>jdbc-quickstart</artifactId>
    <version>1.0.0</version>

    <properties>
        <maven.compiler.release>21</maven.compiler.release>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.microsoft.sqlserver</groupId>
            <artifactId>mssql-jdbc</artifactId>
            <version>13.6.0.jre11</version>
        </dependency>
        <dependency>
            <groupId>com.azure</groupId>
            <artifactId>azure-core-http-netty</artifactId>
            <version>1.16.6</version>
        </dependency>
        <dependency>
            <groupId>com.azure</groupId>
            <artifactId>azure-identity</artifactId>
            <version>1.18.4</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.14.0</version>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>3.5.0</version>
                <configuration>
                    <executable>${java.home}/bin/java</executable>
                    <arguments>
                        <argument>-classpath</argument>
                        <classpath />
                        <argument>Quickstart</argument>
                    </arguments>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

L'artefatto jre11 del driver funziona con JDK 21. La dipendenza esplicita azure-identity fornisce le librerie di autenticazione necessarie per le modalità Microsoft Entra in questo avvio rapido; queste librerie sono dipendenze opzionali dal driver e non vengono aggiunte automaticamente alla tua applicazione.

Queste versioni corrispondono al modello di oggetti del progetto Maven (POM) pubblicato in JDBC 13.6.0. La dipendenza esplicita azure-core-http-netty mantiene la versione di trasporto selezionata da quel rilascio del driver.

Per aggiornamenti sui driver, controlla la pagina di download, le versioni pubblicate di Maven e la matrice di supporto Java. Quando aggiorni il driver, abbina le dipendenze di autenticazione al POM pubblicato dal driver. Vedi Dipendenze delle caratteristiche. Usa versioni di rilascio esplicite invece di gamme di versioni Maven o LATEST.

Configura la connessione

Imposta le variabili di ambiente nello stesso terminale dove usi Maven. Sostituisci <server> e <database> con il nome del tuo endpoint e database. Imposta SQL_SERVER_NAME solo sul nome host, senza un URL JDBC né una porta.

Se il valore del server copiato è tcp:<server>,1433, usa solo <server> per SQL_SERVER_NAME e imposta SQL_PORT a 1433. Non includere il prefisso tcp: o il suffisso ,1433 nel nome host.

Azure SQL o Fabric con autenticazione Microsoft Entra

Per lo sviluppo locale, usa ActiveDirectoryInteractive. Il driver apre un browser per l'accesso e supporta l'autenticazione multifattoriale. Accedi con l'identità che ha accesso al tuo database. Non impostare SQL_USER o SQL_PASSWORD per questa modalità.

Per database SQL di Azure, sostituisci <server> con il nome host completo, come contoso.database.windows.net. Per Fabric, copia il nome host dalle impostazioni di connessione del database SQL; non costruirlo dal nome del database né aggiungere un suffisso Azure SQL. Fabric richiede l'autenticazione Microsoft Entra; non usare l'esempio di autenticazione SQL per Fabric.

$env:SQL_SERVER_NAME = "<server>"
$env:SQL_DATABASE_NAME = "<database>"
$env:SQL_PORT = "1433"
$env:SQL_AUTHENTICATION = "ActiveDirectoryInteractive"

Per un'applicazione headless ospitata su una risorsa Azure con un'identità gestita assegnata dal sistema:

  1. Abilita l'identità gestita della risorsa.
  2. Chiedi al tuo amministratore di concedere a quell'identità l'accesso al database. In Azure SQL, crea un utente del database per l'identità. Per Fabric, segui i requisiti di autenticazione e accesso per Fabric, comprese le impostazioni del tenant applicabili alle entità servizio.
  3. Imposta SQL_AUTHENTICATION su ActiveDirectoryManagedIdentity nella configurazione dell'applicazione dell'host. Tieni le impostazioni del server, del database e delle porte. La stessa applicazione Java funziona senza browser né password.

L'identità gestita richiede un host Azure supportato; non sostituisce il login interattivo sulla tua workstation. Per le identità assegnate dall'utente e altre modalità di autenticazione, vedi Collega usando l'autenticazione Microsoft Entra.

SQL Server con autenticazione SQL

Per un container SQL Server o un'istanza esistente configurata per l'autenticazione SQL, imposta SQL_AUTHENTICATION e SqlPassword fornisce un login SQL con accesso al tuo database. Non usare un account amministratore server per questo esempio. Il prompt della password di PowerShell richiede PowerShell 7.1 o versioni successive.

$env:SQL_SERVER_NAME = "<server>"
$env:SQL_DATABASE_NAME = "<database>"
$env:SQL_PORT = "1433"
$env:SQL_AUTHENTICATION = "SqlPassword"
$env:SQL_USER = "<user_id>"
$env:SQL_PASSWORD = Read-Host "SQL password" -MaskInput

Usa la porta TCP della tua istanza se non è 1433. Le variabili ambientali tengono le credenziali fuori dal codice sorgente, ma non sono uno store segreto. Non registrarli né sottoporli al controllo del fonte. Non abilitare il debug logging di Maven (-X) mentre le variabili password sono impostate: il plugin di esecuzione registra i valori dell'ambiente del processo figlio. Per le applicazioni distribuite, utilizzate le impostazioni di gestione segreta e connessione sicura della vostra piattaforma.

Fidati di un'autorità certificatrice privata

Salta questa sezione se il tuo JDK si fida già dell'emittente del certificato del server. Altrimenti, ottieni il certificato pubblico e l'impronta digitale SHA-256 dell'autorità certificatrice (CA) emittente dal tuo amministratore tramite un canale affidabile. Non fidarti di un certificato solo perché il server l'ha presentato durante una connessione fallita.

Imposta SQL_SERVER_NAME su un nome DNS coperto dal certificato del server e risolvibile dal tuo computer. L'applicazione non sovrascrive hostNameInCertificate, quindi il driver valida il nome del server configurato. Aggiungere una CA affidabile non risolve una discrepanza tra nome certificato.

Usa il/la keytool dalla stessa installazione di JDK 21 che Maven utilizza. Sostituisci <ca-certificate-file> con il percorso del certificato CA verificato, <jdk-home> con la directory di quel JDK e <trust-store-file> con un nuovo percorso assoluto al di fuori del tuo progetto. Tieni il trust store in una directory che altri utenti non privilegiati non possono modificare. Fermati se qualche comando fallisce.

  1. Ispeziona il certificato CA e confronta la sua impronta digitale SHA-256 con il valore fornito dal tuo amministratore.

    keytool -printcert -file "<ca-certificate-file>"
    
  2. Crea un deposito fiduciario dedicato per PKCS12 copiando le radici pubbliche del JDK. Non modificare il file del cacerts JDK installato né sovrascrivere un trust store esistente.

    keytool -importkeystore -srckeystore "<jdk-home>/lib/security/cacerts" -destkeystore "<trust-store-file>" -deststoretype PKCS12
    

    Inserisci una nuova password del negozio di destinazione nei prompt. Per la password source-store, usa il valore fornito dal tuo provider JDK o dall'amministratore. Copiare le radici pubbliche mantiene la fiducia nei server che utilizzano CA pubbliche.

  3. Aggiungi la CA verificata allo store dedicato.

    keytool -importcert -alias sql-server-ca -file "<ca-certificate-file>" -keystore "<trust-store-file>" -storetype PKCS12
    

    Inserisci la password del negozio di destinazione. Prima di confermare l'importazione, verifica che l'impronta digitale visualizzata corrisponda al valore verificato.

Imposta queste due variabili opzionali nel terminale dove usi Maven. Usa la password del negozio di destinazione che hai appena creato. Il prompt della password di PowerShell richiede PowerShell 7.1 o versioni successive.

$env:SQL_TRUST_STORE = "<trust-store-file>"
$env:SQL_TRUST_STORE_PASSWORD = Read-Host "Trust-store password" -MaskInput

L'applicazione Java legge queste variabili e configura esplicitamente il suo trust store JDBC. Ometti entrambe le variabili per utilizzare la configurazione di trust predefinita della Java Virtual Machine (JVM). Mantieni encrypt=true e trustServerCertificate=false.

Maven avvia un processo Java separato per questa applicazione. L'impostazione di una proprietà Java Secure Socket Extension (JSSE), come javax.net.ssl.trustStore con mvn -D... o MAVEN_OPTS, non configura quel processo figlio. JAVA_TOOL_OPTIONS e JDK_JAVA_OPTIONS le ricevono, ma la JVM riporta tali opzioni all'avvio. Non inserire password in nessuna delle due variabili. Usa invece le variabili applicative in questa sezione. Per maggiori informazioni sulla configurazione del trust, vedi Configura il client per la crittografia.

Aggiungi l'applicazione Java

Dalla directory jdbc-quickstart, crea la directory dei sorgenti Java.

New-Item -ItemType Directory -Path src\main\java -Force | Out-Null

Salva la seguente applicazione completa come Quickstart.java in src/main/java.

La query SELECT CAST(? AS int) + 1 AS answer Transact-SQL (T-SQL) accetta un parametro. setInt lega il valore 41 separatamente dal testo SQL. Il risultato atteso è esattamente una riga contenente 42.

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.microsoft.sqlserver.jdbc.SQLServerDataSource;

public class Quickstart {
    public static void main(String[] args) throws SQLException {
        SQLServerDataSource dataSource = new SQLServerDataSource();
        dataSource.setServerName(required("SQL_SERVER_NAME"));
        dataSource.setDatabaseName(required("SQL_DATABASE_NAME"));
        dataSource.setPortNumber(Integer.parseInt(required("SQL_PORT")));
        dataSource.setEncrypt("true");
        dataSource.setTrustServerCertificate(false);
        dataSource.setLoginTimeout(30);

        String authentication = required("SQL_AUTHENTICATION");
        switch (authentication) {
            case "ActiveDirectoryInteractive":
            case "ActiveDirectoryManagedIdentity":
                break;
            case "SqlPassword":
                dataSource.setUser(required("SQL_USER"));
                dataSource.setPassword(required("SQL_PASSWORD"));
                break;
            default:
                throw new IllegalArgumentException(
                        "SQL_AUTHENTICATION must be ActiveDirectoryInteractive, "
                        + "ActiveDirectoryManagedIdentity, or SqlPassword.");
        }
        dataSource.setAuthentication(authentication);

        if (System.getenv("SQL_TRUST_STORE") != null
                || System.getenv("SQL_TRUST_STORE_PASSWORD") != null) {
            dataSource.setTrustStore(required("SQL_TRUST_STORE"));
            dataSource.setTrustStorePassword(required("SQL_TRUST_STORE_PASSWORD"));
            dataSource.setTrustStoreType("PKCS12");
        }

        String sql = "SELECT CAST(? AS int) + 1 AS answer";
        try (Connection connection = dataSource.getConnection();
             PreparedStatement statement = connection.prepareStatement(sql)) {
            statement.setInt(1, 41);
            statement.setQueryTimeout(30);
            try (ResultSet results = statement.executeQuery()) {
                if (!results.next() || results.getInt("answer") != 42 || results.next()) {
                    throw new SQLException("Expected exactly one row with answer = 42.");
                }
            }
        }
        System.out.println("Verified result: 42");
    }

    private static String required(String name) {
        String value = System.getenv(name);
        if (value == null || value.isBlank()) {
            throw new IllegalArgumentException("Set environment variable " + name + ".");
        }
        return value;
    }
}

L'applicazione imposta i timeout di accesso e di interrogazione a 30 secondi. L'autenticazione interattiva prevede un limite di attesa separato per il token descritto in Troubleshoot the first run. L'applicazione chiude il set di risultati, l'istruzione preparata e la connessione utilizzando try-with-resources, incluso quando si verifica un'eccezione. Gli errori si propagano e fanno uscire il processo con uno stato diverso da zero.

Esegui e verifica

Dalla directory jdbc-quickstart, esegui:

mvn -q compile exec:exec

Maven scarica le dipendenze, compila l'applicazione e avvia un processo Java separato. Per ActiveDirectoryInteractive, completa l'accesso al browser e torna al tuo terminale.

Dopo che la query viene eseguita correttamente e l'applicazione ha chiuso le risorse, stampa:

Verified result: 42

Un messaggio del browser che indica che l'autenticazione è completa non dimostra che la connessione al database sia stata riuscita a funzionare. Controlla il risultato dell'applicazione e lo stato di uscita zero: $LASTEXITCODE in PowerShell o $? in Bash. La query non dipende da alcuna tabella esistente né lascia dati da ripulire.

Se hai usato l'autenticazione SQL, rimuovi SQL_PASSWORD dall'ambiente terminale quando hai finito. Esegui Remove-Item Env:\SQL_PASSWORD in PowerShell. In Bash, esegui unset SQL_PASSWORD.

Se hai configurato un trust store privato di CA, rimuovi anche le sue variabili di ambiente. Esegui Remove-Item Env:\SQL_TRUST_STORE, Env:\SQL_TRUST_STORE_PASSWORD in PowerShell. In Bash, esegui unset SQL_TRUST_STORE SQL_TRUST_STORE_PASSWORD. Conserva il trust store solo finché ne hai bisogno.

Risolvere i problemi relativi al primo avvio

Sintomo Action
Set environment variable ... Imposta la variabile nominata nel terminale che esegue Maven. Un ambiente di sviluppo integrato (IDE) potrebbe necessitare di una propria configurazione di esecuzione.
Errore di compilazione Java o di versione della classe Corri mvn -version e controlla che Maven usa JDK 21. Controlla JAVA_HOME se Maven e java -version segnalano runtime diversi.
Libreria di autenticazione mancante Mantieni la dipendenza azure-identity in pom.xml ed esegui l'applicazione tramite Maven in modo da includere anche le dipendenze transitive.
Timeout di accesso o connessione rifiutata Controlla il nome host del server, la porta TCP, la disponibilità del database e l'accesso alla rete.
L'accesso interattivo scade Il conducente attende al massimo 20 secondi per la richiesta interattiva del token. Effettua l'accesso immediato. Se la richiesta va in timeout, esegui di nuovo il comando. Aumentare loginTimeout non estende questo limite di attesa dei token.
Il login Microsoft Entra ha successo, ma l'accesso al database fallisce Conferma di aver effettuato l'accesso al tenant corretto e che la tua identità abbia accesso al database selezionato. Controlla l'utente del database SQL di Azure o le autorizzazioni di Fabric, a seconda dei casi.
Fallimenti nella validazione dei certificati, inclusi PKIX path building failed Segui Trust, un'autorità certificatrice privata per un emittente privato. Connettiti usando un nome DNS coperto dal certificato server. Non bypassare la validazione con trustServerCertificate=true.

Per ulteriori diagnostiche, vedi Risoluzione dei problemi della connettività.