Search

MyBatis

MyBatis

MyBatis ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด๊ณ  ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ฒŒ์‹œํŒ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋Š” ์‹ค์Šต๊นŒ์ง€ ์ง„ํ–‰ํ•ด ๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.
โ€ข
Mybatis
โ€ข
ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ
โ€ข
์Šคํ”„๋ง ๋ถ€ํŠธ์—์„œ MyBatis ์‚ฌ์šฉ
โ€ข
์˜์กด์„ฑ ์ถ”๊ฐ€
โ—ฆ
build.gradle
โ—ฆ
pom.xml
โ€ข
๋งˆ์ด๋ฐ”ํ‹ฐ์Šค ์„ค์ • ํŒŒ์ผ - mybatis-config.xml
โ€ข
ํ”„๋กœ์ ํŠธ ์„ค์ • - application.properties
โ€ข
DB ๊ตฌ์ถ•
โ€ข
๋กœ์ง ์ž‘์„ฑ
โ—ฆ
DTO ์ž‘์„ฑ
โ—ฆ
SQL Mapper ์ž‘์„ฑ
โ—ฆ
Mapper ์ธํ„ฐํŽ˜์ด์Šค ์ž‘์„ฑ
โ—ฆ
Service ์ž‘์„ฑ
โ—ฆ
Controller ์ž‘์„ฑ
โ—ฆ
View ์ž‘์„ฑ

MyBatis

๋งˆ์ด๋ฐ”ํ‹ฐ์Šค๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง€์ •ํ•œ SQL, ์ €์žฅํ”„๋กœ์‹œ์ € ๊ทธ๋ฆฌ๊ณ  ๋ช‡๊ฐ€์ง€ ๊ณ ๊ธ‰ ๋งคํ•‘์„ ์ง€์›ํ•˜๋Š” ํผ์‹œ์Šคํ„ด์Šค ํ”„๋ ˆ์ž„์›Œํฌ์ด๋‹ค.
์ž๋ฐ” ํ”„๋กœ๊ทธ๋žจ์—์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๋™์„ ์œ„ํ•ด์„œ, JDBC ๋“œ๋ผ์ด๋ฒ„๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, Java ์ฝ”๋“œ์™€ SQL ์ฝ”๋“œ๊ฐ€ ๊ฐ™์ด ์‚ฌ์šฉ๋˜๋‹ˆ๊นŒ, ์œ ์ง€๋ณด์ˆ˜์„ฑ์ด ์ €ํ•˜๋ฉ๋‹ˆ๋‹ค.
๊ทธ๋ž˜์„œ Mybatis ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, Java ์ฝ”๋“œ์—์„œ SQL ์„ ๋ถ„๋ฆฌํ•ด์„œ XML ๊ด€๋ฆฌ๋ฅผ ํ•˜๊ณ , ์ž๋ฐ”์˜ ์ธํ„ฐํŽ˜์ด์Šค ํ˜ธ์ถœ์— ๋”ฐ๋ผ์„œ XML ์˜ ํŠน์ • id ์— ํ•ด๋‹นํ•˜๋Š” ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰์‹œํฐ SQL Mapper ๋ฐฉ์‹์œผ๋กœ DB ์—ฐ๋™์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ

๐Ÿ“ฆย spring-mybatis โ”‚ โ””โ”€โ”€โ”€๐Ÿ“‚java โ”‚ โ””โ”€โ”€โ”€๐Ÿ“‚com.aloha.springmybatis โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€โ”€๐Ÿ“‚controller โ”‚ โ”‚ โ””โ”€โ”€โ”€๐Ÿ“„BoardController.java โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€โ”€๐Ÿ“‚dto โ”‚ โ”‚ โ””โ”€โ”€โ”€๐Ÿ“„Board.java โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€โ”€๐Ÿ“‚service โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€โ”€๐Ÿ“„BoardService.java โ”‚ โ”‚ โ””โ”€โ”€โ”€๐Ÿ“„BoardServiceImpl.java โ”‚ โ”‚ โ”‚ โ””โ”€โ”€โ”€๐Ÿ“‚mapper โ”‚ โ””โ”€โ”€โ”€๐Ÿ“„BoardMapper.java โ”‚ โ””โ”€โ”€โ”€๐Ÿ“‚resources โ”‚ ๐Ÿ“„application.properties โ”‚ ๐Ÿ“„mybatis-config.xml โ”‚ โ””โ”€โ”€โ”€๐Ÿ“‚com.aloha.springmybatis.mapper โ””โ”€โ”€โ”€โ”€๐Ÿ“„BoardMapper.xml
Plain Text
๋ณต์‚ฌ

์Šคํ”„๋ง ๋ถ€ํŠธ์—์„œ MyBatis ์‚ฌ์šฉ

SpringBoot ์—์„œ MyBatis๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ์—๋Š” ์ฃผ๋กœ Gradle ๋นŒ๋“œ๋„๊ตฌ์˜ ์„ค์ •ํŒŒ์ผ์€ build.gradle ๋˜๋Š” Maven ๋นŒ๋“œ๋„๊ตฌ์˜ ์„ค์ • ํŒŒ์ผ์ธ pom.xml ์— ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•˜์—ฌ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค

์˜์กด์„ฑ ์ถ”๊ฐ€

โ€ข
build.gradle
โ€ข
pom.xml

build.gradle

โ€ข
mysql ๋“œ๋ผ์ด๋ฒ„ ์˜์กด์„ฑ
โ€ข
MyBatis ์˜์กด์„ฑ
โ€ข
build.gradle ์ „์ฒด์ฝ”๋“œ

mysql ๋“œ๋ผ์ด๋ฒ„ ์˜์กด์„ฑ

runtimeOnly 'com.mysql:mysql-connector-j'
Java
๋ณต์‚ฌ

MyBatis ์˜์กด์„ฑ

implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.3' testImplementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter-test:3.0.3'
Java
๋ณต์‚ฌ
springboot v3 ๋ฒ„์ „์„ ๊ธฐ์ค€์œผ๋กœ ์‚ฌ์šฉํ•œ ์˜์กด์„ฑ์ž…๋‹ˆ๋‹ค.

build.gradle

plugins { id 'java' id 'war' id 'org.springframework.boot' version '3.3.5' id 'io.spring.dependency-management' version '1.1.6' } group = 'com.aloha' version = '0.0.1-SNAPSHOT' java { toolchain { languageVersion = JavaLanguageVersion.of(17) } } configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.3' compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' runtimeOnly 'com.mysql:mysql-connector-j' annotationProcessor 'org.projectlombok:lombok' providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter-test:3.0.3' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' } tasks.named('test') { useJUnitPlatform() }
Java
๋ณต์‚ฌ

pom.xml

โ€ข
mysql ๋“œ๋ผ์ด๋ฒ„ ์˜์กด์„ฑ
โ€ข
MyBatis ์˜์กด์„ฑ
โ€ข
build.gradle ์ „์ฒด์ฝ”๋“œ

mysql ๋“œ๋ผ์ด๋ฒ„ ์˜์กด์„ฑ

<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.27</version> <scope>runtime</scope> </dependency>
XML
๋ณต์‚ฌ

MyBatis ์˜์กด์„ฑ

<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>3.0.3</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter-test</artifactId> <version>3.0.3</version> <scope>test</scope> </dependency>
XML
๋ณต์‚ฌ
springboot v3 ๋ฒ„์ „์„ ๊ธฐ์ค€์œผ๋กœ ์‚ฌ์šฉํ•œ ์˜์กด์„ฑ์ž…๋‹ˆ๋‹ค.

