나도 스프링 부트를 사용해보자! - 스프링 DB 접근 기술

min·2022년 2월 19일
0

출처
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9E%85%EB%AC%B8-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8
스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
김영한 강사님

H2 데이터베이스 설치

H2는 처음 들어본다!
흥미롭다..
원래 DB 설정하느라 1시간 버려야 되는거 아닌가? (환경 설정이랑 척진 사람)
금방 설치 할 수 있어서 편리했다!

순수 JDBC

고대의 개발 방식
자바는 Database와 연동하기 위해서는 무조건 jdbc가 필요함
build.gradle에 라이브러리를 추가해줘야 함

  1. Datasource를 생성자 주입으로 spring으로 부터 받아준다.
  2. sql문을 작성해준다. String sql = "insert ~~";
  3. Datasource 객체로부터 Connection 객체를 받아준다.
Connection conn = dataSoruce.getConnection();
  1. PreparedStatement 객체를 만들어주고 excute 해준다.
private Connection getConnection() {
	return DataSourceUtils.getConnection(dataSource);
}
    
private void close(Connection conn) throws SQLException {
	DataSourceUtils.releaseConnection(conn, dataSource);
}

application.properties 파일이 태초부터 있어서 그냥 사용 할 수 있는 것도 매우 인상적이다.

개방-폐쇄 원칙(OCP, Open-Closed Principle)

  • 확장에는 열려있고, (기존 코드에 대한) 수정/변경에는 닫혀있다.
  • 스프링의 DI를 이용하면 기존 코드를 전혀 손대지 않고 설정만으로 구현 클래스를 변경 할 수 있다.

스프링 통합 테스트

이 부분이 신기한게 생각해보면 나는 이걸 .. 해 본적이 없는 것이다...! 회사에서 juit 사용 할 때도 그냥 ES 질의 시에만 해보고! TDD 공부 해볼 때도 순수 자바에서만 해봤기 때문에!! 흥미로웠다.

테스트를 진행해보는데 이해하기 힘든 일이 일어났다.
insert 과정을 테스트하고 있으니까 분명히 insert는 일어 날 것인데 list로 조회해보면 insert 된 멤버를 찾을 수가 없었다. 그리고 게다가 동일한 이름에 대해서는 validate를 하고 있어서 exception이 떨어져야 되는데 안 떨어진다! 그냥 ui로 추가를 해봤을 때는 너무 잘 들어가는 사태 발생. 심지어 id까지 38로 늘어난 상황!
근데 생각해보면.. 테스트를 하는데 이게 DB에 영향을 미쳐도 되는걸까..? 테스트하는 데이터가 DB에 쌓이게 될텐데 쌓이지 않는게 맞지 않나? 라는 생각이 들었고 또 커뮤니티를 뒤져봤다... 근데 사실 그 뒤에 설명해주실 예정이었다...

@Transactional 어노테이션에 의해 트랜잭션을 시작하고 테스트 완료 후에 롤백 해주고 있었다. 이렇게 바로 설명해주시는데 강의 멈춰놓고.. insert 이후에 commit이 안된건가 하고 직접 commit을 때리고 있었다;

@SpringBootTest: 스프링 컨테이너와 테스트를 함께 실행한다는 의미이다!
설정이 너무 쉬워서 신기하다..

좋은 테스트는! 순수 자바 테스트로 만들어졌을 확률이 더욱 크다! (흥미로움)

스프링 JDBCTemplate

Mybatis와 비슷한 라이브러리로 JDBC API에서 본 반복 코드를 대부분 제거해준다.

생성자가 하나인 경우에 @Autowired를 생략 할 수 있다.

    public Optional<Member> findByName(String name) {
        List<Member> result = jdbcTemplate.query("select * from member where id = ?", memberRowMapper());
        return result.stream().findAny();
    }
    
    private RowMapper<Member> memberRowMapper() {
        return (rs, rowNum) -> {
            Member member = new Member();
            member.setId(rs.getLong(rs.getString("id")));
            member.setName(rs.getString("name"));
            return member;
        };
    }

