[데브코스] Spring DB Connection
Updated: Categories: TILW8D1 - JDBC / MyBatis / JPA 등 스프링에서 DB를 사용하는 방법에 대해 알아보자
JDBC
- JDBC 복습 (이전 포스팅)
기본 사용법
- JDBC 드라이버 지정
- DB 접속 정보를 입력해 Connection 획득
- 해당 Connection을 통해 Statement 획득
- 쿼리날리기
- Connection과 Statement 닫아주기
예시
try{
Class.forName(드라이버);
Connection connection = DriverManager.getConnection(DB주소, 유저명, 비번);
Statement statement = connection.createStatement();
statement.executeQuery(쿼리);
statement.close();
connection.close();
} ...
JDBC Template
- Spring Boot의 JDBC Template을 통해 커넥션의 과정을 자동화할 수 있다.
기본 사용법
- DB 접속 정보(datasource)를
application.yaml
에 작성 - App Context 생성
@Autowired
로 JdbcTemplate 생성
예시
@Autowired
JdbcTemplate jdbcTemplate;
...
jdbcTemplate.update(쿼리)
jdbcTemplate.query(쿼리, resultSet 조작)
jdbcTemplate.queryForObject(쿼리, resultSet 조작)
MyBatis
- JDBC만 사용하면 자바 코드와 SQL문의 문법을 섞어서 사용해야하는 단점이 존재한다.
- 따라서
Query Mapper
인 MyBatis를 사용하여 코드와 SQL을 분리해보자
기본 사용법
- 쿼리를 사용하는
Repository
인터페이스를 작성한다 - 해당 인터페이스의 메소드와 매핑되는
mapper xml
을 작성한다 - 위에서 작성한 인터페이스와 xml을
application.yaml
에서 매핑시켜준다
Repository Interface
@Mapper
어노테이션으로 컴포넌트 등록
@Mapper
public interface RepositoryInterface {
메소드1,
메소드2,
...
}
Mapper XML
- 해당 xml 파일에 쿼리를 작성. (경로는 resources 폴더 하위)
- mapper의 namespace에 매핑할 인터페이스의 경로를 설정해줘야 한다.
- 인터페이스의 메소드명과 id가 일치하는 경우 쿼리가 실행됨
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="매핑할 인터페이스 경로">
<insert id="메소드1">
쿼리작성
</insert>
<select id="메소드2">
쿼리작성
</select>
...
</mapper>
yaml 설정
- 도메인 모델을 모아놓은 패키지 경로를 설정하여 매핑 기준을 정해준다
객체
->쿼리
쿼리 결과
->객체
- 쿼리를 작성하는 xml 경로를 설정한다.
mybatis:
# 쿼리결과(Result Set)을 어떤 자바 객체로 매핑할지 지정한다
type-aliases-package: 도메인 모델 패키지 경로
configuration:
map-underscore-to-camel-case: true # 매핑 객체명은 카멜케이스로
default-fetch-size: 100 # 쿼리 레코드 몇개까지 가져올지 설정
default-statement-timeout: 30 # statement 타임아웃 설정
mapper-locations: classpath:mapper/*.xml # 쿼리 xml 경로 지정
사용
- 구현체가 없는 인터페이스지만, 메소드를 호출하면 Mapper XML을 통해 쿼리가 실행된다
- 도메인 객체를 입력할 수 있고, 결과값 또한 도메인 객체에 매핑되어 나온다.
@Autowired
RepositoryInterface repositoryInterface;
...
var 도메인객체 = repositoryInterface.메소드1(도메인객체);
JPA
- 쿼리를 작성하지 않고 자바 코드 entity를 통해 데이터에 접근하는 ORM
- 자바 객체와 DB 테이블이 완벽히 연동되어 동작한다!
- SQL 의존적 개발에서 탈피, 객체중심 개발이 가능하다.
- But 관계형 DB를 중심으로 구조화되어 있기 때문에 OOP의 특징을 지원하지는 않는다.
yaml
- jpa 설정은 yaml 파일에서~
spring:
jpa:
generate-ddl: true
open-in-view: false
show-sql: true
Entity
@Entity
어노테이션으로 컴포넌트 등록@Table
어노테이션으로 특정 테이블과 entity 클래스를 매핑한다.- 생략시 클래스명과 동일한 테이블과 매핑됨
@Id
어노테이션으로 PK인 필드를 지정한다.- JPA 객체는 default 생성자만을 사용한다
@Entity
@Table(name = "테이블명")
public class CustomerEntity {
@Id
private 키값
}
Repository
- 기존 방식대로라면 Repository에 작성할게 많았지만 JPA를 사용하면 인터페이스만 선언해주면된다. (
뭐야이거..) JpaRepository
를 상속받기만 하면 끝.- 인자값엔 어떤 Entity와 매핑할지와 PK 타입(ex.
Long
)을 넣어주면 된다.
- 인자값엔 어떤 Entity와 매핑할지와 PK 타입(ex.
public interface 레포지토리 extends JpaRepository<엔티티, PK타입> {
}
사용
- JPA로 매핑된 인터페이스를 사용하기만 하면 된다. (Django에서 모델 사용하는것처럼..)
- 메소드는 이미 JPA 내부에 정의되어 있음 (findAll, save 등등..)
@Autowired
RepositoryInterface repositoryInterface;
...
var 도메인객체 = repositoryInterface.메소드()
Transactional
@Transactional
이 붙어 있으면 쿼리결과 객체는 영속성 컨텍스트에서 관리된다- 트랜잭션 안에서 쿼리결과 객체의 변화가 감지되면 자동으로 업데이트 쿼리가 실행됨.
JPA 구조
JPA
는 라이브러리가 아닌 인터페이스, 즉 관계형 DB를 어떻게 자바 객체로 사용할지를 정의한 방법일 뿐이다.Hibernate
는 JPA 인터페이스를 구현한 구현체이다.- 즉 우리가 가져다 쓸 수 있는 라이브러리임.
Spring Data JPA
는 JPA를 쓰기 편하게 만들어주는 모듈이다.- 우리가 Repository를 통해 JPA를 편하게 사용할 수 있는 것은 Spring Data JPA 내부에 있는
Entity Manager
덕분임
- 우리가 Repository를 통해 JPA를 편하게 사용할 수 있는 것은 Spring Data JPA 내부에 있는
출처 : https://suhwan.dev/2019/02/24/jpa-vs-hibernate-vs-spring-data-jpa/