16 커넥션풀
p283 - src/test/java/spring/jdbc/connection/DataSourceTest
@Slf4j
public class DataSourceTest {
private static final String URL = "jdbc:mysql://localhost:3306/test";
private static final String USERNAME = "root";
private static final String PASSWORD = "1234";
@Test
void dataSourceTest() throws SQLException {
DriverManagerDataSource datasource = new DriverManagerDataSource(URL, USERNAME, PASSWORD);
getConnection(datasource);
}
@Test
void hikariCPDataSourceTest() throws SQLException, InterruptedException {
// HikariCP DataSource 생성
HikariDataSource dataSource = new HikariDataSource();
dataSource.setJdbcUrl(URL);
dataSource.setUsername(USERNAME);
dataSource.setPassword(PASSWORD);
dataSource.setMaximumPoolSize(10);
dataSource.setPoolName("HikariPool");
dataSource.setInitializationFailTimeout(5000);
getConnection(dataSource);
Thread.sleep(1000);
}
private void getConnection(DataSource dataSource) throws SQLException {
Connection con1 = dataSource.getConnection();
Connection con2 = dataSource.getConnection();
log.info("con = {}", con1);
log.info("con2 = {}", con2);
}
}
p284 - src/main/resources/logback.xml
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
<!-- HikariCP의 디버그 레벨 설정 -->
<logger name="com.zaxxer.hikari" level="DEBUG"/>
</configuration>
p286 - src/main/java/spring/jdbc/repository/UsersDataSourceRepository
@Slf4j
public class UsersDataSourceRepository {
private final DataSource dataSource;
public UsersDataSourceRepository(DataSource dataSource) {
this.dataSource = dataSource;
}
public Users save(Users user) {
String sql = "INSERT INTO users (userId, userName, age) VALUES (?, ?, ?)";
Connection con = null;
PreparedStatement pstmt = null;
try {
// 데이터베이스 연결
con = dataSource.getConnection();
// PreparedStatement 생성
pstmt = con.prepareStatement(sql);
// PreparedStatement 파라미터 설정
pstmt.setString(1, user.getUserId());
pstmt.setString(2, user.getUserName());
pstmt.setInt(3, user.getAge());
// 쿼리 실행
int affectedRows = pstmt.executeUpdate();
log.info("affectedRows = {}", affectedRows);
return user;
} catch (SQLException e) {
log.error("Failed to save user: {}", e.getMessage());
throw new RuntimeException("Failed to save user", e);
} finally {
// 자원 해제
try {
if (pstmt != null) {
pstmt.close();
}
if (con != null) {
con.close();
}
} catch (SQLException e) {
log.error("Failed to close resources", e);
}
}
}
// 사용자 조회 로직 (findById)
public Users findById(String userId) {
String sql = "SELECT * FROM users WHERE userId = ?";
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
// 데이터베이스 연결
con = dataSource.getConnection();
// PreparedStatement 생성
pstmt = con.prepareStatement(sql);
pstmt.setString(1, userId);
// 쿼리 실행 및 결과 처리
rs = pstmt.executeQuery();
if (rs.next()) {
Users user = new Users();
user.setUserId(rs.getString("userId"));
user.setUserName(rs.getString("userName"));
user.setAge(rs.getInt("age"));
log.info("Found user: {}", user);
return user;
} else {
log.warn("User with ID {} not found", userId);
return null;
}
} catch (SQLException e) {
log.error("Failed to find user: {}", e.getMessage());
throw new RuntimeException("Failed to find user", e);
} finally {
// 자원 해제
try {
if (rs != null) {
rs.close();
}
if (pstmt != null) {
pstmt.close();
}
if (con != null) {
con.close();
}
} catch (SQLException e) {
log.error("Failed to close resources", e);
}
}
}
// 사용자 업데이트 로직 (update)
public Users update(Users user) {
String sql = "UPDATE users SET userName = ?, age = ? WHERE userId = ?";
Connection con = null;
PreparedStatement pstmt = null;
try {
// 데이터베이스 연결
con = dataSource.getConnection();
// PreparedStatement 생성
pstmt = con.prepareStatement(sql);
// PreparedStatement 파라미터 설정
pstmt.setString(1, user.getUserName());
pstmt.setInt(2, user.getAge());
pstmt.setString(3, user.getUserId());
// 쿼리 실행
int affectedRows = pstmt.executeUpdate();
log.info("Updated affectedRows = {}", affectedRows);
if (affectedRows > 0) {
log.info("User updated successfully: {}", user.getUserId());
return user;
} else {
log.warn("No user found with ID {}", user.getUserId());
return null;
}
} catch (SQLException e) {
log.error("Failed to update user: {}", e.getMessage());
throw new RuntimeException("Failed to update user", e);
} finally {
// 자원 해제
try {
if (pstmt != null) {
pstmt.close();
}
if (con != null) {
con.close();
}
} catch (SQLException e) {
log.error("Failed to close resources", e);
}
}
}
// 사용자 삭제 로직 (deleteById)
public void deleteById(String userId) {
String sql = "DELETE FROM users WHERE userId = ?";
Connection con = null;
PreparedStatement pstmt = null;
try {
// 데이터베이스 연결
con = dataSource.getConnection();
// PreparedStatement 생성
pstmt = con.prepareStatement(sql);
pstmt.setString(1, userId);
// 쿼리 실행
int affectedRows = pstmt.executeUpdate();
log.info("Deleted affectedRows = {}", affectedRows);
if (affectedRows > 0) {
log.info("User with ID {} deleted successfully", userId);
} else {
log.warn("No user found with ID {}", userId);
}
} catch (SQLException e) {
log.error("Failed to delete user: {}", e.getMessage());
throw new RuntimeException("Failed to delete user", e);
} finally {
// 자원 해제
try {
if (pstmt != null) {
pstmt.close();
}
if (con != null) {
con.close();
}
} catch (SQLException e) {
log.error("Failed to close resources", e);
}
}
}
}
p287 - src/test/java/spring/jdbc/repository/UsersDataSourceRepositoryTest
@Slf4j
public class UsersDataSourceRepositoryTest {
private UsersDataSourceRepository usersRepository;
private DataSource dataSource;
@BeforeEach
void setUp() throws SQLException {
// MySQL 데이터베이스에 연결
// dataSource = new DriverManagerDataSource(
// "jdbc:mysql://localhost:3306/test", // MySQL 연결 URL (스키마: test)
// "root", // MySQL 사용자명
// "1234" // MySQL 비밀번호
// );
HikariDataSource dataSource = new HikariDataSource();
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
dataSource.setUsername("root");
dataSource.setPassword("1234");
usersRepository = new UsersDataSourceRepository(dataSource);
// 테스트용 테이블 생성
try (Connection connection = dataSource.getConnection();
Statement stmt = connection.createStatement()) {
stmt.executeUpdate("DELETE FROM users");
stmt.executeUpdate("ALTER TABLE users AUTO_INCREMENT = 1"); // AUTO_INCREMENT 초기화
}
}
@Test
void testSaveUser() {
// 사용자 저장
Users user = new Users();
user.setUserId("user1");
user.setUserName("JohnDoe");
user.setAge(30);
Users savedUser = usersRepository.save(user);
// 저장된 사용자 확인
assertNotNull(savedUser);
assertEquals("JohnDoe", savedUser.getUserName());
assertEquals(30, savedUser.getAge());
}
@Test
void testFindUserById() {
// 사용자 저장
Users user = new Users();
user.setUserId("user2");
user.setUserName("JaneDoe");
user.setAge(25);
usersRepository.save(user);
// 저장된 사용자를 조회
Users foundUser = usersRepository.findById("user2");
// 조회된 사용자 확인
assertNotNull(foundUser);
assertEquals("user2", foundUser.getUserId());
assertEquals("JaneDoe", foundUser.getUserName());
assertEquals(25, foundUser.getAge());
}
@Test
void testUpdateUser() {
// 사용자 저장
Users user = new Users();
user.setUserId("user3");
user.setUserName("InitialName");
user.setAge(20);
usersRepository.save(user);
// 사용자 정보 수정
user.setUserName("UpdatedName");
user.setAge(22);
Users updatedUser = usersRepository.update(user);
// 수정된 사용자 확인
assertNotNull(updatedUser);
assertEquals("UpdatedName", updatedUser.getUserName());
assertEquals(22, updatedUser.getAge());
}
@Test
void testDeleteUser() {
// 사용자 저장
Users user = new Users();
user.setUserId("user4");
user.setUserName("UserToDelete");
user.setAge(35);
usersRepository.save(user);
// 사용자 삭제
usersRepository.deleteById("user4");
// 삭제 후 사용자 확인
Users deletedUser = usersRepository.findById("user4");
assertNull(deletedUser); // 삭제된 사용자는 조회되지 않아야 함
}
}
Last updated