코드를 입력해보는 내내 나는 Mybatis 인간이라서 그런지 쿼리문이 저렇게 코드에 들어가 있는게 가독성이 좋아보이지는 않았다. 뭔가 상수화해서 관리하는 건가? 어떻게 저렇게 코드에 슥 넣어 둘 수 있는걸까? 만약에 100줄 정도의 복잡한 쿼리의 경우에는 어떻게 하려는걸까...?
RowMapper라는 것도 처음봐서 벅벅..
insert 나올 때는 약간 ES가 떠올랐다.. 너무 Mybatis 종속 인간이 되버린걸까..? 과연 이게 편리한 걸까(!!!)
장기적으로 쿼리 같은 걸 관리하려면 Mybatis가 필요해 보이는걸? 이라는 생각을 했다.

JPA

결국엔 SQL은 개발자가 관리를 하게 되는데 JPA를 사용하면 JDBCtemplate/Mybatis가 제공하는 기존의 반복 코드 줄이기는 물론이고 기본적인 SQL도 JPA가 제공해줘서 개발 생산성이 올라간다!
SQL과 데이터 중심의 설계 -> 객체 중심의 설계

위에서 Mybatis가 편리한거 아닌가? 라고 생각했는데 바로 JPA를 알려주시면서 구글 트랜드로 JPA의 중요성을.. 강조해주셨다...😂 아애 처음보는 개념이다!

ORM (Object Relational Mapping)

@Entity 어노테이션을 통해서 해당 객체와 DB 매핑이 이루어 질 수 있다.
JPA는 EntityManager를 통해서 동작한다. build.gradle에서 추가한 라이브러리에 의해서 현재 데이터베이스와 매핑을 해주기 때문에 EntityManager를 주입받아서 사용하면 된다.

어렵다 ㅜ^ㅜ..

강의 따라하면서
https://www.inflearn.com/questions/237621
javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement

Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement

이런 오류가 났다...
댓글 따라했더니 해결됬다..
강의는 버전이 1.4였나 그런데 최신으로 받아서 생기는 문제인것 같은데.. 수정 사항을 다시 지우고 돌리니까 오류가 나지 않았다. 도대체 뭘까; 시간을 너무 많이 써서 우선 넘어간다..

스프링 데이터 JPA

JPA를 편리하게 사용하도록 도와주는 기술이여서 JPA를 먼저 학습한 뒤에 사용해야 함
관계형 데이터베이스를 사용하는 경우 스프링 데이터 JPA를 사용해야 함

...?
이건 뭔가 JPA 당했다라는 말이 맞을 정도로 그냥 코드가 확 줄어들어 버렸다.. 헙🤢

public interface SpringDataJpaMemberRepository extends JpaRepository<Member, Long>, MemberRepository {
    @Override
    Optional<Member> findByName(String name);
}

스프링 데이터 JPA가 SpringDataJpaMemberRepository 를 스프링 빈으로 자동 등록 해준다.

공통 JpaRepository<Member, Long>를 확인해보면 기본적으로 구현이 되어 있는 것을 확인 할 수 있다. 기본적인 pk를 통한 CRUD와 같은 작업은 이미 구현이 되어 있다!

인터페이스(SpringDataJpaMemberRepository)의 이름을 정의 해주는 것 만으로.. 단순한 작업을 진행 할 수 있다!

실무 > JPA, 스프링 데이터 JPA (기본) + Querydsl(동적 쿼리) + JPA(네이티브 쿼리)를 사용한다.

JPA 개념이 너무;; 익숙하지 않아서 프로젝트에 반영하려면 따로 더 공부가 필요할 것 같다. 개념이 안서서 흐린눈 하고 싶지만 편리해보여서 모른척하기에는 양심에 찔리는 기분이다.. 화이팅..

profile
발등에 불이 따뜻하다..

0개의 댓글