JDBC 자습서 2부: SQL 쿼리 실행

이 강좌의 두 번째 부분에서 당신은 JDBC를 사용하여 SQL 데이터베이스에 대한 실행SELECT, INSERT, UPDATEDELETE 문장을 어떻게 사용하는지 배울 것입니다.이러한 작업을 CRUD 작업(생성, 읽기, 업데이트, 삭제)이라고 하는데 이것은 응용 프로그램의 대부분 기능을 구성한다.
주의: 우리는 본 강좌의 끝 부분을 계속할 것입니다. 이것은 본고가 당신이 이미 Connection 대상을 준비했다고 가정한 것을 의미합니다.자세한 내용은 이 자습서의 첫 번째 부분을 참조하십시오.소스 코드는 GitHub에서 얻을 수 있습니다.
다음은 이 개념의 실제 응용을 보지 못하도록 본 논문의 영상 버전입니다.

때 조작 추가


이 강좌에서 우리는 간단한 자바 응용 프로그램을 구축할 것이다. 이 응용 프로그램은 JDBC를 사용하여 MariaDB database와 상호작용을 할 것이다.데이터베이스에는 programming_languages 이라는 표가 포함되어 있는데, 우리는 그 중에서 프로그래밍 언어와 등급을 추적하고 싶다.
최종 사용자의 입장에서 볼 때, 우리는 유용한 기능을 가진 응용 프로그램을 실현할 수 없다.우리는 모든 CRUD 동작을 호출하고 자바 표준 main 방법에서 호출하기만 하면 된다.데이터베이스에 대해 CRUD 작업을 수행하는 방법은 아직 구현되지 않았으나 다음을 수행합니다.
public static void main(String[] args) throws SQLException {
    try {
        initDatabaseConnection();
        deleteData("%");
        readData();
        createData("Java", 10);
        createData("JavaScript", 9);
        createData("C++", 8);
        readData();
        updateData("C++", 7);
        readData();
        deleteData("C++");
        readData();
    } finally {
        closeDatabaseConnection();
    }
}
이 방법은 프로그래밍 언어가 유행하는 허구적인 이야기를 다루었다.우리는 먼저 데이터베이스에서 모든 프로그래밍 언어를 삭제하여 다시 시작하도록 한다.
이로써 우리는 프로그램을 마음대로 실행하고 같은 출력을 얻을 수 있으며 오류가 발생하지 않을 것이다.우리는 매번 조작 후에 데이터를 읽는다. 즉, 화면에 프로그래밍 언어와 등급을 표시해서 조작이 유효한지 확인한다.우리는 프로그래밍 언어를 만들고 그 중 한 언어의 등급을 업데이트한 다음 삭제합니다.
이제 이 방법들을 실현합시다.

JDBC를 사용하여 데이터 삽입


이제 때가 낀 작업을 시작합니다.
private static void createData(String name, int rating) throws SQLException {
    try (PreparedStatement statement = connection.prepareStatement("""
                INSERT INTO programming_language(name, rating)
                VALUES (?, ?)
            """)) {
        statement.setString(1, name);
        statement.setInt(2, rating);
        int rowsInserted = statement.executeUpdate();
        System.out.println("Rows inserted: " + rowsInserted);
    }
}
createData(String, int) 방법은 프로그래밍 언어의 이름과 등급을 수신한다.SQL을 실행하려면 Statement 대상을 사용하여 connection 대상을 구축해야 합니다.PreparedStatement 확장Statement에 유용한 방법을 추가합니다.
대부분의 경우 PreparedStatament 를 사용할 것입니다. 매개 변수를 설정할 수 있기 때문입니다.우리는 실제적으로 파라미터를 사용해야 한다. 삽입할 프로그래밍 언어의 이름과 등급이다.우리는 setString(int, String)setInt(int, int) 방법을 사용하여 이 매개 변수를 설정한다.
실행할 SQL 문이 있는 여러 줄 문자열에 주의하십시오.VALUES 조항에는 두 개의 물음표가 포함되어 있다.첫 번째 물음표는 색인 1을, 두 번째 물음표는 색인 2를 지정합니다.이 인덱스를 사용하면 우리는 상응하는 매개 변수를 설정할 수 있다.
AStatement이기 때문에 APreparedStatement는 정확하게 방출되거나 닫혀야 하는 자원이다.이것은 이러한 유형의 대상에서 호출close() 방법을 통해 실현된 것이다.Statement은try with resources 블록을 사용할 수 있는 자바Closable입니다.우리는 직접 close() 방법을 호출하지 않고 자바에서 호출하도록 합니다.이것은 close() 블록에서 finally 을 호출하여 자원이 이상하거나 오류가 발생하더라도 시종일관 닫는 것과 같다.우리는 매번 Statement 대상을 만들 때마다 같은 방법을 사용할 것이다.executeUpdate() 방법을 어떻게 사용하는지 주의하십시오. 이 방법은 업데이트된 줄의 수를 되돌려줍니다.

JDBC를 사용하여 데이터 검색