pom.xml

<?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 https://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>3.3.5</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>demo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <name>mybatis</name> <description>Demo project for Spring Boot</description> <url/> <licenses> <license/> </licenses> <developers> <developer/> </developers> <scm> <connection/> <developerConnection/> <tag/> <url/> </scm> <properties> <java.version>17</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>3.0.3</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter-test</artifactId> <version>3.0.3</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build> </project>
XML
๋ณต์‚ฌ

๋งˆ์ด๋ฐ”ํ‹ฐ์Šค ์„ค์ • ํŒŒ์ผ - mybatis-config.xml

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "https://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- ์„ค์ • --> <settings> <!-- ์–ธ๋”์Šค์ฝ”์–ด ์ผ€์ด์Šค์ธ ์ปฌ๋Ÿผ์„ ์นด๋ฉœ ์ผ€์ด์Šค๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์„ค์ • --> <!-- board_no - boardNo --> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings> <!-- ํƒ€์ž… ๋ณ„์นญ ์„ค์ • --> <typeAliases> <!-- ํ…Œ์ด๋ธ”๊ณผ ๋งคํ•‘ํ•  DTO๊ฐ€ ์žˆ๋Š” ํŒจํ‚ค์ง€ ๊ฒฝ๋กœ ์ง€์ • --> <package name="com.aloha.mybatis.dto"/> </typeAliases> </configuration>
XML
๋ณต์‚ฌ

mapUnderscoreToCamelCase

<settings> <!-- ์–ธ๋”์Šค์ฝ”์–ด ์ผ€์ด์Šค์ธ ์ปฌ๋Ÿผ์„ ์นด๋ฉœ ์ผ€์ด์Šค๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์„ค์ • --> <!-- board_no - boardNo --> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings>
XML
๋ณต์‚ฌ
์–ธ๋”์Šค์ฝ”์–ด ์ผ€์ด์Šค(์Šค๋„ค์ดํฌ ์ผ€์ด์Šค)๋ฅผ ์นด๋ฉœ ์ผ€์ด์Šค๋กœ ์ž๋™ ๋ณ€ํ™˜ํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ ํ™œ์„ฑํ™”
์ด๋ ‡๊ฒŒ ์ž‘์„ฑํ•˜๋ฉด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์–ธ๋”์Šค์ฝ”์–ด ์ผ€์ด์Šค๋ฅผ ๋ณ„๋„๋กœ ์ž๋ฐ”์˜ ์นด๋ฉœ ์ผ€์ด์Šค๋กœ ๋ณ€ํ™˜ํ•˜์ง€ ์•Š์•„๋„ ์ž๋™์œผ๋กœ ํ…Œ์ด๋ธ”์˜ ์ปฌ๋Ÿผ๋ช…์„ ๊ฐ์ฒด์˜ ๋ณ€์ˆ˜๋กœ ๋งคํ•‘ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ณ€ํ™˜ํ•ด์ค๋‹ˆ๋‹ค.

typeAliases - package

<typeAliases> <!-- ํ…Œ์ด๋ธ”๊ณผ ๋งคํ•‘ํ•  DTO๊ฐ€ ์žˆ๋Š” ํŒจํ‚ค์ง€ ๊ฒฝ๋กœ ์ง€์ • --> <package name="com.aloha.mybatis.dto"/> </typeAliases>
XML
๋ณต์‚ฌ
resultType ์†์„ฑ์—์„œ dto ๊ฐ์ฒด (ํŒจํ‚ค์ง€.ํด๋ž˜์Šค๋ช…) (ํด๋ž˜์Šค๋ช…)
์ด ์„ค์ •์„ ๊ตฌ์„ฑํ•˜๋ฉด Mapper ํŒŒ์ผ์—์„œ resultType ์†์„ฑ์ด ํŒจํ‚ค์ง€๋ถ€ํ„ฐ ํด๋ž˜์Šค๊นŒ์ง€ ๋‹ค ์ง€์ •ํ•˜์ง€ ์•Š์•„๋„, ๋งคํ•‘ํ•  ๊ฐ์ฒด๊ฐ€ ์žˆ๋Š” ํŒจํ‚ค์ง€๋ฅผ ์—ฌ๊ธฐ ์„ค์ •ํ•จ์œผ๋กœ์จ, ๊ฐ์ฒด ์ด๋ฆ„๋งŒ ์ž‘์„ฑํ•ด๋„ ์กฐํšŒ์˜ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ฒด์˜ ๋ฐ”๋กœ ๋งคํ•‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
<!-- ๊ฒŒ์‹œ๊ธ€ ์กฐํšŒ --> <select id="select" resultType="com.aloha.mybatis.dto.Board">
XML
๋ณต์‚ฌ
์ด ์„ค์ •์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด ย ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํŒจํ‚ค์ง€๋ถ€ํ„ฐ ํด๋ž˜์Šค๋ช…๊นŒ์ง€ resultType ์†์„ฑ์— ๋‹ค ์ž‘์„ฑํ•ด์•ผ ๋˜์ง€๋งŒ, ์ด ์„ค์ •์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ์ฒด๋ช…๋งŒ ์ž‘์„ฑํ•ด๋„ ๋ฉ๋‹ˆ๋‹ค.
<!-- ๊ฒŒ์‹œ๊ธ€ ์กฐํšŒ --> <select id="select" resultType="Board">
XML
๋ณต์‚ฌ
๋”ฐ๋ผ์„œ ์กฐํšŒ ๊ฒฐ๊ณผ๋ฅผ ๋งคํ•‘ํ•  ๊ฐ์ฒด๋“ค์ด ์žˆ๋Š” ํŒจํ‚ค์ง€๋“ค์„ ๋ฏธ๋ฆฌ ์ง€์ •ํ•ด ๋†“์œผ๋ฉด . ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์†์„ฑ ๊ฐ’์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค .

ํ”„๋กœ์ ํŠธ ์„ค์ • - application.properties

DB ๋“œ๋ผ์ด๋ฒ„์™€ MyBatis์˜ ์„ค์ •์„ ํ”„๋กœ์ ํŠธ์— ์•Œ๋ ค์ฃผ๊ธฐ ์œ„ํ•ด์„œ๋Š” ย application.properties ํŒŒ์ผ์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ฐ์ดํ„ฐ ์†Œ์Šค์™€ Mybatis ๊ด€๋ จ ์„ค์ •์„ ์ž‘์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
application.properties ๋Š” ์Šคํ”„๋ง ๋ถ€ํŠธ์˜ ํ”„๋กœ์ ํŠธ ์„ค์ • ํŒŒ์ผ์ž…๋‹ˆ๋‹ค.
โ€ข
๋ฐ์ดํ„ฐ ์†Œ์Šค ์„ค์ •
โ€ข
mybatis-config.xml ์„ค์ •

๋ฐ์ดํ„ฐ ์†Œ์Šค ์„ค์ •

# ๋ฐ์ดํ„ฐ ์†Œ์Šค - MySQL spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://127.0.0.1:3306/aloha?serverTimezone=Asia/Seoul&allowPublicKeyRetrieval=true&useSSL=false&autoReconnection=true&autoReconnection=true spring.datasource.username=aloha spring.datasource.password=123456
Plain Text
๋ณต์‚ฌ

mybatis-config.xml ์„ค์ •

