JDBC는 가장 오래된 DB 연동 기술입니다. 모든 RDB(Relational Database, 관계형 데이터베이스)에서 동일한 자바 코드를 사용합니다. JDBC는 Polymorphism(다형성)을 기반으로 동작합니다.
따라서 DB와 무관하게 동일한 자바 코드를 사용할 수 있습니다.
JDBC
Java Database Connectivity
자바에서 데이터베이스에 접속할 수 있도록 하는 자바 API이다.
실습 순서는 다음과 같습니다.
① H2 DB 구동
② SQL 입력
③ VO(Value Object) 작성
④ DAO(Data Access Object) 작성
⑤ Client 작성
\h2\bin
에서 h2w.bat 파일을 실행합니다.
JDBC URL과 사용자명을 지정합니다.
아래 sql 구문을 입력하고 실행합니다.
drop table s_emp if exists;
CREATE TABLE s_emp(
id NUMBER(7) CONSTRAINT s_emp_id_nn NOT NULL, -- 직원 아이디
name VARCHAR2(25) CONSTRAINT s_emp_name_nn NOT NULL, -- 직원 이름
start_date DATE, -- 입사일
title VARCHAR2(25), -- 직급
dept_name VARCHAR2(25), -- 부서 이름
salary NUMBER(11, 2), -- 급여
CONSTRAINT s_emp_id_pk PRIMARY KEY (id)
);
INSERT INTO s_emp VALUES (1, '안은경', '2002-12-03', '영업대표이사', '영업부', 2500);
SELECT * FROM s_emp;
sql 구문이 잘 실행된 것을 확인할 수 있습니다.
사용자가 입력한 값을 VO에 담아 DB 테이블의 ROW로 매핑합니다. 이와 반대로 처리하기도 합니다.
package com.rubypaper.persistence.jdbc;
import lombok.Data;
import java.sql.Timestamp;
@Data
public class EmployeeVO {
private Long id;
private String name;
private Timestamp startDate;
private String title;
private String deptName;
private Double salary;
}
DAO는 실질적인 DB 연동을 수행합니다.
① insertEmployee()
사용자가 입력한 정보를 DB에 저장
② getEmployeeList()
DB를 조회하여 목록을 콘솔에 출력
③ getConnection(), close()
DB 커넥션 획득과 종료 기능 수행
package com.rubypaper.persistence.jdbc;
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 EmployeeDAO {
// JDBC 변수
private Connection conn = null;
private PreparedStatement stmt = null;
private ResultSet rs = null;
// SQL
private String INSERT_EMP = "INSERT INTO s_emp(id, name, start_date, title, dept_name, salary) VALUES ((SELECT nvl(max(id), 0) + 1 FROM s_emp), ?, ?, ?, ?, ?)";
private String LIST_EMP = "SELECT id, name, start_date, title, dept_name, salary FROM s_emp ORDER BY name";
// 회원 등록
public void insertEmployee(EmployeeVO vo) {
System.out.println("===> JDBC 기반으로 직원 등록 기능 처리");
try {
conn = getConnection();
stmt = conn.prepareStatement(INSERT_EMP);
stmt.setString(1, vo.getName());
stmt.setTimestamp(2, vo.getStartDate());
stmt.setString(3, vo.getTitle());
stmt.setString(4, vo.getDeptName());
stmt.setDouble(5, vo.getSalary());
stmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
close(stmt, conn);
}
}
// 회원 목록 조회
public List<EmployeeVO> getEmployeeList() {
System.out.println("===> JDBC 기반으로 직원 목록 조회 기능 처리");
List<EmployeeVO> employeeList = new ArrayList<EmployeeVO>();
try {
conn = getConnection();
stmt = conn.prepareStatement(LIST_EMP);
rs = stmt.executeQuery();
while(rs.next()){
EmployeeVO employee = new EmployeeVO();
employee.setId(rs.getLong("ID"));
employee.setName(rs.getString("NAME"));
employee.setStartDate(rs.getTimestamp("START_DATE"));
employee.setTitle(rs.getString("TITLE"));
employee.setDeptName(rs.getString("DEPT_NAME"));
employee.setSalary(rs.getDouble("SALARY"));
employeeList.add(employee);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
close(rs, stmt, conn);
}
return employeeList;
}
// 커넥션 획득
public Connection getConnection() {
try {
Class.forName("org.h2.Driver");
String url = "jdbc:h2:tcp://localhost/~/test";
conn = DriverManager.getConnection(url, "sa", "");
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
// 커넥션 종료(ResultSet, Statement, Connection)
public void close(ResultSet rs, Statement stmt, Connection conn) {
try {
if(rs != null)
rs.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
rs = null;
}
try {
if(stmt != null)
stmt.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
stmt = null;
}
try {
if(conn != null && !conn.isClosed())
conn.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
conn = null;
}
}
// 커넥션 종료(Statement, Connection)
public void close(Statement stmt, Connection conn) {
try {
if(stmt != null)
stmt.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
stmt = null;
}
try {
if(conn != null && !conn.isClosed())
conn.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
conn = null;
}
}
}
Client는 DAO에 구현된 메서드의 기능을 확인합니다.
package com.rubypaper.persistence.jdbc;
import java.sql.Timestamp;
import java.util.List;
public class EmployeeServiceClient {
public static void main(String[] args) {
EmployeeVO vo = new EmployeeVO();
vo.setName("홍길동");
vo.setStartDate(new Timestamp(System.currentTimeMillis()));
vo.setTitle("과장");
vo.setDeptName("총무부");
vo.setSalary(2700.00);
EmployeeDAO employeeDAO = new EmployeeDAO();
employeeDAO.insertEmployee(vo);
List<EmployeeVO> employeeList = employeeDAO.getEmployeeList();
for (EmployeeVO employee : employeeList) {
System.out.println("---> " + employee.toString());
}
}
}
콘솔에 실행 결과가 나타납니다. DB에도 데이터가 들어갔는지 확인해볼까요?
DB에도 데이터가 정상적으로 들어왔습니다.
앞에서 언급했듯이 JDBC는 모든 RDB에 대해 동일한 자바 코드를 사용합니다. 코드 변경없이 DB를 변경하기만 하면 됩니다. (테스트를 하고 싶다면 DAO.getConnection()에서 DB를 변경하면 됩니다.)
① DB 연동 메서드(insertEmployee, getEmployeeList)에 중복되는 코드가 사용됩니다. getConnection, close를 반복적으로 작성해야 합니다.
② SQL 구문이 DAO에 포함되어 있습니다. SQL을 변경하려면 DAO 파일을 열고 수정한 다음 다시 컴파일을 해야합니다.
JPA 퀵스타트
채규태 지음ㅣ루비페이퍼ㅣ2020ㅣ도서 정보