Read CRUD 작업을 수행하려면 다음과 같은 유형의 객체를 가져와야 합니다.
private static void readData() throws SQLException {
    try (PreparedStatement statement = connection.prepareStatement("""
                SELECT name, rating
                FROM programming_language
                ORDER BY rating DESC
            """)) {
        try (ResultSet resultSet = statement.executeQuery()) {
            boolean empty = true;
            while (resultSet.next()) {
                empty = false;
                String name = resultSet.getString("name");
                int rating = resultSet.getInt("rating");
                System.out.println("\t> " + name + ": " + rating);
            }
            if (empty) {
                System.out.println("\t (no data)");
            }
        }
    }
}
이번에 우리는 ResultSet 대상에서 executeQuery() 방법을 호출했다.이 방법은 자원을 처리할 때 다시 닫아야 한다. (이것은try with resources 블록에서 그것을 실례화하는 이유이다.)statement 대상은 커서를 저장합니다. 이 커서가 첫 번째 줄에 있기 전에 우리는 ResultSet 방법으로 이 줄을 이동할 수 있습니다. 더 많은 줄이 교체할 수 없을 때 이 방법은 되돌아갑니다resultSet.각 열의 값을 읽으려면 next() 방법을 사용하여 열의 이름(SQLfalse 문구에서 반환)을 지정하거나 열 색인에 대응하는 정수(1부터 시작)를 사용합니다.우리는 이 get 방법으로 되돌아오는 값을 사용하여 자바 프로그램의 표준 출력에서 한 줄을 출력할 수 있다.Java 유형에 따라 방법이 다릅니다.JDBC 드라이버에 따라 어느 정도 SQL 유형을 자바 형식으로 변환할 수 있습니다.예를 들어, 다음 표에서는 MariaDB 유형을 잠재적인 Java 유형과 일치시킵니다.
마리아 천 타입
Java 유형SELECT , get , CHAR , VARCHAR BLOB , TEXT , java.lang.String , java.io.InputStream , java.io.Reader java.sql.Blob , java.sql.Clob , FLOAT , REAL , DOUBLE PRECISION , NUMERIC , DECIMAL , TINYINT , SMALLINT , MEDIUMINT INTEGER , BIGINT , java.lang.String , java.lang.Short , java.lang.Integer , java.lang.Long java.lang.Double , java.math.BigDecimal , DATE , TIME DATETIME , TIMESTAMP , java.lang.String

JDBC를 사용하여 데이터 수정


CRUD 업데이트 작업은 생성 작업과 유사합니다.
private static void updateData(String name, int newRating) throws SQLException {
    try (PreparedStatement statement = connection.prepareStatement("""
                UPDATE programming_language
                SET rating = ?
                WHERE name = ?
            """)) {
        statement.setInt(1, newRating);
        statement.setString(2, name);
        int rowsUpdated = statement.executeUpdate();
        System.out.println("Rows updated: " + rowsUpdated);
    }
}
Create 작업에 비해 새로운 내용은 없습니다. 단지 java.sql.DateSQL 문장을 사용했을 뿐입니다. java.sql.Timestamp

JDBC를 사용하여 데이터 삭제


마지막으로 JDBC의 관점에서 볼 때 CRUD 삭제 작업은 생성 및 업데이트 작업과 유사합니다.
private static void deleteData(String nameExpression) throws SQLException {
    try (PreparedStatement statement = connection.prepareStatement("""
                DELETE FROM programming_language
                WHERE name LIKE ?
            """)) {
        statement.setString(1, nameExpression);
        int rowsDeleted = statement.executeUpdate();
        System.out.println("Rows deleted: " + rowsDeleted);
    }
}
오류가 발생하면 JDBC에서 하나UPDATE를 내보냅니다.이 예시 프로그램에서, 우리는 방법에 INSERT 자구를 추가하기만 하면 되지만, 더 심각한 프로그램에서, 이 이상을 포착할 수 있습니다. 예를 들어 오류 메시지를 표시할 수 있습니다.

SQL 주입


SQL 주입은 프로그램의 입력으로 악의적인 SQL 코드를 삽입해 코드를 실행하는 공격이다.우리는 SQLExceptionthrows 방법을 사용하여 파라미터를 SQL 문장에 전달하기 때문에 위의 예시에서 SQL 주입을 허용하지 않는다.SQL 문의 매개변수 값을 설정하는 문자열을 영원히 연결하지 마십시오.다음은 하지 말아야 할 예이다.
// DON’T DO THIS:
private static void updateWithSqlInjection(String name, int newRating) throws SQLException {
    System.out.println("Performing SQL injection...");
    try (PreparedStatement statement = connection.prepareStatement(
        "UPDATE programming_language SET rating = " + newRating + " WHERE name = '" + name + "'"
    )) {
        int rowsUpdated = statement.executeUpdate();
        System.out.println("Rows updated: " + rowsUpdated);
    }
}
PreparedStatement 변수의 값이 사용자가 입력한 경우 악의적인 사용자는 유사set 문자열을 가져올 수 있습니다. 그러면 다음과 같은 SQL 문이 생성됩니다.
UPDATE programming_language SET rating = 5 WHERE name = ''; TRUNCATE programming_language; SELECT 'boom!;'
모든 프로그래밍 언어가 사라졌다.이것은 좋은 일이 아니다!한 마디로 하면 항상 name 방법으로 파라미터를 설정하십시오.SQL 주입 공격을 방지하기 위해 적절한 문자 이스케이프를 수행합니다.
참고: 이 취약점을 시도하려면 JDBC URL 연결 문자열의 구성 매개 변수를 사용하여 다중 질의를 활성화해야 합니다.
jdbc:mariadb://localhost:3306/jdbc_demo?allowMultiQueries=true
다음 글은 응용 프로그램의 성능을 향상시키기 위해 연결 탱크를 사용하는 방법을 배울 것이다.

좋은 웹페이지 즐겨찾기