# Mybatis ์„ค์ • # Mybatis ์„ค์ • ๊ฒฝ๋กœ : ~/resources/mybatis-config.xml mybatis.config-location=classpath:mybatis-config.xml # Mybatis ๋งคํผ ํŒŒ์ผ ๊ฒฝ๋กœ : ~/๋ฉ”์ธํŒจํ‚ค์ง€/mapper/**Mapper.xml mybatis.mapper-locations=classpath:mybatis/mapper/**/**.xml
Plain Text
๋ณต์‚ฌ
โ€ข
classpath: ๋ผ๊ณ  ์ง€์ •ํ•˜๋ฉด, ~/resources ๊ฒฝ๋กœ ํ•˜์œ„๋ถ€ํ„ฐ ๊ฒฝ๋กœ๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
โ€ข
classpath:mybatis/mapper/**/**.xml ๋ผ๊ณ  ์ง€์ •ํ•˜๋ฉด, ~/resources ๊ฒฝ๋กœ๋ถ€ํ„ฐ ๋ชจ๋“  ๊ฒฝ๋กœ์˜ ๋ชจ๋“  ํ•˜์œ„ ํŒŒ์ผ์˜ ํ™•์žฅ์ž๊ฐ€ .xml ์ด๋ฉด ๋งˆ์ด๋ฐ”ํ‹ฐ์Šค ๋งคํผ(SQL) ํŒŒ์ผ๋กœ ์ธ์‹ํ•˜๋„๋ก ์ง€์ •ํ•œ๋‹ค.

mybatis-config.xml ์„ค์ • ํŒŒ์ผ ์—†์ด ์ ์šฉํ•˜๊ธฐ

# ์ปฌ๋Ÿผ๋ช…์„ ๋ณ€์ˆ˜๋ช…์œผ๋กœ ์ž๋™๋งคํ•‘ : board_no โžก boardNo mybatis.configuration.map-underscore-to-camel-case=true # resultType ์†์„ฑ์—์„œ dto ๊ฐ์ฒด (ํŒจํ‚ค์ง€.ํด๋ž˜์Šค๋ช…) โžก (ํด๋ž˜์Šค๋ช…) mybatis.type-aliases-package=com.aloha.mybatis.dto # Mybatis ๋งคํผ ํŒŒ์ผ ๊ฒฝ๋กœ : ~/๋ฉ”์ธํŒจํ‚ค์ง€/mapper/**Mapper.xml mybatis.mapper-locations=classpath:mybatis/mapper/**/**.xml
Plain Text
๋ณต์‚ฌ
MyBatis์— ์„ค์ • ํŒŒ์ผ์„ ์‚ฌ์šฉํ•ด์„œ ๋งˆ์ด๋ฐ”ํ‹ฐ์Šค์˜ ์„ค์ •์„ ๊ด€๋ฆฌํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ . ๊ธฐ๋ณธ์ ์ธ ์„ค์ •๋“ค์„ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ํ”„๋กœํฌํ‹ฐ์Šค์—์„œ ๋ฐ”๋กœ ์„ค์ •์„ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

application.properties

spring.application.name=spring-mybatis # ๋ฐ์ดํ„ฐ ์†Œ์Šค - MySQL spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://127.0.0.1:3306/aloha?serverTimezone=Asia/Seoul&allowPublicKeyRetrieval=true&useSSL=false&autoReconnection=true&autoReconnection=true spring.datasource.username=aloha spring.datasource.password=123456 # Mybatis ์„ค์ • # Mybatis ์„ค์ • ๊ฒฝ๋กœ : ~/resources/mybatis-config.xml # mybatis.config-location=classpath:mybatis-config.xml # ์ปฌ๋Ÿผ๋ช…์„ ๋ณ€์ˆ˜๋ช…์œผ๋กœ ์ž๋™๋งคํ•‘ : board_no โžก boardNo mybatis.configuration.map-underscore-to-camel-case=true # resultType ์†์„ฑ์—์„œ dto ๊ฐ์ฒด (ํŒจํ‚ค์ง€.ํด๋ž˜์Šค๋ช…) โžก (ํด๋ž˜์Šค๋ช…) mybatis.type-aliases-package=com.aloha.mybatis.dto # Mybatis ๋งคํผ ํŒŒ์ผ ๊ฒฝ๋กœ : ~/๋ฉ”์ธํŒจํ‚ค์ง€/mapper/**Mapper.xml mybatis.mapper-locations=classpath:mybatis/mapper/**/**.xml
Plain Text
๋ณต์‚ฌ

DB ๊ตฌ์ถ•

์ด๋ฒˆ ์‹ค์Šต์—์„œ๋Š” MySQL์˜ ๋“œ๋ผ์ด๋ฒ„๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค . MySQL์˜ ์„ค์น˜๊ฐ€ ํ•„์š”ํ•˜๊ฑฐ๋‚˜ . ๊ธฐ๋ณธ์ ์ธ ์‚ฌ์šฉ ๋ฐฉ๋ฒ•์„ ์•Œ๊ณ  ์‹ถ๋‹ค๋ฉด ์œ„์˜ ํŽ˜์ด์ง€๋ฅผ ์ฐธ์กฐํ•ด ์ฃผ์„ธ์š” .
โ€ข
์Šคํ‚ค๋งˆ : aloha
โ€ข
ํ…Œ์ด๋ธ” ์ƒ์„ฑ
โ—ฆ
board

board

