JDBC (Java DataBase Connectivity)
- 자바 언어로 데이터베이스 프로그래밍을 하기 위한 라이브러리
- 자바 프로그래밍 언어로 만들어진 클래스와 인터페이스로 이루어진 API로서 ANSI SQL 지원
- SQL문을 실행할 수 있는 함수 호출 인터페이스
JDBC 특징
- DBMS 종류에 독립적인 자바 프로그래밍 가능
- DB가 달라지더라도 동일한 API를 사용하게 해줌 (드라이버 및 URL만 수정하면 가능)
- 자바가 가지는 플랫폼에 독립적이라는 특성과 DBMS에 독립적인 특성을 가짐
JDBC 기능
- 데이터베이스에 연결 설정
- SQL 문장을 DBMS에 전송
- SQL 문장 전송 후 결과를 처리할 수 있음
JDBC API: java.sql package
Driver (interface)
- 드라이버에 대한 정보를 가지고 있음
- 모든 드라이버가 반드시 구현해야 하는 인터페이스
- 드라이버의 버전이나 연결에 대한 정보를 알아볼 수 있는 메소드를 가지고 있음
Connection (interface)
- 데이터베이스에 대한 하나의 세션을 표현 (세션 : 하나의 클라이언트가 서버에 요청을 하기 위해 연결을 맺은 상태)
- DriverManager 클래스의 getConnection() 메소드를 이용하여 얻어 올 수 있음
- default로 setAutoCommit(true) 로 설정됨
Statement (interface)
: SQL 문장을 실행하고, 결과 값을 가져오기 위해 사용
// 특별히 SQL 문을 구분하지 않고,
// DML(delete, update, insert), Query(selct), DDL(create, drop) 등 수행 가능
public boolean execute(String sql) throws SQLException
// select를 처리할 때 사용
public ResultSet executeQuery(String sql) throws SQLException
// 주로 DML(delete, update, insert) 등의 SQL을 수행할 때 사용
public int executeUpdate(String sql) throws SQLException
PreparedStatement (interface)
- 동일한 SQL 문장이 여러번 반복적으로 수행될 때 사용하는 객체
- 대용량 문자나 바이너리 타입의 데이터를 저장하기 위해 사용될 수도 있음
- SQL 문장이 미리 컴파일 되어 PreparedStatement 객체에 저장됨
- 여러 번 반복 수행 시 clearParameters() 메소드를 이용해 Statement에 남겨진 값 초기화
// select를 처리할 때 사용
public ResultSet executeQuery() throws SQLException
// 주로 DML(delete, update, insert) 등의 SQL을 수행할 때 사용
public int executeUpdate() throws SQLException
ResultSet (interface)
- 쿼리에 대한 결과값 처리
- next() : ResultSet 객체의 커서를 이동
- getXXX(index or name) 메소드를 이용하여 데이터를 얻을 수 있음
JDBC 프로그래밍 개발 순서
1. JDBC Driver Loading
: DB와의 접속을 오픈 하기 위해 애플리케이션의 JVM 안으로 특정 드라이버 클래스를 적재
// mysql Driver class : com.nysql.cj.jdbc.Driver
private static final String DRIVER = "com.mysql.cj.jdbc.Driver";
// singleton 디자인 패턴
private static DBUtil instance = new DBUtil();
public static DBUtil getInstance() {
return instance;
}
// 생성자에서 최초 한번 or static block
private DBUtil() {
try {
Class.forName(DRIVER);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
2. DBMS와 연결 (Connection 생성)
public Connection getConnection() throws SQLException {
// URL 예 : "jdbc:mysql://localhost:3306/[스키마이름]?serverTimezone=UTC";
return DriverManager.getConnection(URL, DB_ID, DB_PWD);
}
3. SQL 실행 준비 (Statement, PreparedStatement 생성)
String sql = "select * from users";
Statement stmt = con.createStatement();
PreparedStatement pstmt = con.preparedStatement(sql);
4. SQL 실행 (DML - insert/update/delete, Query-select)
// select
Resultset rs = stmt.executeQuery(sql);
Resultset rs = pstmt.executeQuery();
// update delete insert
// pstmt.setXX(index, value); ? 에 들어갈
int r = stmt.executeUpdate(sql);
int r = pstmt.executeUpdate();
5. DBMS 연결 끊기
: 연결 역순으로 종료
rs.close();
pstmt.close();
conn.close();
실전 예시
table
CREATE TABLE IF NOT EXISTS `enjoy_trip`.`plan` (
`id` INT NOT NULL AUTO_INCREMENT,
`title` VARCHAR(100) NOT NULL,
`content` VARCHAR(500) NOT NULL,
`image` VARCHAR(100),
`writer` VARCHAR(20) NOT NULL,
PRIMARY KEY (`id`),
INDEX `fk_user_userId` (`writer` ASC) VISIBLE)
ENGINE = InnoDB;
DTO
package com.jmdb.EnjoyTrip.dto;
import lombok.*;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class Plan {
private int id;
private String title;
private String content;
private String image;
private String writer;
}
DAO
package com.jmdb.EnjoyTrip.dao;
import java.sql.*;
import java.util.*;
import com.jmdb.EnjoyTrip.dto.Plan;
import com.jmdb.EnjoyTrip.util.DBUtil;
public class PlanDaoImpl implements PlanDao {
private static PlanDao instance = new PlanDaoImpl();
private PlanDaoImpl() {}
public static PlanDao getInstance() {
return instance;
}
DBUtil util = DBUtil.getInstance();
@Override
public List<Plan> select(String writer) throws SQLException {
List<Plan> plans = new ArrayList<Plan>();
String sql = "select * from plan where writer = ?";
try (Connection conn = util.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)){
ps.setString(1, writer);
try(ResultSet rs = ps.executeQuery()){
while(rs.next()) {
plans.add(new Plan(
rs.getInt("id"),
rs.getString("title"),
rs.getString("content"),
rs.getString("image"),
rs.getString("writer")
));
}
}
}
return plans;
}
@Override
public int insert(Plan plan) throws SQLException {
String sql = "insert into plan (title, content, image, writer) values(?, ?, ?, ?)";
try (Connection conn = util.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)){
ps.setString(1, plan.getTitle());
ps.setString(2, plan.getContent());
ps.setString(3, plan.getImage());
ps.setString(4, plan.getWriter());
return ps.executeUpdate();
}
}
@Override
public int delete(int id) throws SQLException {
String sql = "delete from plan where id=?";
try (Connection conn = util.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)){
ps.setInt(1, id);
return ps.executeUpdate();
}
}
@Override
public int update(Plan plan) throws SQLException {
String sql = "update plan set title=?, content=?, image=?, writer=? where id=?";
try (Connection conn = util.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)){
ps.setString(1, plan.getTitle());
ps.setString(2, plan.getContent());
ps.setString(3, plan.getImage());
ps.setString(4, plan.getWriter());
ps.setInt(5, plan.getId());
return ps.executeUpdate();
}
}
// -------------- dao test ---------------------------
public static void main(String[] args) throws Exception {
PlanDao dao = PlanDaoImpl.getInstance();
dao.insert(new Plan(
0, "부산", "너무 가보고 싶어요!!", null, "danbibibi"));
dao.insert(new Plan(
0, "경주", "너무 또 가보고 싶어요!!", null, "danbibibi"));
dao.delete(1);
dao.update(new Plan(
2, "여수", "너무 가보고 싶어요!!", null, "danbibibi"));
for(Plan p : dao.select("danbibibi")) System.out.println(p);
}
}
'WEB > back-end' 카테고리의 다른 글
Interceptor (0) | 2023.04.22 |
---|---|
AOP(Aspect Oriented Programming, 관점 지향 프로그래밍) (0) | 2023.04.22 |
Spring (0) | 2023.04.21 |
DAO, DTO, Entity 란? (0) | 2023.03.22 |
Servlet과 JSP (0) | 2023.03.21 |