2020-4-4 스프링 Data common (1)

JPA

  • java에서는 JDBC(Java Database Connection)이라는걸 사용해서 DB에 연결할 수 있다.

img

docker run -p 54320:5432 -e POSTGRES_PASSWORD=1234 -e POSTGRES_USER=jimmy -e POSTGRES_DB=jpa-test --name postgre_boot -d postgres

$docker exec -it container_name bash
$su -u postgres

java와 sql

  • DDL : 데이터를 정의, 스키마를 만든다.
  • DML :
@SpringBootApplication
@PropertySource("classpath:application.properties")
public class DemoApplication {
	@Value("${db.username}")
	private String username;

	@Value("${db.password}")
	private String password;

	public static void main(String[] args) throws SQLException {
		SpringApplication.run(DemoApplication.class, args);
		String url = "jdbc:postgresql://localhost:54320/jpa-test";
		String username = "jimmy";
		String password="1234";
		try (Connection connection = DriverManager.getConnection(url, username, password)){
			System.out.println("Connection created: " + connection);
			String sql = "insert into ACCOUNT values (1, 'docker', '123')";
			try(PreparedStatement statement = connection.prepareStatement(sql)) {
				statement.execute();
			}
		}
	}
}

  • 이렇게 데이터를 다루는게 굉장히 번거롭다.
  • connection을 만드는 비용이 비싸고 오래걸린다.
  • sql이 DB마다 다르다. 그래서 Postgre => mysql로 가면 코드를 다 바꿔야된다.
  • 중복된 코드가 많다.

ORM(Object-Relation Mapping)

  • ORM은 클래스와 SQL 데이터베이스 테이블 사이의 맵핑정보를 기술한 메타데이터를 사용한다. 애플리케이션 객체를 SQL 데이터베이스 테이블에 자동으로 깔끔하게 영속화해준다.

JDBC대신 도메인 모델 사용하려는 이유는?

  • 객체 지향 프로그래밍의 장점을 활용
  • 각종 디자인패턴
  • 코드 재사용
  • 비즈니스 로직 구현 및 테스트 편하다.

장점

  • 생산성
  • 유지보수성
  • 성능 : 더 느릴수도 있다. 하지만 C가 자바보다 빠르다라는 맥락하고 비슷하다. 객체와 데이터베이스 사이에 캐시가 존재하기 때문에 불필요한 쿼리를 날리지 않는다. 여러번 동일한 쿼리를 날리면 캐시에서 디비에 변경사항을 반영하느냐 안하느냐를 결정한다.
  • 벤더 독립성 : mysql, postgresql 등으로 변경이 손쉽다. dialect(방언)을 설정하기만 하면 hibernate는 그 dialect에 맞는 sql을 생성한다.

단점

  • 학습비용

ORM 패러다임 불일치

밀도의 문제

  • 객체
    • 다양한 크기의 객체를 만들 수 있다.
    • 커스텀한 타입 만들기 쉽다.(primitive가 아닌 사용자 정의 클래스를 말한다)
  • 릴레이션
    • 테이블
    • 기본데이터타입(UDT는 비추)

서브타입문제

  • 객체
    • 상속구조 만들기 쉽다
    • 다형성
  • 릴레이션
    • 테이블 상속이라는게 없다
    • 상속기능을 구현해도 표준기술이 아니다
    • 다형적인 관계를 표현할 방법이 없다

식별성문제

  • 객체
    • 레퍼런스 동일성
    • 인스턴스 동일성(equlas()메서드)
  • 릴레이션
    • 주키(Primary key)

관계문제

  • 객체
    • 객체 레퍼런스로 관계표현
    • 방향이 존재한다.
    • 다대다 관계를 가질 수 있다.
  • 릴레이션
    • 외래키로 관계표현
    • 방향이라는 의미가 없다. 그냥 Join으로 아무거나 묶을 수 있다. => 외래키는 방향이 없다. 사실상 양방향
    • 다대다관계를 태생적으로 못만들고 조인테이블 또는 링크 테이블을 사용해서 두개의 1대다 관계로 풀어야한다.

데이터 네비게이션 문제

가장 복잡하고 성능에 영향을 많이준다.

  • 객체
    • 레퍼런스를 이용해서 다른 객체로 이동 가능
    • 콜렉션을 순회할 수도 있다.
  • 릴레이션
    • 원하는데이터를 가져오는데 매우 비효율적. 데이터베이스에 요청이 적게하기 위해 Join을 하는데 이 역시도 문제. => SQL에서 커넥션을 만드는게 큰 비용인데, 많은 Join을 해도 문제다.
    • n+1 select문제가 발생
Written on April 4, 2020