SpringBoot #2.2 JDBC

텐저린티·2023년 6월 27일
0

데브코스

목록 보기
15/41

JDBC

  • 자바 어플리케이션이 관계형 데이터베이스와 연결할 수 있게 해주는 소프트웨어

JDBC Driver Model

  • 4개의 타입
  • MySQL에서는 type4(Thin Driver -Fully Java Driver) JDBC Driver 제공

JDBC Flow

  • DriverManager 를 통해 커넥션 객체 받아옴
  • Connection 통해 Statement 가져옴
  • Statement 통해 쿼리 실행 → ResultSet 가져오거나 update 실행
  • 데이터베이스 커넥션 종료 → 꼭 해줘야 함.

AutoClose

  • 데이터베이스 커넥션을 자동으로 종료
public static void main(String[] args) {
    try (
        var connection = DriverManager.getConnection("jdbc:mysql://localhost/order_mgmt", "root", "root1234!");
        var statement = connection.createStatement();
        var resultSet = statement.executeQuery("select * from customers");
    ) {
        while (resultSet.next()) {
            var name = resultSet.getString("name");
            var customerId = UUID.nameUUIDFromBytes(resultSet.getBytes("customer_id"));
            logger.info("customer Id -> {} name -> {}", customerId, name);
        }
    } catch (SQLException exception) {
        logger.error("Got error while closing connection", exception);
    }
}

PrepareStatement

  • SQL 쿼리에 공격자가 임의의 sql을 삽입하는 공격, sql injection.
  • 이를 방지하는 방법
  • 미리 준비된 구문을 실행만 하기 때문에 보안, 성능에 강점
  • 대신 autoclose 가 안 되기 때문에 try 블록으로 넣어줘야 함
public static void main(String[] args) {
    try (
        var connection = DriverManager.getConnection("jdbc:mysql://localhost/order_mgmt", "root", "root1234!");
        var statement = connection.prepareStatement("select * from customers");
    ) {
				statement.executeStatement();
				try (var resultSet = statement.executeQuery()) {
	        while (resultSet.next()) {
	            var name = resultSet.getString("name");
	            var customerId = UUID.nameUUIDFromBytes(resultSet.getBytes("customer_id"));
	            logger.info("customer Id -> {} name -> {}", customerId, name);
	        }
				}
    } catch (SQLException exception) {
        logger.error("Got error while closing connection", exception);
    }
}

UUID 주의사항

var customerId = UUID.nameUUIDFromBytes(resultSet.getBytes("customer_id"));
  • nameUUIDFromBytes 는 UUID 3버전의 메소드
  • UUID.randomeUUID 는 4버전의 메소드
  • 둘의 버전과 바이트 제한이 다르기 때문에 논리 오류가 발생
    • insert로 만든 entity랑 find로 찾은 entity랑 id가 다른 현상
  • UUID를 두 개의 바이트로 쪼개서 합치는 방식으로 해결
private UUID toUUID(byte[] customerIds) {
    var byteBuffer = ByteBuffer.wrap(customerIds);
    return new UUID(byteBuffer.getLong(), byteBuffer.getLong());
}

var customerId = toUUID(resultSet.getBytes("customer_id"));

SpringBoot #2.2 JDBC

JDBC

  • 자바 어플리케이션이 관계형 데이터베이스와 연결할 수 있게 해주는 소프트웨어

스크린샷 2023-06-27 오전 10.39.31.png

JDBC Driver Model

  • 4개의 타입
  • MySQL에서는 type4(Thin Driver -Fully Java Driver) JDBC Driver 제공

JDBC Flow

스크린샷 2023-06-27 오전 10.41.26.png

  • DriverManager 를 통해 커넥션 객체 받아옴
  • Connection 통해 Statement 가져옴
  • Statement 통해 쿼리 실행 → ResultSet 가져오거나 update 실행
  • 데이터베이스 커넥션 종료 → 꼭 해줘야 함.

AutoClose

  • 데이터베이스 커넥션을 자동으로 종료
public static void main(String[] args) {
    try (
        var connection = DriverManager.getConnection("jdbc:mysql://localhost/order_mgmt", "root", "root1234!");
        var statement = connection.createStatement();
        var resultSet = statement.executeQuery("select * from customers");
    ) {
        while (resultSet.next()) {
            var name = resultSet.getString("name");
            var customerId = UUID.nameUUIDFromBytes(resultSet.getBytes("customer_id"));
            logger.info("customer Id -> {} name -> {}", customerId, name);
        }
    } catch (SQLException exception) {
        logger.error("Got error while closing connection", exception);
    }
}

PrepareStatement

  • SQL 쿼리에 공격자가 임의의 sql을 삽입하는 공격, sql injection.
  • 이를 방지하는 방법
  • 미리 준비된 구문을 실행만 하기 때문에 보안, 성능에 강점
  • 대신 autoclose 가 안 되기 때문에 try 블록으로 넣어줘야 함
public static void main(String[] args) {
    try (
        var connection = DriverManager.getConnection("jdbc:mysql://localhost/order_mgmt", "root", "root1234!");
        var statement = connection.prepareStatement("select * from customers");
    ) {
				statement.executeStatement();
				try (var resultSet = statement.executeQuery()) {
	        while (resultSet.next()) {
	            var name = resultSet.getString("name");
	            var customerId = UUID.nameUUIDFromBytes(resultSet.getBytes("customer_id"));
	            logger.info("customer Id -> {} name -> {}", customerId, name);
	        }
				}
    } catch (SQLException exception) {
        logger.error("Got error while closing connection", exception);
    }
}

UUID 주의사항

var customerId = UUID.nameUUIDFromBytes(resultSet.getBytes("customer_id"));
  • nameUUIDFromBytes 는 UUID 3버전의 메소드
  • UUID.randomeUUID 는 4버전의 메소드
  • 둘의 버전과 바이트 제한이 다르기 때문에 논리 오류가 발생
    • insert로 만든 entity랑 find로 찾은 entity랑 id가 다른 현상
  • UUID를 두 개의 바이트로 쪼개서 합치는 방식으로 해결
private UUID toUUID(byte[] customerIds) {
    var byteBuffer = ByteBuffer.wrap(customerIds);
    return new UUID(byteBuffer.getLong(), byteBuffer.getLong());
}

var customerId = toUUID(resultSet.getBytes("customer_id"));

DataAccessException

  • JDBC 사용하면서 발생하는 예외에 대한 캡슐 클래스
  • 데이터베이스 사용하면서 발생하는 모든 예외에 대해 catch가 가능하므로 하위 예외를 catch 문에서 잡아서 개별 처리 가능
profile
개발하고 말테야

0개의 댓글

관련 채용 정보