๐งConnection Pool ์ด์ฉํ๊ธฐ
Connection Pooling ์ค์์ HikariCP ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ Connection Pool ์ด์ฉํจ
1. HikariConfig ๊ฐ์ฒด ์์ฑ์ ํตํด ์ค์ ์ ์ ์ํจ.
๋ด ์๊ฐ : HikariConfig ๊ฐ์ฒด๋ Connection Pool ์ค์ ํ์ ์ ๋ณด ๊ฐ์ฒด์
@Test
public void testHikariCP() throws Exception {
HikariConfig config = new HikariConfig();
config.setDriverClassName("org.mariadb.jdbc.Driver");
config.setJdbcUrl("jdbc:mariadb://localhost:3306/webdb");
config.setUsername("webuser");
config.setPassword("webuser");
config.addDataSourceProperty("cachePrepStmts", "true");
config.addDataSourceProperty("prepStmtCacheSize", "250");
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
HikariDataSource ds = new HikariDataSource(config);
Connection connection = ds.getConnection();
System.out.println(connection);
connection.close();
}
2. HikariConfig๋ฅผ ํตํด HikariDataSource๋ฅผ ์์ฑํจ.
DataSource๋ Connection Pool์ ๊ตฌํ ๊ฐ์ฒด์
HikariDataSource๋ getConnection()์ ์ ๊ณตํจ์ผ๋ก ์ด๋ฅผ ์ด์ฉํด์ Connection ๊ฐ์ฒด๋ฅผ ์ป์ด์ ์ฌ์ฉํ ์ ์์.
remind : Connection ์ธํฐํ์ด์ค๋ ๋คํธ์ํฌ๋ฅผ ํตํด db์ ์ฐ๊ฒฐํด์ฃผ๋ ์ญํ
@Test
public void testHikariCP() throws Exception {
HikariConfig config = new HikariConfig();
config.setDriverClassName("org.mariadb.jdbc.Driver");
config.setJdbcUrl("jdbc:mariadb://localhost:3306/webdb");
config.setUsername("webuser");
config.setPassword("webuser");
config.addDataSourceProperty("cachePrepStmts", "true");
config.addDataSourceProperty("prepStmtCacheSize", "250");
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
HikariDataSource ds = new HikariDataSource(config);
Connection connection = ds.getConnection();
System.out.println(connection);
connection.close();
}
๐งDAO์ @Cleanup
์ฑ
์๊ณผ ์ญํ ๋ถ๋ฆฌ ์์น์ ๋ฐ๋ผ ๋ค์๊ณผ ๊ฐ์ ๊ตฌ์กฐ๋ก ์๋น์ค๋ฅผ ์ฒ๋ฆฌํ๊ฒ ๋จ
TodoService <-> TodoDAO <-> DB
๐ง์ฑ๊ธํค ๋ฐฉ์(ENUM)์ ์ฌ์ฉํ์ฌ ConnectionUtil ํด๋์ค ๊ตฌํ
package org.zerock.jdbcex.dao;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import java.sql.Connection;
public enum ConnectionUtil {
INSTANCE;
private HikariDataSource ds;
ConnectionUtil() {
HikariConfig config = new HikariConfig();
config.setDriverClassName("org.mariadb.jdbc.Driver");
config.setJdbcUrl("jdbc:mariadb://localhost:3306/webdb");
config.setUsername("webuser");
config.setPassword("webuser");
config.addDataSourceProperty("cachePrepStmts", "true");
config.addDataSourceProperty("prepStmtCacheSize", "250");
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
ds = new HikariDataSource(config);
}
public Connection getConnection()throws Exception {
return ds.getConnection();
}
}
์ด๋ฅผ ํตํด ์ธ๋ถ์์๋ ConnectionUtil.INSTANCE.getConnection()์ ํตํด Connection์ ์ป์ ์ ์์.
๐งTodoDAO ํด๋์ค ๊ตฌํ(ํ์ฌ ์๊ฐ ๊ฐ์ ธ์ค๋ ์ฟผ๋ฆฌ ์ฝ์
๋์ด ์์)
package org.zerock.jdbcex.dao;
import lombok.Cleanup;
import org.zerock.jdbcex.domain.TodoVO;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
public class TodoDAO {
public String getTime(){
String now = null;
try(Connection connection = ConnectionUtil.INSTANCE.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("select now()");
ResultSet resultSet = preparedStatement.executeQuery();
) {
resultSet.next();
now = resultSet.getString(1);
}catch(Exception e){
e.printStackTrace();
}
return now;
}
๐งLombok ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ @Cleanup ์ฌ์ฉํ์ฌ TodoDAO ํด๋์ค ๊ตฌํ(์์ ๋์ผํ ์ฝ๋์)
package org.zerock.jdbcex.dao;
import lombok.Cleanup;
import org.zerock.jdbcex.domain.TodoVO;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
public class TodoDAO {
public String getTime2() throws Exception {
@Cleanup Connection connection = ConnectionUtil.INSTANCE.getConnection();
@Cleanup PreparedStatement preparedStatement = connection.prepareStatement("select now()");
@Cleanup ResultSet resultSet = preparedStatement.executeQuery();
resultSet.next();
String now = resultSet.getString(1);
return now;
}
}
๐งTodoVO๋ฅผ ์ฌ์ฉํ์ฌ DB์ ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ๋ ๊ธฐ๋ฅ(insert ์ฟผ๋ฆฌ ์คํ ์ฝ๋)์ TodoDAO์ ๊ตฌํํ๊ธฐ
DAO๋ ์ฑ
์๊ณผ ์ญํ ๋ถ๋ฆฌ ์์น์ ์ํด ๋ฐ์ดํฐ๋ฅผ ์ฝ์
ํ๋ ๊ธฐ๋ฅ(insert)์ ํ๋ ๊ฒ์ด์ง ์ค์ ๊ฐ๊น์ง ์
๋ ฅ ๋ฐ๊ณ ๊ฐ์ DB์ ์ฝ์
ํ๋ ๊ฒ์ด ์๋ / ๋ฐ์ดํฐ๋ฅผ ์
๋ ฅ๋ฐ๋ ๊ฒ์ ์๋น์ค ๊ณ์ธต์์ DAO์๊ฒ ๊ฐ์ ์ ๋ฌํ๊ณ ํ์ ์
๋ ฅ๋ฐ์ ๋ฐ์ดํฐ ๊ฐ์ ํตํด DAO๋ DB์ ๋ฐ์ดํฐ๋ฅผ ์ฝ์
ํ๋ ์ญํ ์ ํ๊ฒ ๋จ.
package org.zerock.jdbcex.dao;
import lombok.Cleanup;
import org.zerock.jdbcex.domain.TodoVO;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
public class TodoDAO {
public void insert(TodoVO vo) throws Exception {
String sql = "insert into tbl_todo (title, dueDate, finished) values (?, ?, ?)";
@Cleanup Connection connection = ConnectionUtil.INSTANCE.getConnection();
@Cleanup PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, vo.getTitle());
preparedStatement.setDate(2, Date.valueOf(vo.getDueDate()));
preparedStatement.setBoolean(3, vo.isFinished());
preparedStatement.executeUpdate();
}
๐งString sql ์์์ values ์์ '?'๊ฐ์ ๋์ค์ ์ ๋ฌํ ๋ฐ์ดํฐ๋ค์ ์ง์ ํ๋๋ฐ PreparedStatement.setXXX()๋ฅผ ์ด์ฉํด์ ์ค์ ๊ฐ๋ค์ ์ง์ ํจ.
setXXX() ๋ฉ์๋: ์ฟผ๋ฆฌ ๋ด์์ ?(ํ๋ ์ด์คํ๋)๋ก ํ์๋ ์์น์ ๊ฐ์ ๋ฐ์ธ๋ฉ.
import java.sql.*;
public class PreparedStatementExample {
public static void main(String[] args) {
String query = "INSERT INTO users (id, name, age) VALUES (?, ?, ?)";
try (Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/dbname", "username", "password");
PreparedStatement preparedStatement = connection.prepareStatement(query)) {
preparedStatement.setInt(1, 101);
preparedStatement.setString(2, "Alice");
preparedStatement.setInt(3, 30);
๐งTodoDAO์ ๋ชฉ๋ก ๊ธฐ๋ฅ ๊ตฌํํ๊ธฐ
package org.zerock.jdbcex.dao;
import lombok.Cleanup;
import org.zerock.jdbcex.domain.TodoVO;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
public class TodoDAO {
public List<TodoVO> selectAll()throws Exception {
String sql = "select * from tbl_todo";
@Cleanup Connection connection = ConnectionUtil.INSTANCE.getConnection();
@Cleanup PreparedStatement preparedStatement = connection.prepareStatement(sql);
@Cleanup ResultSet resultSet = preparedStatement.executeQuery();
List<TodoVO> list = new ArrayList<>();
while(resultSet.next()) {
TodoVO vo = TodoVO.builder()
.tno(resultSet.getLong("tno"))
.title(resultSet.getString("title"))
.dueDate( resultSet.getDate("dueDate").toLocalDate())
.finished(resultSet.getBoolean("finished"))
.build();
list.add(vo);
}
return list;
}
}
๐งTodoDAO์ ์กฐํ ๊ธฐ๋ฅ ๊ตฌํํ๊ธฐ
package org.zerock.jdbcex.dao;
import lombok.Cleanup;
import org.zerock.jdbcex.domain.TodoVO;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
public class TodoDAO {
public TodoVO selectOne(Long tno)throws Exception {
String sql = "select * from tbl_todo where tno = ?";
@Cleanup Connection connection = ConnectionUtil.INSTANCE.getConnection();
@Cleanup PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setLong(1, tno);
@Cleanup ResultSet resultSet = preparedStatement.executeQuery();
resultSet.next();
TodoVO vo = TodoVO.builder()
.tno(resultSet.getLong("tno"))
.title(resultSet.getString("title"))
.dueDate( resultSet.getDate("dueDate").toLocalDate())
.finished(resultSet.getBoolean("finished"))
.build();
return vo;
}
}
๐งTodoDAO์ ์ญ์ /์์ ๊ธฐ๋ฅ ๊ตฌํํ๊ธฐ
package org.zerock.jdbcex.dao;
import lombok.Cleanup;
import org.zerock.jdbcex.domain.TodoVO;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
public class TodoDAO {
public void deleteOne(Long tno) throws Exception {
String sql = "delete from tbl_todo where tno = ?";
@Cleanup Connection connection = ConnectionUtil.INSTANCE.getConnection();
@Cleanup PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setLong(1, tno);
preparedStatement.executeUpdate();
}
}
package org.zerock.jdbcex.dao;
import lombok.Cleanup;
import org.zerock.jdbcex.domain.TodoVO;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
public class TodoDAO {
public void updateOne(TodoVO todoVO)throws Exception{
String sql = "update tbl_todo set title =?, dueDate = ?, finished = ? where tno =?";
@Cleanup Connection connection = ConnectionUtil.INSTANCE.getConnection();
@Cleanup PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, todoVO.getTitle());
preparedStatement.setDate(2, Date.valueOf(todoVO.getDueDate()));
preparedStatement.setBoolean(3, todoVO.isFinished());
preparedStatement.setLong(4, todoVO.getTno());
preparedStatement.executeUpdate();
}
}