스프링 DB 접근 기술 종류
- JDBC
- JDBCTemplate
- JPA
- Spring Data JPA
JDBC(Java Database Connectivity)
JDBC는 자바에서 데이터베이스를 접속할 수 잇도록 하는 자바 API이다. JDBC는 데이터 베이스에서 접근을 제공한다.
DataSource는 데이터베이스 커넥션을 획득할 때 사용하는 객체다.
기본적인 조회
@Override
publicMember save(Member member) {
String sql = "insert into member(name) values(?)";
Connection conn =null;
PreparedStatement pstmt =null;
ResultSet rs =null;
try{
conn = getConnection();
pstmt = conn.prepareStatement(sql,
Statement.RETURN_GENERATED_KEYS);
pstmt.setString(1, member.getName());
pstmt.executeUpdate();
rs = pstmt.getGeneratedKeys();
if(rs.next()) {
member.setId(rs.getLong(1));
}else{
throw newSQLException("id 조회 실패");
}
returnmember;
}catch(Exception e) {
throw newIllegalStateException(e);
}finally{
close(conn, pstmt, rs);
}
}
@Override
publicOptional<Member> findById(Long id) {
String sql = "select * from member where id = ?";
Connection conn =null;
PreparedStatement pstmt =null;
ResultSet rs =null;
try{
conn = getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setLong(1, id);
rs = pstmt.executeQuery();
if(rs.next()) {
Member member =newMember();
member.setId(rs.getLong("id"));
member.setName(rs.getString("name"));
returnOptional.of(member);
}else{
returnOptional.empty();
}
}catch(Exception e) {
throw newIllegalStateException(e);
}finally{
close(conn, pstmt, rs);
}
}
@Override
publicList<Member> findAll() {
String sql = "select * from member";
Connection conn =null;
PreparedStatement pstmt =null;
ResultSet rs =null;
try{
conn = getConnection();
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
List<Member> members =newArrayList<>();
while(rs.next()) {
Member member =newMember();
member.setId(rs.getLong("id"));
member.setName(rs.getString("name"));
members.add(member);
}
returnmembers;
}catch(Exception e) {
throw newIllegalStateException(e);
}finally{
close(conn, pstmt, rs);
}
}
@Override
publicOptional<Member> findByName(String name) {
String sql = "select * from member where name = ?";
Connection conn =null;
PreparedStatement pstmt =null;
ResultSet rs =null;
try{
conn = getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, name);
rs = pstmt.executeQuery();
if(rs.next()) {
Member member =newMember();
member.setId(rs.getLong("id"));
member.setName(rs.getString("name"));
returnOptional.of(member);
}
returnOptional.empty();
}catch(Exception e) {
throw newIllegalStateException(e);
}finally{
close(conn, pstmt, rs);
}
}
privateConnection getConnection() {
returnDataSourceUtils.getConnection(dataSource);
}
private voidclose(Connection conn, PreparedStatement pstmt, ResultSet rs) {
try{
if(rs !=null) {
rs.close();
}
}catch(SQLException e) {
e.printStackTrace();
}
try{
if(pstmt !=null) {
pstmt.close();
}
}catch(SQLException e) {
e.printStackTrace();
}
try{
if(conn !=null) {
close(conn);
}
}catch(SQLException e) {
e.printStackTrace();
}
}
private voidclose(Connection conn)throwsSQLException {
DataSourceUtils.releaseConnection(conn, dataSource);
}
JDBC Template
스프링 JdbcTemplate과 MyBatis 같은 라이브러리는 JDBC API에서 본 반복 코드를 대부분 제거해준다. 하지만 SQL은 직접 작성해야 한다.
JDBC Template 구현방식
@Override
publicMember save(Member member) {
SimpleJdbcInsert jdbcInsert =newSimpleJdbcInsert(jdbcTemplate);
jdbcInsert.withTableName("member").usingGeneratedKeyColumns("id");
Map<String, Object> parameters =newHashMap<>();
parameters.put("name", member.getName());
Number key = jdbcInsert.executeAndReturnKey(newMapSqlParameterSource(parameters));
member.setId(key.longValue());
returnmember;
}
@Override
publicOptional<Member> findById(Long id) {
List<Member> result = jdbcTemplate.query("select * from member where id = ? ", memberRowMapper(), id);
returnresult.stream().findAny();
}
@Override
publicList<Member> findAll() {
returnjdbcTemplate.query("select * from member", memberRowMapper());
}
@Override
publicOptional<Member> findByName(String name) {
List<Member> result = jdbcTemplate.query("select * from member where name = ? ", memberRowMapper(), name);
returnresult.stream().findAny();
}
privateRowMapper<Member> memberRowMapper() {
return(rs, rowNum) -> {
Member member =newMember();
member.setId(rs.getLong("id"));
member.setName(rs.getString("name"));
returnmember;
};
}
JPA
JPA(Java Persistence API)는 자바 진영의 ORM 기술 표준
ORM → Object-relational mapping
객체는 객체대로 설계를 진행하고 관계형 DB는 독립적으로 설계한다.
ORM은 중간에서 매핑시켜준다.
private finalEntityManager em;
publicJpaMemberRepository(EntityManager em) {
this.em = em;
}
@Override
publicMember save(Member member) {
em.persist(member);
returnmember;
}
@Override
publicOptional<Member> findById(Long id) {
Member member = em.find(Member.class, id);
returnOptional.ofNullable(member);
}
@Override
publicOptional<Member> findByName(String name) {
List<Member> result = em.createQuery("select m from Member m where m.name = :name", Member.class)
.setParameter("name", name)
.getResultList();
returnresult.stream().findAny();
}
@Override
publicList<Member> findAll() {
returnem.createQuery("Select m from Member m", Member.class).getResultList();
}
Spring Data JPA
JPA기반 데이터 액세스 계층에 대한 향상된 지원을 해준다. 데이터 액세스 기술을 사용하는 spring 기반 애플리케이션을 나은 방향으로 구축 할 수 있다.
Spring Data JPA
Spring Data JPA, part of the larger Spring Data family, makes it easy to easily implement JPA based repositories. This module deals with enhanced support for JPA based data access layers. It makes it easier to build Spring-powered applications that use dat
spring.io
public interfaceSpringDataJpaMemberRepositoryextendsJpaRepository<Member,Long>, MemberRepository {
//select m from Member m where m.name = ?
@Override
Optional<Member> findByName(String name);
}
마무리
JPA를 공부하기로 마음을 먹어서 JPA를 공부하고 Spring Data JPA를 더 깊이 있게 다루기로 하였다.
출처 : Inflearn - 김영한 강사님 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술