티스토리 뷰
JDBC는 Java Database Connectivity이며, Java에서 Database에 접속하고 제어하기 위해 사용되는 API입니다. JDBC Template는 JDBC API를 사용하기 위해 Spring에서 제공하는 라이브러리입니다. JDBC Template를 활용하면, Java에서 관계형 데이터베이스에 접근하고 데이터를 생성(Create), 수정(Update), 삭제(Delete), 읽기(Read) 즉, CRUD를 수행할 수 있습니다..
이번 포스팅에서는 Springboot에서 JDBC Template를 활용하여 관계형 데이터베이스에 접근하고 데이터를 생성, 수정, 삭제, 읽기를 수행하는 방법에 대해 다루어 보겠습니다.
JDBC template 실습을 위한 프로젝트 다운로드하기
SpringIO 공식 사이트에서 제공하는 Spring Initializr를 활용하여, JDBC Template 실습용 프로젝트를 다운로드합니다. https://start.spring.io/ 에 접속하여 아래와 같이 설정한 후 프로젝트를 다운로드합니다.
- Gradle Project
- Java
- Spring Boot 2.6.7
- Packaging JAR
- Java 8
- Dependency : JDBC API, H2 Database
dependency항목에 JDBC API와 H2 Database를 추가합니다. H2 Database는 메모리형 데이터베이스로, 별도의 데이터베이스 S/W 설치 없이 사용 가능하여 토이 프로젝트를 할 때, 많이 사용합니다. 프로젝트를 다운로드하여, IntelliJ IDEA로 엽니다. 프로젝트를 열고 나서 build.gradle 파일을 열어보시면, 프로젝트 빌드 환경설정 내용이 작성되어있습니다. 그중에 dependency 항목을 보시면, JDBC API와 H2 Database에 대한 디펜던시 항목이 추가된 것을 확인하실 수 있습니다.
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
runtimeOnly 'com.h2database:h2'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
프로젝트를 다운로드하고, IDE로 열기까지 완료하셨으면 실습 준비는 완료되었습니다.
JDBC Template를 이용한 RDBMS 접근하는 코드 작성하기
왜 JDBC Template이라고 이름이 정의되었을까요? 제 생각엔, SQL 쿼리문은 DML , DDL 등 여러 가지로 조합으로 작성이 가능한데, 모든 SQL 쿼리문에 대해 API로 제공하기엔 양이 방대하므로, SQL 문을 입력받고 처리할 수 있는 템플릿이라 해서 템플릿이라는 명칭이 붙은 것 같네요. 다시 본론으로 돌아가서, 인터넷 웹 사이트 중 가장 많이 사용되는 정보가 Customer, 즉 고객정보입니다. 예제로 Customer정보를 저장, 추가, 삭제, 읽기를 수행하는 예제를 작성해보겠습니다. Customer 클래스를 작성하고, 이 클래스는 id와 이름을 저장하고, 정보를 출력하는 역할을 합니다.
package com.example.demo.relationaldataaccess;
public class Customer {
private long id;
private String firstName, lastName;
public Customer(long id, String firstName, String lastName) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
}
@Override
public String toString() {
return String.format(
"Customer[id=%d, firstName='%s', lastName='%s']",
id, firstName, lastName);
}
}
다음으로, Database를 생성하고 insert, select 하는 소스코드를 작성해보겠습니다.
package com.example.demo;
import com.example.demo.relationaldataaccess.Customer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
@SpringBootApplication
public class DemoApplication implements CommandLineRunner {
private static final Logger log = LoggerFactory.getLogger(DemoApplication.class);
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Autowired
JdbcTemplate jdbcTemplate;
@Override
public void run(String... strings) throws Exception {
log.info("Creating tables");
jdbcTemplate.execute("DROP TABLE customers IF EXISTS");
jdbcTemplate.execute("CREATE TABLE customers(" +
"id SERIAL, first_name VARCHAR(255), last_name VARCHAR(255))");
List<Object[]> splitUpNames = Arrays.asList("John Woo", "Jeff Dean", "Josh Bloch", "Josh Long").stream()
.map(name -> name.split(" "))
.collect(Collectors.toList());
splitUpNames.forEach(name -> log.info(String.format("Inserting customer record for %s %s", name[0], name[1])));
jdbcTemplate.batchUpdate("INSERT INTO customers(first_name, last_name) VALUES (?,?)", splitUpNames);
log.info("Querying for customer records where first_name = 'Josh':");
jdbcTemplate.query(
"SELECT id, first_name, last_name FROM customers WHERE first_name = ?", new Object[] { "Josh" },
(rs, rowNum) -> new Customer(rs.getLong("id"), rs.getString("first_name"), rs.getString("last_name"))
).forEach(customer -> log.info(customer.toString()));
}
}
소스코드를 살펴보면, 우선 DemoApplication에 CommandLineRunner 인터페이스를 상속합니다. CommandLineRunner 상속의 의미는 스프링의 애플리케이션 콘텍스트가 모두 로딩된 후 run() 메서드를 실행하겠다는 의미입니다. Database를 테스트하고자, HTTP GET API를 만들고, Controller 클래스 만들어서 브라우저로 테스트하는 것보다, 단순히 커맨드 라인에서 결과를 확인하는 게 좋을 때는 CommandLineRunner를 활용하는 것이 좋습니다. 다음으로, 데이터베이스 테이블을 삭제하고, 생성하는 DDL 쿼리문을 실행하고자 할 때는 jdbcTemplate.execute() 함수를 이용하고, select 쿼리문은 jdbcTemplate.query(), insert문은 jdbcTemplate.batchUpdate()를 활용합니다. 한 건의 데이터를 저장할 때 jdbcTemplate.update()가 좋지만, 여러 건의 데이터는 batchUpdate가 좋습니다. 그 이유는, 데이터베이스에게 작업을 요청하고 응답을 받아야 하는데, 건 별로 데이터 저장을 요청하고 응답을 받는 것보다 여러 건의 데이터를 저장할 경우 대량의 데이터 저장을 한 번만 요청하고 한 번만 응답받는 게 좋기 때문입니다. 소스코드를 실행해보면, 아래와 같이 콘솔 결과를 볼 수 있습니다. 로그를 살펴보시면, Customer 정보가 4건 저장되었고, josh bloch와 josh long을 조회하여 정보를 출력한 결과를 확인할 수 있습니다.
Inserting customer record for John Woo
Inserting customer record for Jeff Dean
Inserting customer record for Josh Bloch
Inserting customer record for Josh Long
Querying for customer records where first_name = 'Josh':
Customer[id=3, firstName='Josh', lastName='Bloch']
Customer[id=4, firstName='Josh', lastName='Long']
이상 Springboot에서 H2 Database와 JDBC API를 사용하는 방법을 알아보았습니다.
'IT 기술' 카테고리의 다른 글
SPA와 MPA 차이, 장단점 비교 (웹사이트 검색 노출 원리) (1) | 2022.07.31 |
---|---|
SpringBoot JPA 사용법 (0) | 2022.07.31 |
Springboot Actuator로 Health check 설정하기 (0) | 2022.07.29 |
Github Page와 Jekyll로 웹 사이트 제작하기 (블로그,포트폴리오) (0) | 2022.07.28 |
네이버 키워드 검색량 조회하는 방법 (0) | 2022.07.27 |
- Total
- Today
- Yesterday
- oracle pga sga
- 멀티코어 멀티프로세서
- AWS
- OSI 7계층
- 스프링부트실행
- 테스팅 자동화
- python
- MPA
- notion
- springboot restapi
- C++
- iframe 태그 찾기
- SPA
- 스프링부트빌드
- oracle 메모리
- 디자인패턴
- codesmell 유형
- springboot 실행
- API Gateway 캐싱
- 코드스멜 유형
- TCP/UDP
- selenium
- springboot build
- 클린코드작성원칙
- token
- springboot rest api 서버
- 스프링부트 restapi
- 클린코드작성법
- 디자인패턴 구조패턴
- notion 업무일정관리
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |