[Java] 34. 데이터 베이스에 접속하는 방법


Study/Java  2020. 6. 12. 14:53

안녕하세요. 명월입니다.


이 글은 Java에서 데이터 베이스에 접속하는 방법에 대한 글입니다.


우리가 프로젝트를 설계하고 프로그램을 작성하면서 데이터를 저장하고 검색, 탐색하는 시스템으로 아마 데이터 베이스를 가장 많이 사용할 꺼라 생각됩니다.

데이터 베이스 종류만 해도 엄청나게 많은데 대표적으로 관계형 데이터 베이스 관리 시스템(rdbms)인 오라클(oracle), Sql server(MS-SQL), Mysql(MariaDB), Postgres ....등이 있습니다.

여기서 가장 많이 사용하는 건 역시 오라클, Sql server이고 무료로는 MariaDB를 많이 사용합니다.


그럼 Java에서 데이터 베이스를 접속해서 사용하는 방법을 소개하겠습니다.

저는 무료 DB인 MariaDB를 사용하여 예제를 작성합니다만, Oracle이나 Sql server도 참조하는 라이브러리만 다를 뿐 사용 방법은 같습니다.

먼저 maven을 이용해 라이브러리를 업데이트합니다.

링크 - https://mvnrepository.com/artifact/mysql/mysql-connector-java/8.0.20

<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>8.0.20</version>
</dependency>

참고로 Oracle은 다음과 같습니다.

링크 - https://mvnrepository.com/artifact/com.oracle.jdbc

Mssql은 다음과 같습니다.

링크 - https://mvnrepository.com/artifact/com.microsoft.sqlserver/mssql-jdbc


이전에 제가 mariaDB를 설치하는 방법을 설명한 글이 있습니다.

링크 - [CentOS] mariaDB 설치

링크 - [Window] MariaDB를 설치하는 방법


이제 자바 소스에서 데이터 베이스에 접속하겠습니다.

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
public class Example {
  // 실행 함수
  public static void main(String[] args) {
    try {
      // 클래스 할당
      // MariaDB, Mysql의 경우
      Class.forName("com.mysql.jdbc.Driver");
      // 오라클의 경우
      //Class.forName("oracle.jdbc.driver.OracleDriver");
      // Sql server의 경우
      //Class.forName("com.microsoft.sqlserver.jdbc.SqlServerDriver");
      // 접속 정보 - useLegacyDatetimeCode와 serverTimezone를 설정해야 한다.
      String constr = "jdbc:mysql://localhost:3306/test?useLegacyDatetimeCode=false&serverTimezone=UTC";
      // 접속 정보와, id, password 넣기, 사용 후 close
      try (Connection con = DriverManager.getConnection(constr, "nowonbun", "a12345")) {
        // Statement 생성, 사용후 close
        try (Statement stmt = con.createStatement()) {
          // 테이블 삭제 쿼리 실행
          stmt.execute("drop table test");
        } catch (Throwable e) {
          e.printStackTrace();
        }
        // Statement 생성, 사용후 close
        try (Statement stmt = con.createStatement()) {
          // 테이블 생성 쿼리 실행
          stmt.execute("create table test(idx bigint auto_increment, contents varchar(200), primary key(idx))");
        } catch (Throwable e) {
          e.printStackTrace();
        }
        // 데이터 리스트
        List<String> data = new ArrayList<>();
        data.add("hello world");
        data.add("good");
        data.add("hi!");
        // PreparedStatement 생성, 사용후 close
        try (PreparedStatement pstmt = con.prepareStatement("insert into test(contents) values(?)")) {
          // 데이터 insert
          for (String d : data) {
            // 파라미터 입력
            pstmt.setString(1, d);
            // 쿼리 실행
            pstmt.executeUpdate();
          }
        }
        // Statement 생성, 사용후 close
        try (Statement stmt = con.createStatement()) {
          // 쿼리 검색 결과 취득
          ResultSet result = stmt.executeQuery("select * from test");
          // iterator 패턴
          while (result.next()) {
            // 첫번째 컬럼 취득
            int idx = result.getInt(1);
            // 두번째 컬럼 취득
            String contents = result.getString(2);
            // 콘솔 출력
            System.out.println(" idx - " + idx + " contents - " + contents);
          }
        }
      }
    } catch (Throwable e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
}

먼저 처음에 데이터 베이스의 종류에 Class.forName에 할당하는 클래스가 다릅니다. 저의 경우는 mariaDB를 사용했으므로 mysql 클래스를 할당했습니다.

그리고 connection은 소켓 종류의 리소스이기 때문에 사용 후에는 반드시 리소스를 반환해야 한다.

쿼리를 실행하는 인터페이스에는 일반 Statement와 PreparedStatement가 있습니다.

일반 Statement의 경우는 재사용이 필요없는 일회성 쿼리를 실행할 때 사용합니다. PreparedStatement의 경우는 쿼리를 재사용할 때 사용하는 쿼리입니다.

쿼리에 ?표로 바인딩 설정을 하고 setString이나 setInt로 파라미터를 바이딩합니다. 프로그램에서 일반적으로 인덱스 시작인 0부터가 아닌 1부터 시작합니다. (저도 이게 많이 헤갈립니다.)

즉, ?가 두개 혹은 세개가 있으면 setString(1, data), setString(2, data), setString(3, data)이런 식으로 바인딩됩니다.


그리고 검색을 해서 결과는 ResultSet으로 받습니다. 내부는 iterator 패턴으로 구성되어 있으며 next() 함수를 통해 포인터 이동을 합니다.

여기서도 컬럼을 취득할 때 인덱스가 1부터 해서 취득합니다.

참고로 위 소스는 테이블 생성부터 데이터 삽입, 검색까지 한 프로그램입니다.


최근에는 사실 데이터 베이스를 직접 connection을 취득해서 접속하는 경우는 거의 없습니다.

ORM(Object-Relational Reference Mapping) 프래임 워크가 많고, 특히 JPA의 ORM은 아예 Java에서 표준으로 자리를 잡았기 때문에 실무 프로젝트에서는 위처럼 데이터 베이스를 접속하는 경우는 없습니다.

그러나 간단한 프로그램이나 테스트를 위한 프로그램이라면 필요할 수도 있습니다. ORM에 관해서는 다른 글로 자세히 설명하겠습니다.

여기까지 Java에서 데이터 베이스에 접속하는 방법에 대한 글이었습니다.


궁금한 점이나 잘못된 점이 있으면 댓글 부탁드립니다.