출처
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는 처음 들어본다!
흥미롭다..
원래 DB 설정하느라 1시간 버려야 되는거 아닌가? (환경 설정이랑 척진 사람)
금방 설치 할 수 있어서 편리했다!
고대의 개발 방식
자바는 Database와 연동하기 위해서는 무조건 jdbc가 필요함
build.gradle에 라이브러리를 추가해줘야 함
Datasource를 생성자 주입으로 spring으로 부터 받아준다.String sql = "insert ~~";Datasource 객체로부터 Connection 객체를 받아준다.Connection conn = dataSoruce.getConnection();
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)
이 부분이 신기한게 생각해보면 나는 이걸 .. 해 본적이 없는 것이다...! 회사에서 juit 사용 할 때도 그냥 ES 질의 시에만 해보고! TDD 공부 해볼 때도 순수 자바에서만 해봤기 때문에!! 흥미로웠다.

테스트를 진행해보는데 이해하기 힘든 일이 일어났다.
insert 과정을 테스트하고 있으니까 분명히 insert는 일어 날 것인데 list로 조회해보면 insert 된 멤버를 찾을 수가 없었다. 그리고 게다가 동일한 이름에 대해서는 validate를 하고 있어서 exception이 떨어져야 되는데 안 떨어진다! 그냥 ui로 추가를 해봤을 때는 너무 잘 들어가는 사태 발생. 심지어 id까지 38로 늘어난 상황!
근데 생각해보면.. 테스트를 하는데 이게 DB에 영향을 미쳐도 되는걸까..? 테스트하는 데이터가 DB에 쌓이게 될텐데 쌓이지 않는게 맞지 않나? 라는 생각이 들었고 또 커뮤니티를 뒤져봤다... 근데 사실 그 뒤에 설명해주실 예정이었다...
@Transactional 어노테이션에 의해 트랜잭션을 시작하고 테스트 완료 후에 롤백 해주고 있었다. 이렇게 바로 설명해주시는데 강의 멈춰놓고.. insert 이후에 commit이 안된건가 하고 직접 commit을 때리고 있었다;
@SpringBootTest: 스프링 컨테이너와 테스트를 함께 실행한다는 의미이다!
설정이 너무 쉬워서 신기하다..
좋은 테스트는! 순수 자바 테스트로 만들어졌을 확률이 더욱 크다! (흥미로움)
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가 필요해 보이는걸? 이라는 생각을 했다.
결국엔 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 당했다라는 말이 맞을 정도로 그냥 코드가 확 줄어들어 버렸다.. 헙🤢
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 개념이 너무;; 익숙하지 않아서 프로젝트에 반영하려면 따로 더 공부가 필요할 것 같다. 개념이 안서서 흐린눈 하고 싶지만 편리해보여서 모른척하기에는 양심에 찔리는 기분이다.. 화이팅..