JDBC의 사용법(MySQL)

leedong617·2024년 9월 8일
post-thumbnail

JDBC의 개념

JDBC는 자바 애플리케이션이 데이터베이스와 상호작용할 수 있게 하는 표준 인터페이스임. JDBC를 사용하면 데이터베이스에 접속하여 데이터를 조회하거나 삽입, 수정, 삭제할 수 있음. JDBC는 데이터베이스 독립적인 API로, 다양한 DBMS(Oracle, MySQL, PostgreSQL 등)를 동일한 방식으로 다룰 수 있음.

JDBC의 작동 원리

JDBC는 드라이버를 사용하여 자바 애플리케이션과 데이터베이스를 연결함. JDBC 드라이버는 데이터베이스와의 통신을 처리하는 역할을 하며, 데이터베이스마다 다른 드라이버가 필요함. JDBC의 기본적인 작동 원리는 다음과 같음

JDBC 드라이버 로드

  • 자바 애플리케이션은 먼저 JDBC 드라이버를 로드하여 데이터베이스와의 연결을 준비함.
    데이터베이스 연결
  • DriverManager를 통해 데이터베이스에 연결함. 이때 데이터베이스의 URL, 사용자명, 비밀번호 등을 제공하여 연결함.
    SQL 쿼리 실행
  • 연결이 성공하면 SQL 쿼리를 Statement 또는 PreparedStatement를 사용하여 실행함.
    결과 처리
  • 쿼리 실행 결과는 ResultSet 객체를 통해 처리함. 이 객체를 사용해 데이터베이스에서 반환된 결과를 읽을 수 있음.
    연결 해제
  • 데이터베이스 작업이 완료되면 연결을 종료하여 자원을 해제함.

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 사용자이름의 설정된 비밀번호 입력


만약 github나 다른곳에 공유할 생각이라면 username 값과 password값은 개인정보 이기 때문에 지우고 올리는것이 좋다.


JDBC 사용 방법

이제 본격적인 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로직을 추가로 만들지는 않겠음.

위 예시들을 참고하여 충분히 작성이 가능하다고 생각함.

profile
웹개발자 취업 준비생

0개의 댓글