
JDBC는 자바 애플리케이션이 데이터베이스와 상호작용할 수 있게 하는 표준 인터페이스임. JDBC를 사용하면 데이터베이스에 접속하여 데이터를 조회하거나 삽입, 수정, 삭제할 수 있음. JDBC는 데이터베이스 독립적인 API로, 다양한 DBMS(Oracle, MySQL, PostgreSQL 등)를 동일한 방식으로 다룰 수 있음.
JDBC는 드라이버를 사용하여 자바 애플리케이션과 데이터베이스를 연결함. JDBC 드라이버는 데이터베이스와의 통신을 처리하는 역할을 하며, 데이터베이스마다 다른 드라이버가 필요함. JDBC의 기본적인 작동 원리는 다음과 같음
JDBC 드라이버 로드
DBMS 서버 설치 : MySQL, Oracle 등
JDBC Driver 설치 : 각 DBMS 페이지에서 제공하는 파일을 다운받기 (*.jar 파일)
JDBC API : JDK에 포함
JDBC Driver(MySQL) 다운로드
https://dev.mysql.com/downloads/connector/j/!
다운로드 파일을 압축을 풀고 원하는 경로에 저장
JDBC를 사용할 프로젝트 마우스 오른쪽 버튼을 클릭 -> Properties 클릭

Java Build Path 클릭
Add External JARs 클릭
다운 받은 driver파일을 압축을 풀고 폴더안에 jar파일을 선택 후 열기 클릭
Apply and Close 클릭
그 다음은 DB에 스키마와 테이블이 만들어졌다는 가정하에 설명하겠음.
테이블은 Member 와 Product
Product 테이블을 만들때는 product_no 컬럼에 AutoIncrement설정을 해줘야함(숫자타입에만 설정가능)
Member 와 Product 의 DTO와 DAO 클래스를 만들어 줌.
DAO와 DTO에 대해 무엇인지 궁금하다면
https://velog.io/@leedong617/DAO%EC%99%80-DTO

