본문 바로가기
Java/네트워크 통신

[Java] 126. 연습 : JDBC-HikariCP를 사용해 코드 작성하기

글: Song hyun 2024. 6. 18.
728x90
반응형

[Java] 126. 연습 : JDBC-HikariCP를 사용해 코드 작성하기


 

(1) DBConnectionManager

-Connection을 사용해 MySQL에 접속, 연결하는 역할

-HikariCP를 사용해 커넥션 풀을 활용함 => 커넥션 풀을 사용시, SQL 접속에 들어가는 자원 고갈을 최소화할 수 있음.

*하지만 커넥션 풀은 메모리 소모가 크다.

**커넥션(Connection)의 실행 주체는 Thread이다.

package ver2;

import java.sql.SQLException;
import java.sql.Connection;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

import lombok.Synchronized;

// 싱글톤 패턴 - 단 하나의 객체만 필요함을 보장해야 한다면
// 싱글톤 패턴으로 설계 할 수 있다.
// for Example: Timer 클래스
public class DBConnectionManager {
	
	// 자기 자신의 참조 주소값을 담을 변수 생성.
	// 단, private으로 외부에서 접근 못하도록 막는다.
	private static DBConnectionManager instance;
	private HikariDataSource dataSource;
	
	// 생성자를 <---- 외부에서 생성자를 호출 못하게 막아야 한다.
	private DBConnectionManager() {
		HikariConfig config=new HikariConfig();
		config.setJdbcUrl("jdbc:mysql://localhost:3306/studentdb?serverTimezone=Asia/Seoul");
		config.setUsername("root");
		config.setPassword("asd123");
		config.setMaximumPoolSize(10);
		dataSource=new HikariDataSource(config);
	}
	
	// 외부에서 클래스 이름.getOOO 메서드를 만들어주면 된다.
	// 한 번에 하나의 스레드만 접근하도록 동기화 적용
	public synchronized DBConnectionManager getInstance() {
		if(instance==null) {
			instance=new DBConnectionManager();
		}
		return instance;
	}
	
	// Connection 객체를 반환 (구현체-HikariCP)
	public Connection getConnection() throws SQLException{
		return dataSource.getConnection();
	}
	
	
	
}

 

(2) StudentDTO (Data Transfer Object)

-SQL(데이터베이스)에 담긴 레코드들을 담는 클래스(인스턴스화에 사용)

package ver2.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

// DTO의 기능은 단지 데이터만 담을 역할을 하는 것은 아니다.
// 기능 추가도 가능하다.
@Data // 게터, 세터 생성
@NoArgsConstructor // 매개변수가 없는 생성자
@AllArgsConstructor // 매개변수가 모두 있는 생성자
// 생성자 오버로딩을 통해 빌더 패턴을 사용할 수 있다.
@ToString

public class StudentDTO {
	
	private int id;
	private String name;
	private int age;
	private String email;

	
}

 

 

(3) StudentDAO (Data Access Object)

-SQL(데이터베이스)에서 정보를 받아와, CRUD를 실행하는 주체

package ver2;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;


import ver2.model.StudentDTO;

// 물론 기능 설계는 인터페이스를 먼저 작성하고 구현 클래스를 만드는 것이 좋다.
public class StudentDAO {

	// 학생 정보 추가 기능 만들기
	// 클래스 = 데이터의 묶음
	public void addStudent(StudentDTO dto) throws SQLException {
		String query = " INSERT INTO students(name,age,email) VALUES(?,?,?) ";
		try (Connection conn = DBConnectionManager.getInstance().getConnection()) {
			PreparedStatement pstmt = conn.prepareStatement(query);
			pstmt.setString(1, dto.getName());
			pstmt.setInt(2, dto.getAge());
			pstmt.setString(3, dto.getEmail());
			pstmt.executeUpdate();
		}
	}

	// 학생의 ID로 조회하는 기능 만들기 (PK 활용)
	public StudentDTO getStudentByID(int id) throws SQLException {
		String query = " SELECT * FROM students WHERE id = ? ";
		try (Connection conn = DBConnectionManager.getInstance().getConnection()) {
			PreparedStatement pstmt = conn.prepareStatement(query);
			pstmt.setInt(1, id);

			try (ResultSet rs = pstmt.executeQuery()) {
				if (rs.next()) {
					return new StudentDTO(rs.getInt("id"), rs.getString("name"), rs.getInt("age"),
							rs.getString("email"));
				}
			}
		}
		return null;
	}

	// 학생 전체를 조회하는 기능 만들기
	public List<StudentDTO> getAllStudents() throws SQLException {
		// tip: 리스트라면 무조건 리스트를 생성하고 코드 작성
		List<StudentDTO> list = new ArrayList<>();
		String query = " SELECT * FROM students ";
		try (Connection conn = DBConnectionManager.getInstance().getConnection()) {
			PreparedStatement pstmt = conn.prepareStatement(query);
			ResultSet rs = pstmt.executeQuery();
		
			while(rs.next()){
				StudentDTO dto = new StudentDTO().builder()
					.id(rs.getInt("id"))
					.name(rs.getString("name"))
					.age(rs.getInt("age"))
					.email(rs.getString("email"))
					.build();
				list.add(dto);
			}
		}
		// todo 수정하기
		return list;
	}

	// 학생 정보 수정 기능 만들기
	public void updateStudent(String name, StudentDTO dto) throws SQLException {
		String query=" UPDATE students SET name = ? , age = ? , email = ? WHERE name = ? ";
		try(Connection conn=DBConnectionManager.getInstance().getConnection()){
			PreparedStatement pstmt=conn.prepareStatement(query);
			pstmt.setString(1, dto.getName());
			pstmt.setInt(2, dto.getAge());
			pstmt.setString(3, dto.getEmail());
			pstmt.setString(4, name); // 조건값 셋팅
			pstmt.executeUpdate();
		}
	}

	// 학생 정보 삭제하기
	public void deleteStudent(int id) throws SQLException {
		String query=" DELETE FROM students WHERE id = ? ";
		try(Connection conn = DBConnectionManager.getInstance().getConnection()){
			PreparedStatement pstmt=conn.prepareStatement(query);
			pstmt.setInt(1, id);
			pstmt.executeUpdate();
		}

	}

}

 

 

(4) StudentManagementSystem

-DBManager, DAO, DTO를 활용해 프로그램 실행 (main 쓰레드)

package ver2;

import java.sql.SQLException;
import java.util.List;

import ver2.model.StudentDTO;

public class StudentManagementSystem {
	
	private static final StudentDAO STUDENTDAO = new StudentDAO();
	
	public static void main(String[] args) {
		// 사용자에게 보여지는 부분을 꾸며줘도 된다.
		try {
			List<StudentDTO>list = STUDENTDAO.getAllStudents();
			System.out.println(list.size());
			System.out.println(list.toString());
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
728x90
반응형