IntelliJ IDEA version : 2024.3.4.1
spring boot version : v3.3.10-SNAPSHOT
MySQL version : 8.0.41
문서를 읽기 전에 전체 디렉토리 구조를 파악하고 읽으면 이해하기 쉬움!
1. 전체 디렉토리 구조
src
├── main
│ ├── java
│ │ └── com.mc.app
│ │ ├── dto <- 요기
│ │ ├── frame <- 요기
│ │ ├── repository <- 요기
│ │ ├── service <- 요기
│ │ ├── controller
│ │ ├── controllerRest
│ │ ├── util
│ │ ├── Day03Application.java
│ │ └── ServletInitializer.java
│ └── resources
│ ├── mapper <- 요기
│ ├── static
│ ├── templates
│ ├── application.yml
│ └── application-dev.yml <- 요기
└── test
└── java
└── com.mc
├── cust <- 요기
└── weather
1. MySQL 계정 생성
use mysql;
create database 데이터베이스 이름;
select host, user from user;
create user '이름'@'localhost' identified by '비밀번호';
create user '이름'@'%' identified by '비밀번호';
grant all on mcdb.* to 'mcuser'@'%';
flush privileges;
2. build.gradle에 dependency 추가
// Mybatis & Mysql JDBC Driver
implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.3'
runtimeOnly 'com.mysql:mysql-connector-j'
3. properties 설정 (application-dev.yml)
: datasource랑 mybatis 줄 들여쓰기 중요!
: classparh는 기본적으로 resources 파일을 의미
# Spring Config
spring:
mvc:
view:
prefix: /WEB-INF/views/ # 경로
suffix: .jsp # 확장자
datasource:
url: jdbc:mysql://127.0.0.1:포트번호/DB이름?characterEncoding=utf8
username: 이름
password: 비밀번호
# Mybatis
mybatis: # classpath 기본 경로는 resources
type-aliases-package: com.mc.app.dto # dto 경로 지정
mapper-locations: classpath:/mapper/*.xml # mapper 경로 지정
4. resource/mapper 디렉토리에 파일명.xml 생성
: xml파일이 실제 DB 쿼리를 실행하는 파일
parameterType : 보내주는 타입
resultType : 받아오는 타입 (받아올 때 타입을 맞춰서 변환시켜줌)
<?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="com.mc.app.repository.CustRepository">
<select id="selectOne" parameterType="String" resultType="cust"> /* com.mc.dto.cust */
SELECT * FROM cust WHERE id=#{id}
</select>
<select id="select" resultType="cust">
SELECT * FROM cust
</select>
<insert id="insert" parameterType="cust">
INSERT INTO cust VALUES (#{id},#{pwd},#{name})
</insert>
<update id="update" parameterType="cust">
UPDATE cust SET pwd=#{pwd},name=#{name} WHERE id=#{id}
</update>
<delete id="delete" parameterType="String">
DELETE FROM cust WHERE id=#{id}
</delete>
</mapper>
5. dto/Cust
: 데이터를 담는 객체 (VO / DTO)
: DB의 테이블 구조를 기반으로 생성됨
package com.mc.app.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder
public class Cust {
private String id;
private String pwd;
private String name;
}
6. frame : 뼈대를 만들어 놓기( frame/MCRepository, frame/MCService )
: frame 패키지는 공통적으로 사용할 추상화된 인터페이스(뼈대) 를 정의하는 곳
: 비즈니스 로직이나 DB 연동을 하다 보면 다양한 도메인(Cust, Board 등)에 대해 CRUD 작업이 반복
: 이 반복되는 메서드의 틀을 미리 인터페이스로 정의해서, 재사용성과 유지보수성을 높이기 위한 설계 방식
MCService.java
package com.mc.app.frame;
import java.util.List;
public interface MCService<V,K> {
void add(V v) throws Exception;
void mod(V v) throws Exception;
void del(K k) throws Exception;
V get(K k) throws Exception;
List<V> get() throws Exception;
}
: 서비스 계층의 기본 동작을 정의한 인터페이스
V : 데이터 타입 (예: Cust, Board 등)
K : 키 타입 (예: id - String, 번호 - Integer 등)
MCRepository.java
package com.mc.app.frame;
import java.util.List;
public interface MCRepository<V,K> {
void insert(V v) throws Exception;
void update(V v) throws Exception;
void delete(K k) throws Exception;
V selectOne(K k) throws Exception;
List<V> select() throws Exception;
}
: DAO(Data Access Object)의 인터페이스
: DB와 직접 연결되는 로직을 추상화하여, 실제 구현체(repository)가 이 인터페이스를 따르도록 함
7. service/CustService
: CustService는 비즈니스 로직을 처리하는 서비스 계층
: MCService<Cust, String> 인터페이스를 구현하고, 실제 DB 처리는 CustRepository에게 위임한다.
: 즉, Controller → Service → Repository → DB 흐름에서 중간에 위치하며,
: 여기서 검증, 트랜잭션, 데이터 가공 등의 로직을 처리할 수 있다.
package com.mc.app.service;
// 코드가 너무 길어서 import부분은 지움
@Service
@RequiredArgsConstructor
public class CustService implements MCService<Cust, String> {
final CustRepository custRepository;
@Override
public void add(Cust cust) throws Exception {
custRepository.insert(cust);
}
@Override
public void mod(Cust cust) throws Exception {
custRepository.update(cust);
}
@Override
public void del(String s) throws Exception {
custRepository.delete(s);
}
@Override
public Cust get(String s) throws Exception {
return custRepository.selectOne(s);
}
@Override
public List<Cust> get() throws Exception {
return custRepository.select();
}
}
8. repository/CustRepository
: CustRepository는 DB와 실제 연결되어 SQL을 실행하는 DAO(Data Access Object) 이다.
: MyBatis의 Mapper XML 파일(custmapper.xml)과 연결되어 있고, @Mapper로 마이바티스가 해당 인터페이스의 구현체를 자동 생성
package com.mc.app.repository;
import com.mc.app.dto.Cust;
import com.mc.app.frame.MCRepository;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Repository
@Mapper
public interface CustRepository extends MCRepository<Cust, String> {}
: 인터페이스만 정의하면, MyBatis가 mapper XML을 통해 자동으로 구현체를 생성
: CustRepository는 MCRepository를 상속하므로 기본 CRUD 메서드를 갖는다.
: 실질적으로는 custmapper.xml에 정의된 SQL이 실행
<cust, String> : String 부분은 무조건 래퍼클래스를 사용해야 한다.
: DTO 부분에 id가 int여도 여기선 Integer를 사용해야 한다.
9. 흐름 요약 ( Controller → DB까지 )
요청 → Controller
→ Service (비즈니스 로직)
→ Repository (DAO: DB에 접근)
→ Mapper XML (SQL 실행)
→ DB
→ 결과를 다시 Controller로 반환
계층 | 설명 |
DTO | 데이터를 담는 객체 |
Frame | 공통 인터페이스 정의 |
Service | 비즈니스 로직 처리 |
Repository | DB 접근 |
Mapper XML | 실제 SQL 실행 |
Controller | 요청/응답 처리 |
10. test/java/com/mc/cust (CRUD)
: Insert, Update, Select, SelectOne, Delete test
Insert
@SpringBootTest
@Slf4j
class InsertTest {
@Autowired
CustService custService;
@Test
void contextLoads() {
Cust cust = Cust.builder().id("id10").pwd("pwd10").name("구름이").build();
try {
custService.add(cust);
log.info("OK!!");
} catch (Exception e) {
log.info("id 중복!!");
}
}
}
Update
@SpringBootTest
@Slf4j
class Update {
@Autowired
CustService custService;
@Test
void contextLoads() {
Cust cust = Cust.builder().id("id02").pwd("222222").name("김튜브").build();
try {
custService.mod(cust);
log.info("OK!!");
} catch (Exception e) {
log.info("id 중복!!");
}
}
}
Select, SelectOne
@SpringBootTest
@Slf4j
class Select {
@Autowired
CustService custService;
@Test
void contextLoads() {
List<Cust> custs = null;
try {
custs = custService.get();
log.info("OK:"+custs);
} catch (Exception e) {
log.info("Id 중복");
}
}
@Test
void contextLoads2() {
Cust cust = null;
try {
cust = custService.get("id01");
log.info("OK:"+cust.toString());
} catch (Exception e) {
log.info("Id 중복");
}
}
}
delete
@SpringBootTest
@Slf4j
class Update {
@Autowired
CustService custService;
@Test
void contextLoads() {
Cust cust = Cust.builder().id("id02").pwd("222222").name("김튜브").build();
try {
custService.mod(cust);
log.info("OK!!");
} catch (Exception e) {
log.info("id 중복!!");
}
}
}
'Database > JDBC' 카테고리의 다른 글
JDBC) eclipse + MySQL 연동 (0) | 2025.02.11 |
---|