13. Spring 기반의 DB 연동
1> JDBC vs SpringJDBC
- sql 이용
- JDBC 보다 자바코드가 훨신 적음. (예외처리 불필요. 이유는 모두 RuntimeException 계열임)
try {
} catch (SQLException e) { // Compilechecked
// Compilechecked -> ComplieUnchecked
throw new RuntimeException(""); // ComplieUnchecked
}
- JdbcTemplate 빈을 이용해서 DB 처리.
2> SpringJDBC + h2 연동
가. 의존성 설정
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
나. h2 관리자 콘솔 설정
- 웹페이지로 제공
- 의존성 설정
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
- h2 관리자 콘솔 활성화
# application.properties
# h2 관리자 콘솔 활성화
spring.h2.console.enabled=true
- Application.java 실행
다음과 같이 console 에 h2 관리자 정보가 출력됨.
H2 console available at '/h2-console'.
Database available at 'jdbc:h2:mem:797f0fa4-06d6-40d2-ad29-8f0a92182454'
웹 브라우저에 요청
http://localhost:8080/h2-console
요청 URL 은 실행시마다 매번 랜덤하게 바뀜.
따라서 URL 고정하자.(testdb)
# application.properties
spring.datasource.url=jdbc:h2:mem:testdb
다. 매실행마다 자동으로 파일인식해서 테이블을 생성 + 데이터를 저장하는 작업처리
https://docs.spring.io/spring-boot/docs/2.7.18/reference/htmlsingle/#howto.data-initialization.using-basic-sql-scripts
#src/main/resources
schema.sql : create table 문
data.sql : insert 문
#schema.sql
create table todo (
id int primary key,
name varchar(255) not null,
author varchar(255) not null
);
#data.sql
insert into todo(id,name,author) values (1, 'boot공부', '홍길동');
insert into todo(id,name,author) values (2, 'react공부', '홍길동');
insert into todo(id,name,author) values (3, 'CI/CD공부', '홍길동');
라. boot 와 연동
- 전체적인 아키텍쳐
TodoH2Service
@Service @Repository
Application.java <--------> TodoH2ServiceImple <---------> TodoH2Repository <----------> h2
TodoDTO(Todo)
- sql 문 + JdbcTemplate 빈이용해서 연동
DML(insert/delete/update): update() 메서드
단일레코드조회: queryForObject(sql, RowMapper인터페이스, 파라미터값)
다중레코드조회: query(sql, RowMapper인터페이스 [,파라미터값])
package com.exam;
import java.util.List;
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.context.ApplicationContext;
import com.exam.dto.TodoDTO;
import com.exam.service.TodoH2Service;
import com.exam.service.TodoH2ServiceImpl;
@SpringBootApplication
public class Application implements CommandLineRunner{
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
ApplicationContext ctx;
@Override
public void run(String... args) throws Exception {
logger.info("logger:ApplicationContext:{}",ctx);
TodoH2ServiceImpl service =
ctx.getBean("todoService", TodoH2ServiceImpl.class);
// 저장
service.save(new TodoDTO(4, "final프로젝트", "홍길동"));
// 수정
service.update(new TodoDTO(4, "마지막프로젝트", "홍길동2"));
// 삭제
service.delete(1);
// id가 4번이 Todo 조회(단일조회)
TodoDTO todo = service.findById(4);
System.out.println(todo);
System.out.println("######################");
// 전체 조회
List<TodoDTO> list = service.findAll();
System.out.println(list);
}
}
package com.exam.dto;
public class TodoDTO {
int id;
String name;
String author;
public TodoDTO() {
super();
// TODO Auto-generated constructor stub
}
public TodoDTO(int id, String name, String author) {
super();
this.id = id;
this.name = name;
this.author = author;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
@Override
public String toString() {
return "TodoDTO [id=" + id + ", name=" + name + ", author=" + author + "]";
}
}
package com.exam.repository;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import com.exam.dto.TodoDTO;
@Repository("todoRepository")
public class TodoH2Repository {
// @Autowired 또는 생성자로 주입
// @Autowired
JdbcTemplate template;
// 생성자를 통해서 주입
public TodoH2Repository(JdbcTemplate template) {
super();
this.template = template;
}
// Todo 저장
public void save(TodoDTO todo) {
String sql = "insert into todo (id,name,author) values (?,?,?)";
template.update(sql, todo.getId(), todo.getName(), todo.getAuthor());
}
// Todo 삭제
public void delete(int id) {
String sql = "delete from todo where id = ?";
template.update(sql, id);
}
// Todo 수정
public void update(TodoDTO todo) {
String sql = "update todo set name=?, author=? where id=?";
template.update(sql, todo.getName(), todo.getAuthor(), todo.getId());
}
// Todo 단일조회
public TodoDTO findById(int id) {
String sql = "select id,name,author from todo where id = ?";
TodoDTO todo = template.queryForObject(sql, new RowMapper<TodoDTO>() {
@Override
public TodoDTO mapRow(ResultSet rs, int rowNum) throws SQLException {
// rs 에 값을 얻어서 TodoDTO 에 저장후 반환.
TodoDTO dto = new TodoDTO();
dto.setId(rs.getInt("id"));
dto.setName(rs.getString("name"));
dto.setAuthor(rs.getString("author"));
return dto;
}
}, id);
return todo;
}
// Todo 전체조회
public List<TodoDTO> findAll() {
String sql = "select id,name,author from todo ";
List<TodoDTO> list = template.query(sql, new RowMapper<TodoDTO>() {
@Override
public TodoDTO mapRow(ResultSet rs, int rowNum) throws SQLException {
// rs 에 값을 얻어서 TodoDTO 에 저장후 반환.
TodoDTO dto = new TodoDTO();
dto.setId(rs.getInt("id"));
dto.setName(rs.getString("name"));
dto.setAuthor(rs.getString("author"));
return dto;
}
});
return list;
}
}
package com.exam.service;
import java.util.List;
import org.springframework.stereotype.Service;
import com.exam.dto.TodoDTO;
public interface TodoH2Service {
public void save(TodoDTO todo); // 저장
public void delete(int id); // 삭제
public void update(TodoDTO todo); // 수정
public TodoDTO findById(int id); // 단일 조회
public List<TodoDTO> findAll(); // 전체 조회
}
package com.exam.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.exam.dto.TodoDTO;
import com.exam.repository.TodoH2Repository;
@Service("todoService")
public class TodoH2ServiceImpl implements TodoH2Service {
// @Autowired 또는 생성자로 주입
@Autowired
TodoH2Repository todoH2Repository;
// 저장
@Override
public void save(TodoDTO todo) {
todoH2Repository.save(todo);
}
// 삭제
@Override
public void delete(int id) {
todoH2Repository.delete(id);
}
// 수정
@Override
public void update(TodoDTO todo) {
todoH2Repository.update(todo);
}
// 단일조회
@Override
public TodoDTO findById(int id) {
return todoH2Repository.findById(id);
}
// 다중조회
@Override
public List<TodoDTO> findAll() {
return todoH2Repository.findAll();
}
}
# application.properties
logging.level.org.springframework=info
spring.h2.console.enabled=true
# application.properties
spring.datasource.url=jdbc:h2:mem:testdb
# data.sql
insert into todo(id,name,author) values (1, 'boot공부', '홍길동');
insert into todo(id,name,author) values (2, 'react공부', '홍길동');
insert into todo(id,name,author) values (3, 'CI/CD공부', '홍길동');
# schema.sql
create table todo (
id int primary key,
name varchar(255) not null,
author varchar(255) not null
);
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.18</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.exam</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
'[study]이론정리 > Spring Boot' 카테고리의 다른 글
Spring 기반의 DB 연동 - mybatis + mysql: 연동1 - @Repository 클래스 + TodoMapper.xml 연동 (1) | 2024.07.02 |
---|---|
Spring 기반의 DB 연동 - SpringJDBC + mysql 연동 (0) | 2024.07.02 |
AOP(Aspect Oriented Programming: 관점 지향 프로그래밍) (1) | 2024.07.02 |
프로파일(Profile) (0) | 2024.07.02 |
초기화 및 cleanup 작업 처리(@PostConstruct & @PreDestroy) (0) | 2024.07.02 |