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
반응형
'Java > 네트워크 통신' 카테고리의 다른 글
[Java] 125. JDBC 실습 : 학생 정보 관리 시스템 만들기 (0) | 2024.06.17 |
---|---|
[Java] 124. JDBC에서의 예외 처리 (0) | 2024.06.17 |
[Java] 123. HikariCP 라이브러리를 프로젝트에 추가하기 (0) | 2024.06.17 |
[Java] 122. JDBC 성능 최적화 (0) | 2024.06.17 |
[Java] 121. JDBC를 활용한 CRUD와 SOLID 원칙 (2) (0) | 2024.06.14 |