Member 와 Product DTO의 구성
Member.java
package com.member;
public class Member {
private String member_id;
private String member_pw;
private String name;
private int age;
public Member() {
}
public Member(String member_id,String member_pw,String name,int age) {
this.member_id=member_id;
this.member_pw=member_pw;
this.name=name;
this.age=age;
}
public String getMember_id() {
return member_id;
}
public void setMember_id(String member_id) {
this.member_id = member_id;
}
public String getMember_pw() {
return member_pw;
}
public void setMember_pw(String member_pw) {
this.member_pw = member_pw;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Member [member_id=" + member_id + ", member_pw=" + member_pw + ", name=" + name + ", age=" + age + "]";
}
}
Product.java
package com.product;
public class Product {
private String product_no;
private String product_name;
private int price;
public Product() {
}
public Product(String product_no,String product_name,int price) {
this.product_no=product_no;
this.product_name=product_name;
this.price=price;
}
public String getProduct_no() {
return product_no;
}
public void setProduct_no(String product_no) {
this.product_no = product_no;
}
public String getProduct_name() {
return product_name;
}
public void setProduct_name(String product_name) {
this.product_name = product_name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
@Override
public String toString() {
return "Product [product_no=" + product_no + ", product_name=" + product_name + ", price=" + price + "]";
}
}
get set 메소드들과 toString메소드를 간편하게 만드는 방법
해당 클래스 파일에서 마우스 오른쪽을 클릭하고

get set 메소드 생성

ToString 메소드 생성

그러면 DTO 클래스들은 작성 완료.
그 다음은 DAO 클래스를 작성하겠음.
public class MemberDAO {
private String driver = "com.mysql.cj.jdbc.Driver";
private String url = "jdbc:mysql://[호스트]:[포트번호]/[db스키마이름]?serverTimezone=UTC&useUniCode=yes&characterEncoding=UTF-8";
private String username = "[사용자이름]";
private String password = "[비밀번호]";
}
DB서버를 연결할 변수 설정


public class MemberDAO {
private String driver = "com.mysql.cj.jdbc.Driver";
private String url = "jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUniCode=yes&characterEncoding=UTF-8";
private String username = "root";
private String password = "[비밀번호]";
}
비밀번호는 해당 MySQL 사용자이름의 설정된 비밀번호 입력
이제 본격적인 JDBC 사용 방법을 설명하겠음.
예를 들어 회원 생성로직을 만들겠음.
Statement 가 아닌 PreparedStatement를 사용하여 구현함.
PreparedStatement는 SQL 문에 매개변수를 전달할 수 있어 SQL 인젝션을 방지하고 성능을 향상시킬 수 있음.
public class MemberDAO {
private String driver = "com.mysql.cj.jdbc.Driver";
private String url = "jdbc:mysql://[호스트]:[포트번호]/[db스키마이름]?serverTimezone=UTC&useUniCode=yes&characterEncoding=UTF-8";
private String username = "[사용자이름]";
private String password = "[비밀번호]";
// Member Insert 로직
public int insert(Member member) throws Exception {
Class.forName(driver);
int rowCount = 0;
// try-with-resources를 사용하여 Connection과 PreparedStatement를 자동으로 닫음
try (
Connection con = DriverManager.getConnection(url, username, password);
PreparedStatement pstmt = con.prepareStatement("insert into member(member_id,member_pw,name,age) values(?,?,?,?)");
) {
// ?에 순서대로 값이 들어감
pstmt.setString(1, member.getMember_id());
pstmt.setString(2, member.getMember_pw());
pstmt.setString(3, member.getName());
pstmt.setInt(4, member.getAge());
// excuteUpdate : 데이터 삽입, 수정, 삭제에 사용됨 (영향받은 값들의 개수를 반환함)
rowCount = pstmt.executeUpdate(); // 실행하여 데이터 삽입 후 결과 반환 (삽입이기 때문에 성공했다면 값 1 반환 실패한다면 에러)
} catch (SQLException e) {
e.printStackTrace(); // 로그 또는 적절한 예외 처리
}
// 리소스가 자동으로 해제됨
/*
* pstmt.close();
* con.close();
* 불필요
*/
return rowCount;
}
}
테스트 해보면

성공적으로 1을 반환함.

이제 멤버의 아이디로 멤버를 찾는 로직을 구현 해보겠음.
// Member Select By ID 로직
public Member findById(String member_id) throws Exception {
Member member = null;
Class.forName(driver);
try(
Connection con = DriverManager.getConnection(url, username, password);
PreparedStatement pstmt = con.prepareStatement("select member_id, member_pw, name, age from member where member_id=?");
) {
pstmt.setString(1, member_id);
// executeQuery : 데이터 조회에 사용됨 (ResultSet 객체를 반환함. 이 객체는 쿼리 결과를 행 단위로 처리할 수 있게 해줌.)
ResultSet rs = pstmt.executeQuery();
// next()메소드를 호출하여 다음 행이 있는지 확인하고, 첫 번째 행이 있다면 데이터를 추출하여 Member 객체를 생성함.
if(rs.next()) {
member=new Member(
//rs.getString()과 rs.getInt()를 통해 ResultSet에서 데이터를 추출하고, 이를 Member 객체의 생성자에 전달함.
rs.getString("member_id"),
rs.getString("member_pw"),
rs.getString("name"),
rs.getInt("age"));
}
}
// 데이터 추출받은 멤버 객체 반환
return member;
}
실행결과

다음은 모든 회원을 찾는 로직을 구현 해보겠음.
// Member Select All 로직
public List<Member> findAll() throws Exception {
List<Member> members = new ArrayList<>();
Class.forName(driver);
try(
Connection con = DriverManager.getConnection(url, username, password);
PreparedStatement pstmt = con.prepareStatement("select member_id, member_pw, name, age from member");
) {
// executeQuery : 데이터 조회에 사용됨 (ResultSet 객체를 반환함. 이 객체는 쿼리 결과를 행 단위로 처리할 수 있게 해줌.)
ResultSet rs = pstmt.executeQuery();
// next()메소드를 호출하여 다음 행이 있는지 확인하고, 행이 있다면 데이터를 추출하여 Member 객체를 생성함.
while(rs.next()) {
Member member=new Member(
//rs.getString()과 rs.getInt()를 통해 ResultSet에서 데이터를 추출하고, 이를 Member 객체의 생성자에 전달함.
rs.getString("member_id"),
rs.getString("member_pw"),
rs.getString("name"),
rs.getInt("age"));
members.add(member);
}
}
// 데이터 추출받은 멤버 객체 리스트 반환
return members;
}
실행결과
다음은 Product DAO를 만들어 보겠음.
public int insert(Product product) throws Exception {
Class.forName(driver);
int rowCount = 0;
try (
Connection con = DriverManager.getConnection(url, username, password);
PreparedStatement pstmt = con.prepareStatement("insert into product(product_name, price) values(?,?)");
) {
pstmt.setString(1, product.getProduct_name());
pstmt.setInt(2, product.getPrice());
rowCount = pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace(); // 로그 또는 적절한 예외 처리
}
return rowCount;
}
실행결과


Update나 Delete로직을 추가로 만들지는 않겠음.
위 예시들을 참고하여 충분히 작성이 가능하다고 생각함.