CREATE TABLE `board` ( `no` int NOT NULL AUTO_INCREMENT, `title` varchar(100) NOT NULL, `writer` varchar(100) NOT NULL, `content` text, `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `views` int NOT NULL DEFAULT '0', PRIMARY KEY (`no`) ) COMMENT='๊ฒŒ์‹œํŒ';
SQL
๋ณต์‚ฌ

๋กœ์ง ์ž‘์„ฑ

โ€ข
DTO ์ž‘์„ฑ
โ€ข
SQL Mapper ์ž‘์„ฑ
โ€ข
Mapper ์ธํ„ฐํŽ˜์ด์Šค ์ž‘์„ฑ
โ€ข
Service ์ž‘์„ฑ
โ€ข
Controller ์ž‘์„ฑ
โ€ข
View ์ž‘์„ฑ

DTO ์ž‘์„ฑ

โ€ข
Board.java

Board.java

Board dto๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ board ํ…Œ์ด๋ธ”๊ณผ ๋งคํ•‘ํ•˜๊ธฐ ์œ„ํ•œ ๋ฐ์ดํ„ฐ ์ „์†ก ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค
/** * Board * - ๊ฒŒ์‹œ๊ธ€ ์ •๋ณด */ @Data public class Board { private int no; private String title; private String writer; private String content; private Date createdAt; private Date updatedAt; private int views; }
Java
๋ณต์‚ฌ

SQL Mapper ์ž‘์„ฑ

SQL Mapper์—๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์š”์ฒญ์„ ๋ณด๋‚ด๊ธฐ ์œ„ํ•œ SQL ์ฟผ๋ฆฌ๋“ค์„ xml ํƒœ๊ทธ ํ˜•์‹์œผ๋กœ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค
โ€ข
๊ธฐ๋ณธ Mapper ํŒŒ์ผ ํ˜•์‹
โ€ข
๊ธฐ๋ณธ CRUD Mapper ํŒŒ์ผ ์ฝ”๋“œ
โ€ข
BoardMapper.xml

๊ธฐ๋ณธ Mapper ํŒŒ์ผ ํ˜•์‹

Mybatis Mapper ํŒŒ์ผ์—๋Š” ์ตœ์ƒ์œ„ ํƒœ๊ทธ๋กœ <mapper> ํƒœ๊ทธ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ๋„ค์ž„์ŠคํŽ˜์ด์Šค ์†์„ฑ์„ ์ž‘์„ฑํ•ด์„œ ๋ž˜ํผ ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ฒฝ๋กœ๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
namespace="๋งคํผ ์ธํ„ฐํŽ˜์ด์Šค ๊ฒฝ๋กœ"
namespace์˜ ์ž‘์„ฑํ•œ Mapper ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ฒฝ๋กœ๊ฐ€ ์ธํ„ฐํŽ˜์ด์Šค ํŒŒ์ผ์˜ ๊ฒฝ๋กœ์™€ ์ผ์น˜ ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.
<?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"> <!-- namespace="๋งคํผ ์ธํ„ฐํŽ˜์ด์Šค ๊ฒฝ๋กœ" --> <mapper namespace="com.aloha.mybatis.mapper.XXXMapper"> </mapper>
XML
๋ณต์‚ฌ

๊ธฐ๋ณธ CRUD Mapper ํŒŒ์ผ ์ฝ”๋“œ

SQL ํƒœ๊ทธ <select id="select" resultType="base"> Mapper ์ธํ„ฐํŽ˜์ด์Šค ๋ฉ”์†Œ๋“œ public Base select(int baseNo) throws Exception;
๊ฐ SQL ํƒœ๊ทธ์˜ id ์†์„ฑ๊ฐ’์ด Mapper ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋ฉ”์†Œ๋“œ ๋ช…๊ณผ ์ผ์น˜ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.
๋กœ์ง์„ ํ†ตํ•ด์„œ Mapper ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋ฉ”์†Œ๋“œ๊ฐ€ ํ˜ธ์ถœ์ด ๋˜๋ฉด, ์ด์™€ ๋งคํ•‘๋˜์–ด ์žˆ๋Š” SQL mapper ํŒŒ์ผ์˜ ํ•ด๋‹น ๋ฉ”์†Œ๋“œ๋ช…๊ณผ ์ผ์น˜ํ•˜๋Š” ์•„์ด๋””๋ฅผ ๊ฐ€์ง„ SQL ํƒœ๊ทธ๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค
<?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"> <!-- namespace="๋งคํผ ์ธํ„ฐํŽ˜์ด์Šค ๊ฒฝ๋กœ" --> <mapper namespace="com.aloha.mybatis.mapper.BaseMapper"> <!-- ๊ธฐ๋ณธ ๋“ฑ๋ก --> <insert id="insert"> INSERT INTO base( base_id, base_name ) VALUES ( #{baseId}, #{baseName} ) </insert> <!-- ๊ธฐ๋ณธ ์กฐํšŒ --> <select id="select" resultType="base"> SELECT * FROM base WHERE base_no = #{baseNo} </select> <!-- ๊ธฐ๋ณธ ์ˆ˜์ • --> <update id="update"> UPDATE base SET base_id = #{baseId} ,base_name = #{baseName} WHERE base_no = #{baseNo} </update> <!-- ๊ธฐ๋ณธ ์ˆ˜์ • --> <delete id="delete"> DELETE FROM base WHERE base_no = #{baseNo} </delete> </mapper>
XML
๋ณต์‚ฌ

BoardMapper.xml

์ด๋ฒˆ ์‹ค์Šต์—์„œ๋Š” ๊ฒŒ์‹œ๊ธ€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋“ฑ๋ก ์กฐํšŒ ์ˆ˜์ • ์‚ญ์ œํ•˜๋Š” ์ฟผ๋ฆฌ๋“ค์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด SQL ํƒœ๊ทธ๋กœ ์ž‘์„ฑํ•ด ๋ด…๋‹ˆ๋‹ค.
<?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"> <!-- namespace="๋งคํผ ์ธํ„ฐํŽ˜์ด์Šค ๊ฒฝ๋กœ" --> <mapper namespace="com.aloha.mybatis.mapper.BoardMapper"> <!-- ๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก --> <select id="list" resultType="Board"> SELECT * FROM board ORDER BY created_at DESC </select> <!-- ๊ฒŒ์‹œ๊ธ€ ์กฐํšŒ --> <select id="select" resultType="Board"> SELECT * FROM board WHERE no = #{no} </select> <!-- ๊ฒŒ์‹œ๊ธ€ ๋“ฑ๋ก --> <insert id="insert"> INSERT INTO board( title, writer, content) VALUES ( #{title}, #{writer}, #{content} ) </insert> <!-- ๊ฒŒ์‹œ๊ธ€ ์ˆ˜์ • --> <update id="update"> UPDATE board SET title = #{title} ,writer = #{writer} ,content = #{content} WHERE no = #{no} </update> <!-- ๊ฒŒ์‹œ๊ธ€ ์‚ญ์ œ --> <delete id="delete"> DELETE FROM board WHERE no = #{no} </delete> <!-- ๊ฒŒ์‹œ๊ธ€ ๋ฒˆํ˜ธ ์ตœ๋Œ“๊ฐ’ --> <select id="maxPk" resultType="int"> SELECT MAX(no) FROM board </select> </mapper>
XML
๋ณต์‚ฌ

Mapper ์ธํ„ฐํŽ˜์ด์Šค ์ž‘์„ฑ

๋งˆ์ด๋ฐ”ํ‹ฐ์Šค ๋งคํผ ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋ฉ”์†Œ๋“œ๋ช…์€ ๋งคํผ ํŒŒ์ผ์˜ id ์†์„ฑ๊ฐ’๊ณผ ์ผ์น˜ํ•ด์•ผํ•œ๋‹ค. - ํ•ด๋‹น ๋ฉ”์†Œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด, ๋งคํผ XML ํŒŒ์ผ์˜ SQL๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.
โ€ข
BoardMapper.java

BoardMapper.java

@Mapper public interface BoardMapper { // ๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก public List<Board> list() throws Exception; // ๊ฒŒ์‹œ๊ธ€ ์กฐํšŒ public Board select(int no) throws Exception; // ๊ฒŒ์‹œ๊ธ€ ๋“ฑ๋ก public int insert(Board board) throws Exception; // ๊ฒŒ์‹œ๊ธ€ ์ˆ˜์ • public int update(Board board) throws Exception; // ๊ฒŒ์‹œ๊ธ€ ์‚ญ์ œ public int delete(int no) throws Exception; // ๊ฒŒ์‹œ๊ธ€ ๋ฒˆํ˜ธ(๊ธฐ๋ณธํ‚ค) ์ตœ๋Œ“๊ฐ’ public int maxPk() throws Exception; }
Java
๋ณต์‚ฌ
๋งคํผ ํŒŒ์ผ์˜ id์™€ ์ผ์น˜ํ•˜๋Š” ๋ฉ”์†Œ๋“œ๋ช…์„ ์ž‘์„ฑํ•˜๊ณ , ๋งคํผ ํŒŒ์ผ์˜ SQL ํƒœ๊ทธ์— ์ „๋‹ฌํ•ด ์ค„ ํŒŒ๋ผ๋ฏธํ„ฐ๋“ค์„ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.
๋˜ํ•œ ์กฐํšŒ ์ฟผ๋ฆฌ์˜ ๊ฒฝ์šฐ์—๋Š” ์กฐํšŒ ๊ฒฐ๊ณผ๋ฅผ ๋งคํ•‘ ๋ฐ›์„ ๊ฐ์ฒด ํ˜น์€ ์ปฌ๋ ‰์…˜์„ ๋ฐ˜ํ™˜ ํƒ€์ž…์œผ๋กœ ์ž‘์„ฑํ•˜๊ณ , ๋“ฑ๋ก, ์ˆ˜์ •, ์‚ญ์ œ, ์ฟผ๋ฆฌ์˜ ๊ฒฝ์šฐ์—๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์ฒ˜๋ฆฌ๋œ ํ–‰์˜ ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜๋ฐ›๊ธฐ ์œ„ํ•˜์—ฌ int ํƒ€์ž…์œผ๋กœ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค

Service ์ž‘์„ฑ

์ด์ œ ์„œ๋น„์Šค ์ธํ„ฐํŽ˜์ด์Šค์™€ ๊ตฌํ˜„ ํด๋ž˜์Šค๋ฅผ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.
โ€ข
BoardService.java
โ€ข
BoardServiceImpl.java

BoardService.java

์„œ๋น„์Šค ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด์„œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์—์„œ ์‚ฌ์šฉํ•  ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ๋ฉ”์†Œ๋“œ์˜ ํ˜•ํƒœ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ๋ฉ”์†Œ๋“œ ํ˜•ํƒœ๋ฅผ ์ •์˜ํ•จ์œผ๋กœ์จ, ์‹ค์ œ๋กœ ๊ตฌํ˜„ํ•  ์ฝ”๋“œ์— ๋Œ€ํ•ด์„œ ๋‹คํ˜•์„ฑ๊ณผ ํ™•์žฅ์„ฑ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
public interface BoardService { // ๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก public List<Board> list() throws Exception; // ๊ฒŒ์‹œ๊ธ€ ์กฐํšŒ public Board select(int no) throws Exception; // ๊ฒŒ์‹œ๊ธ€ ๋“ฑ๋ก public int insert(Board board) throws Exception; // ๊ฒŒ์‹œ๊ธ€ ์ˆ˜์ • public int update(Board board) throws Exception; // ๊ฒŒ์‹œ๊ธ€ ์‚ญ์ œ public int delete(int no) throws Exception; }
Java
๋ณต์‚ฌ

BoardServiceImpl.java

๊ตฌํ˜„ ํด๋ž˜์Šค์—์„œ๋Š” ๋งคํผ ์ธํ„ฐํŽ˜์ด์Šค์˜ ์ ์ ˆํ•œ ๋ฉ”์†Œ๋“œ๋กœ ํ˜ธ์ถœํ•จ์œผ๋กœ์จ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•˜์—ฌ ์กฐํšŒ, ๋“ฑ๋ก, ์ˆ˜์ •, ์‚ญ์ œ ์š”์ฒญ์„ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋„๋ก ์ฝ”๋“œ๋ฅผ ์™„์„ฑํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ๊ฐ ๋ฉ”์†Œ๋“œ์—์„œ๋Š” ์„œ๋น„์Šค์˜ ๊ฐ ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ๋กœ์ง์„ ํ™•์žฅํ•˜๊ฑฐ๋‚˜ ๊ด€๋ จ๋œ ๋กœ๊ทธ ๋ฐ ์ฒ˜๋ฆฌ๋“ค์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
@Service // ์„œ๋น„์Šค ์—ญํ• ์˜ ์Šคํ”„๋ง ๋นˆ public class BoardServiceImpl implements BoardService { @Autowired private BoardMapper boardMapper; /** * ๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก ์กฐํšŒ */ @Override public List<Board> list() throws Exception { // TODO : boardMapper ๋กœ list() ํ˜ธ์ถœ /* * โžก List<Board> boardList ๋กœ ๋ฐ›์•„์˜ด * โžก return boardList */ List<Board> boardList = boardMapper.list(); return boardList; } /** * ๊ฒŒ์‹œ๊ธ€ ์กฐํšŒ * - no ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๊ฒŒ์‹œ๊ธ€ ๋ฒˆํ˜ธ๋ฅผ ์ „๋‹ฌ๋ฐ›์•„์„œ * ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์กฐํšŒ ์š”์ฒญ */ @Override public Board select(int no) throws Exception { // TODO : boardMapper ๋กœ select(no) ํ˜ธ์ถœ /* * โžก Board board ๋กœ ๋ฐ›์•„์˜ด * โžก return board */ Board board = boardMapper.select(no); return board; } /** * ๊ฒŒ์‹œ๊ธ€ ๋“ฑ๋ก */ @Override public int insert(Board board) throws Exception { // TODO : boardMapper ๋กœ insert(Board) ํ˜ธ์ถœ /* * โžก int result ๋กœ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ํ–‰(๊ฐœ์ˆ˜) ๋ฐ›์•„์˜ด * โžก return result */ int result = boardMapper.insert(board); return result; } /** * ๊ฒŒ์‹œ๊ธ€ ์ˆ˜์ • */ @Override public int update(Board board) throws Exception { // TODO : boardMapper ๋กœ update(Board) ํ˜ธ์ถœ /* * โžก int result ๋กœ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ํ–‰(๊ฐœ์ˆ˜) ๋ฐ›์•„์˜ด * โžก return result */ int result = boardMapper.update(board); return result; } /** * ๊ฒŒ์‹œ๊ธ€ ์‚ญ์ œ */ @Override public int delete(int no) throws Exception { // TODO : boardMapper ๋กœ delete(no) ํ˜ธ์ถœ /* * โžก int result ๋กœ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ํ–‰(๊ฐœ์ˆ˜) ๋ฐ›์•„์˜ด * โžก return result */ int result = boardMapper.delete(no); return result; } }
Java
๋ณต์‚ฌ

Controller ์ž‘์„ฑ

์ปจํŠธ๋กค๋Ÿฌ์—์„œ๋Š” ์š”์ฒญ ๊ฒฝ๋กœ๋ฅผ ๋งคํ•‘ํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ์— ์š”์ฒญ์— ๋Œ€ํ•˜์—ฌ ์ ์ ˆํ•œ ์„œ๋น„์Šค ๋กœ์ง ๋ฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ , ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์‘๋‹ตํ•  ๋ทฐ ํŽ˜์ด์ง€๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
์š”์ฒญ ๊ฒฝ๋กœ ๋งคํ•‘
๋ฐ์ดํ„ฐ ์š”์ฒญ
๋ทฐ ํŽ˜์ด์ง€ ์ง€์ •

BoardController.java

package com.aloha.mybatis.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import com.aloha.springmybatis.dto.Board; import com.aloha.springmybatis.service.BoardService; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestBody; /** * /board ๊ฒฝ๋กœ๋กœ ์š”์ฒญ ์™”์„ ๋•Œ ์ฒ˜๋ฆฌ * [GET] - /board/list : ๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก ํ™”๋ฉด * [GET] - /board/read : ๊ฒŒ์‹œ๊ธ€ ์กฐํšŒ ํ™”๋ฉด * [GET] - /board/insert : ๊ฒŒ์‹œ๊ธ€ ๋“ฑ๋ก ํ™”๋ฉด * [POST] - /board/insert : ๊ฒŒ์‹œ๊ธ€ ๋“ฑ๋ก ์ฒ˜๋ฆฌ * [GET] - /board/update : ๊ฒŒ์‹œ๊ธ€ ์ˆ˜์ • ํ™”๋ฉด * [POST] - /board/update : ๊ฒŒ์‹œ๊ธ€ ์ˆ˜์ • ์ฒ˜๋ฆฌ * [POST] - /board/delete : ๊ฒŒ์‹œ๊ธ€ ์‚ญ์ œ ์ฒ˜๋ฆฌ */ @Slf4j // ๋กœ๊ทธ ์–ด๋…ธํ…Œ์ด์…˜ @Controller // ์ปจํŠธ๋กค๋Ÿฌ ์Šคํ”„๋ง ๋นˆ์œผ๋กœ ๋“ฑ๋ก @RequestMapping("/board") // ํด๋ ˆ์Šค ๋ ˆ๋ฒจ ์š”์ฒญ ๊ฒฝ๋กœ ๋งคํ•‘ // - /board/~ ๊ฒฝ๋กœ์˜ ์š”์ฒญ์€ ์ด ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ์ฒ˜๋ฆฌ public class BoardController { // โญ๋ฐ์ดํ„ฐ ์š”์ฒญ๊ณผ ํ™”๋ฉด ์ถœ๋ ฅ // Controller --> Service (๋ฐ์ดํ„ฐ ์š”์ฒญ) // Controller <-- Service (๋ฐ์ดํ„ฐ ์ „๋‹ฌ) // Controller --> Model (๋ชจ๋ธ ๋“ฑ๋ก) // View <-- Model (๋ฐ์ดํ„ฐ ์ถœ๋ ฅ) @Autowired // ์˜์กด์„ฑ ์ž๋™ ์ฃผ์ž… private BoardService boardService; // @Service๋ฅผ --Impl ์— ๋“ฑ๋ก /** * ๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก ์กฐํšŒ ํ™”๋ฉด * @return * @throws Exception */ @GetMapping("/list") public String list(Model model) throws Exception { // ๋ฐ์ดํ„ฐ ์š”์ฒญ List<Board> boardList = boardService.list(); // ๋ชจ๋ธ ๋“ฑ๋ก model.addAttribute("boardList", boardList); // ๋ทฐ ํŽ˜์ด์ง€ ์ง€์ • return "/board/list"; // resources/templates/board/list.html } /** * ๊ฒŒ์‹œ๊ธ€ ์กฐํšŒ ํ™”๋ฉด * - /board/read?no=๐Ÿ’Ž * @param no * @return * @throws Exception */ // @RequestParam("ํŒŒ๋ผ๋ฏธํ„ฐ๋ช…") // - ์Šคํ”„๋ง ๋ถ€ํŠธ 3.2๋ฒ„์ „ ์ดํ•˜, ์ƒ๋žตํ•ด๋„ ์ž๋™ ๋งคํ•‘๋œ๋‹ค. // - ์Šคํ”„๋ง ๋ถ€ํŠธ 3.2๋ฒ„์ „ ์ด์ƒ, ํ•„์ˆ˜๋กœ ๋ช…์‹œํ•ด์•ผ ๋งคํ•‘๋œ๋‹ค. @GetMapping("/read") public String read(@RequestParam("no") int no, Model model) throws Exception { // ๋ฐ์ดํ„ฐ ์š”์ฒญ Board board = boardService.select(no); // ๋ชจ๋ธ ๋“ฑ๋ก model.addAttribute("board", board); // ๋ทฐํŽ˜์ด์ง€ ์ง€์ • return "/board/read"; } /** * ๊ฒŒ์‹œ๊ธ€ ๋“ฑ๋ก ํ™”๋ฉด * @return */ @GetMapping("/insert") public String insert() { return "/board/insert"; } /** * ๊ฒŒ์‹œ๊ธ€ ๋“ฑ๋ก ์ฒ˜๋ฆฌ * @param board * @return * @throws Exception */ @PostMapping("/insert") public String insertPro(Board board) throws Exception { // ๋ฐ์ดํ„ฐ ์š”์ฒญ int result = boardService.insert(board); // ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ // โญ• ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ์„ฑ๊ณต if( result > 0 ) { return "redirect:/board/list"; } // โŒ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ์‹คํŒจ return "redirect:/board/insert?error"; } /** * ๊ฒŒ์‹œ๊ธ€ ์ˆ˜์ • ํ™”๋ฉด * @param no * @param model * @return * @throws Exception */ @GetMapping("/update") public String update(@RequestParam("no") int no, Model model) throws Exception { Board board = boardService.select(no); model.addAttribute("board", board); return "/board/update"; } /** * ๊ฒŒ์‹œ๊ธ€ ์ˆ˜์ • ์ฒ˜๋ฆฌ * @param board * @return * @throws Exception */ @PostMapping("/update") public String updatePro(Board board) throws Exception { int result = boardService.update(board); if( result > 0 ) { return "redirect:/board/list"; } int no = board.getNo(); return "redirect:/board/update?no="+ no + "&error"; } /** * ๊ฒŒ์‹œ๊ธ€ ์‚ญ์ œ ์ฒ˜๋ฆฌ * @param no * @return * @throws Exception */ @PostMapping("/delete") public String delete(@RequestParam("no") int no) throws Exception { int result = boardService.delete(no); if( result > 0 ) { return "redirect:/board/list"; } return "redirect:/board/update?no=" + no + "&error"; } }
Java
๋ณต์‚ฌ

View ์ž‘์„ฑ

โ€ข
board
โ—ฆ
list.html
โ—ฆ
insert.html
โ—ฆ
read.html
โ—ฆ
update.html
โ€ข
index.html

index.html

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>๋ฉ”์ธ ํ™”๋ฉด</title> </head> <body> <h1>SpringBoot x MyBatis</h1> <h3>๊ฒŒ์‹œํŒ ํ”„๋กœ์ ํŠธ</h3> <ul> <li>Spring Boot 3.x</li> <li>Thymeleaf</li> <li>MySQL 8.x</li> <li>MyBatis 3.0</li> </ul> <div> <a href="/board/list">๊ฒŒ์‹œํŒ</a> </div> </body> </html>
HTML
๋ณต์‚ฌ
โ€ข
board

list.html

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก</title> </head> <body> <h1>๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก</h1> <a href="/board/insert">๊ธ€์“ฐ๊ธฐ</a> <table border="1"> <tr> <th width="50">๋ฒˆํ˜ธ</th> <th width="300">์ œ๋ชฉ</th> <th width="100">์ž‘์„ฑ์ž</th> <th width="200">๋“ฑ๋ก์ผ์ž</th> <th width="200">์ˆ˜์ •์ผ์ž</th> <th widht="100">์กฐํšŒ์ˆ˜</th> </tr> <th:block th:each="board : ${boardList}"> <tr> <td align="center" th:text="${board.no}"></td> <td> <!-- th:???="|๋ฌธ์ž์—ด+${ํ‘œํ˜„์‹}|" --> <a th:href="|/board/read?no=${board.no}|" th:text="${board.title}"></a> </td> <td align="center" th:text="${board.writer}"></td> <!-- ์œ ํ‹ธ๋ฆฌํ‹ฐ๊ฐ์ฒด.๋ฉ”์†Œ๋“œ() #dates.format( ๋‚ ์งœ๊ฐ์ฒด๋ช…, '๋‚ ์งœํฌ๋งท' ) - #dates.format( board.regDate, 'yyyy-MM-dd HH:mm:ss' ) --> <td align="center"> <span th:text="${ #dates.format( board.createdAt, 'yyyy-MM-dd HH:mm:ss' ) }"></span> </td> <td align="center"> <span th:text="${ #dates.format( board.updatedAt, 'yyyy-MM-dd HH:mm:ss' ) }"></span> </td> <td align="center" th:text="${board.views}"></td> </tr> </th:block> </table> </body> </html>
HTML
๋ณต์‚ฌ

insert.html

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>๊ฒŒ์‹œ๊ธ€ ๋“ฑ๋ก</title> </head> <body> <h1>๊ฒŒ์‹œ๊ธ€ ๋“ฑ๋ก</h1> <form action="/board/insert" method="post"> <input type="text" name="title" id="title"> <input type="text" name="writer" id="writer"> <input type="text" name="content" id="content"> <input type="submit" value="๋“ฑ๋ก"> </form> </body> </html>
HTML
๋ณต์‚ฌ

read.html

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>๊ฒŒ์‹œ๊ธ€ ์กฐํšŒ</title> </head> <body> <h1>๊ฒŒ์‹œ๊ธ€ ์กฐํšŒ</h1> <form action="/board/delete" method="post"> <input type="hidden" name="no" th:value="${board.no}"> <table> <tr> <td>์ œ๋ชฉ</td> <td> <input type="text" name="title" th:value="${board.title}"> </td> </tr> <tr> <td>์ž‘์„ฑ์ž</td> <td> <input type="text" name="writer" th:value="${board.writer}"> </td> </tr> <tr> <td colspan="2"> <textarea name="content" id="content" cols="40" rows="5" th:text="${board.content}"></textarea> </td> </tr> </table> <div> <button type="button" onclick="moveUpdate()">์ˆ˜์ •</button> <button type="button" onclick="moveList()">๋ชฉ๋ก</button> </div> </form> <script> // ๐Ÿ‘ฉโ€๐Ÿ’ป ๋ชจ๋ธ ๊ฐ์ฒด๋ฅผ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐฉ๋ฒ• let no = "[[${board.no}]]" // ์ˆ˜์ • ํ™”๋ฉด ์ด๋™ function moveUpdate() { location.href = '/board/update?no=' + no } // ๋ชฉ๋ก ํ™”๋ฉด ์ด๋™ function moveList() { location.href = '/board/list' } </script> </body> </html>
HTML
๋ณต์‚ฌ

update.html

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>๊ฒŒ์‹œ๊ธ€ ์ˆ˜์ •</title> </head> <body> <h1>๊ฒŒ์‹œ๊ธ€ ์ˆ˜์ •</h1> <form id="form" action="/board/update" method="post"> <input type="hidden" name="no" th:value="${board.no}"> <table> <tr> <td>์ œ๋ชฉ</td> <td> <input type="text" name="title" th:value="${board.title}"> </td> </tr> <tr> <td>์ž‘์„ฑ์ž</td> <td> <input type="text" name="writer" th:value="${board.writer}"> </td> </tr> <tr> <td colspan="2"> <textarea name="content" id="content" cols="40" rows="5" th:text="${board.content}"></textarea> </td> </tr> </table> <div> <button type="submit">์ˆ˜์ •</button> <button type="button" onclick="actionDelete()">์‚ญ์ œ</button> <button type="button" onclick="moveList()">๋ชฉ๋ก</button> </div> </form> <script> let form = document.getElementById('form') // ๐Ÿ‘ฉโ€๐Ÿ’ป ๋ชจ๋ธ ๊ฐ์ฒด๋ฅผ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐฉ๋ฒ• let no = "[[${board.no}]]" // ์ˆ˜์ • ํ™”๋ฉด ์ด๋™ function moveUpdate() { location.href = '/board/update?no=' + no } // ์‚ญ์ œ ์š”์ฒญ function actionDelete() { let check = confirm('์ •๋ง๋กœ ์‚ญ์ œํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?') if( check ) { form.action = '/board/delete' form.submit() } } // ๋ชฉ๋ก ํ™”๋ฉด ์ด๋™ function moveList() { location.href = '/board/list' } </script> </body> </html>
HTML
๋ณต์‚ฌ
๊ธฐ๋Šฅ ๋ช…์„ธ์„œ
โ€ข
๊ฒŒ์‹œ๊ธ€ ๋“ฑ๋ก
โ€ข
๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก ์กฐํšŒ
โ€ข
๊ฒŒ์‹œ๊ธ€ ์กฐํšŒ
โ€ข
๊ฒŒ์‹œ๊ธ€ ์ˆ˜์ •
โ€ข
๊ฒŒ์‹œ๊ธ€ ์‚ญ์ œ

๊ฒŒ์‹œ๊ธ€ ๋“ฑ๋ก

๊ฒŒ์‹œ๊ธ€ ๋“ฑ๋ก ์‹œ, ์‚ฌ์šฉ์ž๊ฐ€ /board/insert.html ์—์„œ ๊ฒŒ์‹œ๊ธ€ ์ •๋ณด (์ œ๋ชฉ, ์ž‘์„ฑ์ž, ๋‚ด์šฉ)๋ฅผ ์ž…๋ ฅํ•˜๊ณ , ์—ฌ๋Ÿฌ ํŒŒ์ผ์„ ์ฒจ๋ถ€ํ•˜์—ฌ ์š”์ฒญํ•œ๋‹ค.
โ€ข
๊ฒŒ์‹œ๊ธ€ ์ •๋ณด ๋“ฑ๋ก
โ€ข
ํŒŒ์ผ ์—…๋กœ๋“œ

๊ฒŒ์‹œ๊ธ€ ์ •๋ณด ๋“ฑ๋ก

โ€ข
Model
โ—ฆ
BoardService.java
โ–ช
insert(Board)
โ—ฆ
BoardServiceImpl.java
โ–ช
insert(Board)
โ€ข
๊ฒŒ์‹œ๊ธ€ ์ •๋ณด ๋“ฑ๋ก
โ—ฆ
BoardMapper ์˜ insert(Board) ํ˜ธ์ถœ
โ€ข
ํŒŒ์ผ ์—…๋กœ๋“œ
โ—ฆ
FileService ์˜ upload(List<Files>) ํ˜ธ์ถœ
โ—ฆ
BoardMapper.java
โ–ช
insert(Board)
โ€ข
BoardMapper.xml ์˜ id=โ€insertโ€ ์ฟผ๋ฆฌ์™€ ์—ฐ๊ฒฐ
โ—ฆ
BoardMapper.xml
โ–ช
<insert id=โ€insertโ€ โ€ฆ >
โ€ข
์ ์šฉ๋œ ๋ฐ์ดํ„ฐ ํ–‰์˜ ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ ( 0 ๋˜๋Š” 1 )
โ€ข
View
โ—ฆ
~/board/insert.html
โ–ช
[POST] ๋ฐฉ์‹์œผ๋กœ FORM ์š”์ฒญ
โ€ข
ํŒŒ๋ผ๋ฏธํ„ฐ
โ—ฆ
์ œ๋ชฉ : title
โ—ฆ
์ž‘์„ฑ์ž : writer
โ—ฆ
๋‚ด์šฉ : content
โ—ฆ
ํŒŒ์ผ : file
โ€ข
Controller
โ—ฆ
BoardController.java
โ–ช
@GetMapping(โ€/board/insertโ€)
โ€ข
์‘๋‹ต
โ—ฆ
/board/insert
โ–ช
@PostMapping(โ€/board/insertโ€)
โ€ข
@RequestBody Board board
โ€ข
BoardService ์˜ insert() ๋ฉ”์†Œ๋“œ ์š”์ฒญ
โ€ข
์‘๋‹ต
โ—ฆ
์š”์ฒญ ์„ฑ๊ณต : (redirect) /board/list
โ—ฆ
์š”์ฒญ ์‹คํŒจ : (redirect) /board/insert?error

๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก ์กฐํšŒ

๊ฒŒ์‹œ๊ธ€ ์˜ ์ „์ฒด ๋ชฉ๋ก์„ ์กฐํšŒํ•ฉ๋‹ˆ๋‹ค.
โ€ข
๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก ์ „์ฒด ์กฐํšŒ

๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก - MVC

โ€ข
Model : BoardService
โ€ข
View : /board/list.html
โ€ข
Controller : BoardController.java

๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก ์กฐํšŒ

โ€ข
Model
โ—ฆ
BoardService.java
โ–ช
list()
โ—ฆ
BoardServiceImpl.java
โ–ช
list()
โ—ฆ
BoardMapper.java
โ–ช
list()
โ€ข
BoardMapper.xml ์˜ id=โ€listโ€ ์ฟผ๋ฆฌ์™€ ์—ฐ๊ฒฐ
โ—ฆ
BoardMapper.xml
โ–ช
<seledct id=โ€listโ€ resultType=โ€Boardโ€ โ€ฆ >
โ€ข
resultType=โ€Boardโ€
โ—ฆ
์กฐํšŒ๋œ board ํ…Œ์ด๋ธ”์„ Board ๊ฐ์ฒด๋กœ ๋งคํ•‘
โ€ข
View
โ—ฆ
~/board/list.html
โ€ข
Controller
โ—ฆ
BoardController.java
โ–ช
@GetMapping(โ€/board/listโ€)
โ€ข
Model boardList
โ€ข
์‘๋‹ต
โ—ฆ
/board/list

๊ฒŒ์‹œ๊ธ€ ์กฐํšŒ

๊ฒŒ์‹œ๊ธ€ ์ •๋ณด ํ•œ ๊ฑด์„ ์กฐํšŒํ•ฉ๋‹ˆ๋‹ค.
โ€ข
๊ฒŒ์‹œ๊ธ€ ์ •๋ณด ์กฐํšŒ
โ€ข
์ฒจ๋ถ€ ํŒŒ์ผ ๋ชฉ๋ก ์กฐํšŒ

๊ฒŒ์‹œ๊ธ€ ์ •๋ณด ์กฐํšŒ

โ€ข
Model
โ—ฆ
BoardService.java
โ–ช
select(no)
โ—ฆ
BoardServiceImpl.java
โ–ช
select(no)
โ—ฆ
BoardMapper.java
โ–ช
select(no)
โ€ข
BoardMapper.xml ์˜ id=โ€selectโ€ ์ฟผ๋ฆฌ์™€ ์—ฐ๊ฒฐ
โ—ฆ
BoardMapper.xml
โ–ช
<seledct id=โ€selectโ€ resultType=โ€Boardโ€ โ€ฆ >
โ€ข
resultType=โ€Boardโ€
โ—ฆ
์กฐํšŒ๋œ board ํ…Œ์ด๋ธ”์„ Board ๊ฐ์ฒด๋กœ ๋งคํ•‘
โ€ข
View
โ—ฆ
~/board/read.html
โ€ข
Controller
โ—ฆ
BoardController.java
โ–ช
@GetMapping(โ€/board/readโ€)
โ€ข
Model board
โ€ข
์‘๋‹ต
โ—ฆ
/board/read

๊ฒŒ์‹œ๊ธ€ ์ˆ˜์ •

๊ฒŒ์‹œ๊ธ€ ์ •๋ณด ํ•œ ๊ฑด์„ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค.
โ€ข
๊ฒŒ์‹œ๊ธ€ ์ •๋ณด ์ˆ˜์ •
โ€ข
ํŒŒ์ผ ์‚ญ์ œ (AJAX)

๊ฒŒ์‹œ๊ธ€ ์ •๋ณด ์ˆ˜์ •

โ€ข
Model
โ—ฆ
BoardService.java
โ–ช
update(board)
โ—ฆ
BoardServiceImpl.java
โ–ช
update(board)
โ—ฆ
BoardMapper.java
โ–ช
update(board)
โ€ข
BoardMapper.xml ์˜ id=โ€updateโ€ ์ฟผ๋ฆฌ์™€ ์—ฐ๊ฒฐ
โ—ฆ
BoardMapper.xml
โ–ช
<update id=โ€updateโ€ โ€ฆ >
โ€ข
์ ์šฉ๋œ ๋ฐ์ดํ„ฐ ํ–‰์˜ ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ ( 0 ๋˜๋Š” 1 )
โ€ข
View
โ—ฆ
~/board/update.html
โ€ข
Controller
โ—ฆ
BoardController.java
โ–ช
@GetMapping(โ€/board/updateโ€)
โ€ข
Model board
โ€ข
์‘๋‹ต
โ—ฆ
/board/update
โ–ช
@PostMapping(โ€/board/updateโ€)
โ€ข
@RequestBody Board board
โ€ข
BoardService ์˜ update() ๋ฉ”์†Œ๋“œ ์š”์ฒญ
โ€ข
์‘๋‹ต
โ—ฆ
์š”์ฒญ ์„ฑ๊ณต : (redirect) /board/list
โ—ฆ
์š”์ฒญ ์‹คํŒจ : (redirect) /board/update?error

๊ฒŒ์‹œ๊ธ€ ์‚ญ์ œ

๊ฒŒ์‹œ๊ธ€ ์ •๋ณด ํ•œ ๊ฑด์„ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.
โ€ข
๊ฒŒ์‹œ๊ธ€ ์‚ญ์ œ
โ€ข
์ฒจ๋ถ€ ํŒŒ์ผ ์‚ญ์ œ

๊ฒŒ์‹œ๊ธ€ ์‚ญ์ œ

โ€ข
Model
โ—ฆ
BoardService.java
โ–ช
delete(no)
โ—ฆ
BoardServiceImpl.java
โ–ช
delete(no)
โ—ฆ
BoardMapper.java
โ–ช
delete(no)
โ€ข
BoardMapper.xml ์˜ id=โ€deleteโ€ ์ฟผ๋ฆฌ์™€ ์—ฐ๊ฒฐ
โ—ฆ
BoardMapper.xml
โ–ช
<delete id=โ€deleteโ€ โ€ฆ >
โ€ข
์ ์šฉ๋œ ๋ฐ์ดํ„ฐ ํ–‰์˜ ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ ( 0 ๋˜๋Š” 1 )
โ€ข
View
โ—ฆ
~/board/update.html ์—์„œ [์‚ญ์ œ] ๋ฒ„ํŠผ์œผ๋กœ ์š”์ฒญ
โ€ข
Controller
โ—ฆ
BoardController.java
โ–ช
@GetMapping
โ€ข
โ–ช
@PostMapping(โ€/board/deleteโ€)
โ€ข
@RequestBody Board board
โ€ข
BoardService ์˜ delete() ๋ฉ”์†Œ๋“œ ์š”์ฒญ
โ€ข
์‘๋‹ต
โ—ฆ
์š”์ฒญ ์„ฑ๊ณต : (redirect) /board/list
โ—ฆ
์š”์ฒญ ์‹คํŒจ : (redirect) /board/update?error