[Mybatis] Spring Boot์ Mybatis๋ฅผ ์ด์ฉํ Paging ์ฒ๋ฆฌ์ ๊ฒ์ ๊ธฐ๋ฅ ๊ตฌํ
2022. 6. 19. 06:29ใBack-End ์์ ์ค/Spring Framework
728x90
๋ฐ์ํ
Git Hub ์ฃผ์ : https://github.com/junyharang-Development-Lab/mybatis-paging-search-test/tree/main
๐ Mybatis๋ฅผ ์ด์ฉํ Paging ์ฒ๋ฆฌ์ ๊ฒ์ ๊ธฐ๋ฅ ๊ตฌํ
"์ด ํฌ์คํ ์ ์ฟ ํก ํํธ๋์ค ํ๋์ ์ผํ์ผ๋ก, ์ด์ ๋ฐ๋ฅธ ์ผ์ ์ก์ ์์๋ฃ๋ฅผ ์ ๊ณต๋ฐ์ต๋๋ค."
๐ฝ ์ด๊ธฐ ๊ตฌ์ฑ
์ต์ด DB์๋ ์์ ๊ฐ์ด study๋ผ๋ DB์์ board๋ผ๋ Table์ ๋ง๋ค์ด์ฃผ๊ณ , ์์ ๋ด์ฉ์ ๋ฃ์ด ์ฃผ์์ด์.
๐ฆ Project ๊ตฌ์ฑ
์ด๋ฒ ์ค์ต์์ ์ฃผ๋ํ๋์ Gradle๊ณผ ํจ๊ป ์๋์ ๊ฐ์ด ์์กด์ฑ์ ๊ตฌ์ฑํด ์ฃผ์์ต๋๋ค.
plugins {
id 'org.springframework.boot' version '2.7.0'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
group = 'com.junyharang.mybatis'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.2.2'
implementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'junit:junit:4.13.2'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
implementation group: 'org.mariadb.jdbc', name: 'mariadb-java-client', version: '2.4.1'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
// Page Helper
// https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper-spring-boot-starter
implementation 'com.github.pagehelper:pagehelper-spring-boot-starter:1.4.2'
// Mybatis Test
// https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter-test
testImplementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter-test:2.2.2'
// SQL query show
implementation 'org.bgee.log4jdbc-log4j2:log4jdbc-log4j2-jdbc4.1:1.16'
}
tasks.named('test') {
useJUnitPlatform()
}
์ด๋ฒ ์ค์ต์์ ์ค์ํ ๋ถ๋ถ์ด ๋ฐ๋ก Page Helper์ธ ๊ฒ์ด์์.
Paging์ฒ๋ฆฌ๋ฅผ ์ํด ํ๋ํ๋ ์์์
์ผ๋ก ๋ง๋ค์ง ์๊ณ , JPA์ Pageable๊ณผ ๊ฐ์ ๊ฐ์ฒด๋ฅผ ์ฐพ์๋ณด๋ ์ค ์์ฃผ ์ข์ ๊ฒ์ ๋ฐ๊ฒฌํ์ฌ ์ค์ตํด๋ณด๊ณ , ๋ด์ฉ์ ์ ๋ฆฌ ํด ๋ด
๋๋ค.
์ฃผ๋ํ๋์ DataBase๋ฅผ Maria DB๋ฅผ ์ด์ฉํ๊ณ ์์ด์!
๐ฝ Controller
๐ฆ MybatisPagingTestController
package com.junyharang.mybatis.mybatispagingtest.controller;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.junyharang.mybatis.mybatispagingtest.CustomBaseResponse;
import com.junyharang.mybatis.mybatispagingtest.model.dto.request.BoardListSearchDTO;
import com.junyharang.mybatis.mybatispagingtest.model.dto.request.BoardWriteRequestDTO;
import com.junyharang.mybatis.mybatispagingtest.model.vo.BoardResponseVO;
import com.junyharang.mybatis.mybatispagingtest.service.MybatisPagingTestServiceImpl;
import lombok.RequiredArgsConstructor;
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.RestController;
์ต์ด Controller๋ฅผ ๋ง๋ค์ด ์ฃผ์๊ณ , ์์ ๊ฐ์ด ๊ธ ๋ฑ๋ก, ๋ชฉ๋ก ์กฐํ API๋ฅผ ๋ง๋ค์ด ์ฃผ์์ด์.
์ด๋ฒ ํฌ์คํ
์์ ์ฃผ์ ์์ ์ Paging ์ฒ๋ฆฌ ๊ธฐ๋ฅ์ ๊ฐ๋ ๋ชฉ๋ก ์กฐํ์ด๊ธฐ ๋๋ฌธ์ ๋ชฉ๋ก ์กฐํ์ ๋ํ ๋ด์ฉ๋ง ์ ๋ฆฌ๋ฅผ ํด ๋ณด๊ฒ ์ต๋๋ค.
41 ~ 45๋ฒ์งธ ์ค์์ Client์๊ฒ ์์ฒญ ๋ฐ์ ๋ด์ฉ ์ค pageNum๊ณผ pageSize์ ๋ํ ๊ฐ์ด ์๋ค๋ฉด 400 Error๋ฅผ ๋ฐํํ๊ฒ ํด ์ฃผ์์ด์.
API URI๋ /api/junyharang/board๋ก ์ค์ ์ ํด ์ฃผ์๊ณ , HTTP Method๋ Get์ผ๋ก ์ค์ ์ ํด์ฃผ์์ด์.
๊ทธ๋ฆฌ๊ณ , ํด๋น Method๋ฅผ ํธ์ถํ ๋๋ BoardListSearchDTO Type์ ๊ฐ์ ๋ฐ๋๋ก ์ค์ ์ด ๋์ด ์์ด์.
๊ทธ๋ฐ ๋ค PageHelper ์์ startPage()๋ฅผ ํธ์ถํ์ฌ Client์ ์์ฒญ ๊ฐ์ฒด๋ฅผ ์ ๋ฌํด ์ฃผ๊ณ ์์ด์.
์ด๋ ๊ฒ ํด ์ฃผ๊ฒ ๋๋ฉด ์์ Page์ ๋ํ ๊ณ์ฐ์ ํด ์ฃผ๊ฒ ๋๋ต๋๋ค.
์ฐ๋ฆฌ๊ฐ ์ฃผ๋ชฉํด์ผ ๋ ๊ณณ์ return์ด์์. PageInfo๋ pagehelper-spring-boot-starter์ ์๋ Class์ธ๋ฐ, PageInfo๋ ์๋์ ๊ฐ์ Filed ๋ณ์๋ฅผ ๊ฐ์ง๊ณ ์์ด์.
// ํ์ฌ ํ์ด์ง
private int pageNum ;
// ํ์ด์ง๋น ์๋
private int pageSize ;
// ํ์ฌ ํ์ด์ง ์
private int size ;
// ํ์ฌ ํ์ด์ง์ ์ฒซ ๋ฒ์งธ ์์๊ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์๋ ์ค ๋ฒํธ
private long startRow ;
// ํ์ฌ ํ์ด์ง์ ๋ง์ง๋ง ์์๊ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์๋ ์ค ๋ฒํธ
private long endRow ;
// ์ ์ฒด ํ์ด์ง ์
private int pages ;
// ์ด์ ํ์ด์ง
private int prePage ;
// ๋ค์ ํ์ด์ง
private int nextPage ;
// ์ฒซ ํ์ด์ง์ธ์ง ์ฌ๋ถ
private boolean isFirstPage = false ;
// ๋ง์ง๋ง ํ์ด์ง์ธ์ง ์ฌ๋ถ
private boolean isLastPage = false ;
// ์ด์ ํ์ด์ง๊ฐ ์๋์ง ์ฌ๋ถ
private boolean hasPreviousPage = false ;
// ๋ค์ ํ์ด์ง๊ฐ ์๋์ง ์ฌ๋ถ
private boolean hasNextPage = false ;
// ๋ด๋น๊ฒ์ด์
ํ์ด์ง ๋ฒํธ
private int navigatePages ;
// ๋ชจ๋ ๋ด๋น๊ฒ์ด์
ํ์ด์ง ๋ฒํธ
private int [ ] navigatepageNums ;
// ๋ด๋น๊ฒ์ด์
๋ฐ์ ์ฒซ ํ์ด์ง
private int navigateFirstPage ;
// ๋ด๋น๊ฒ์ด์
๋ฐ์ ๋ง์ง๋ง ํ์ด์ง
private int navigateLastPage ;
์ด๋ ๊ฒ PageInfo๋ Paging ์ฒ๋ฆฌ์ ๊ด๋ จ๋ ์ ๋ณด์ Paging ์ฒ๋ฆฌ๊ฐ ์๋ฃ๋ Data List๋ฅผ ๋ฐํํด ์ฃผ๊ฒ ๋์ด ์์ด์.
์ด๋ฒ์ BoardListSearchDTO๋ฅผ ํ๋ฒ ๋ง๋๋ฌ ๊ฐ๋ด์!
๐ฝ RequestDTO
๐ฆ BoardListSearchDTO
Client๋ ๋ชฉ๋ก ์กฐํ๋ฅผ ์ํด API์๊ฒ ์์ฒญ์ ๋ณด๋ผ ๋, ํ์ฌ ์ด์ฉ์์ Page ์์น ๋ฒํธ์ ํ Page ๋น ์ถ๋ ฅ๋ ๊ฒ์๊ธ ๊ฐ์๋ฅผ ๋ฌด์กฐ๊ฑด ๋ณด๋ด์ค์ผ ํด์. ์ ๊ทธ๋ผ Exception์ด ํฐ์ง๊ฒ ๋๋ต๋๋ค!
๊ทธ๋ฆฌ๊ณ , ๋ชฉ๋ก ์กฐํ์ ํจ๊ป ๊ฒ์ ๊ธฐ๋ฅ ๊ตฌํ์ ์ํด ๊ฒ์ Type๊ณผ ๊ฒ์์ด๋ฅผ ํจ๊ป ๋ฐ์ ์ ์๋๋ก DTO๋ฅผ ๊ตฌ์ฑํ์ฌ ์ฃผ์์ด์.
Mybatis๋ JPA์ ๋ค๋ฅด๊ฒ ๊ตฌ๋ํ ๋ ์ฐธ์กฐํ ๊ฐ์ฒด์ Getter์ Setter๋ฅผ ๋ชจ๋ ํ์๋ก ํ๊ธฐ ๋๋ฌธ์ @Data๋ฅผ ๋ฃ์ด์ฃผ์์ต๋๋ค.
JPA๋ฅผ ์ด์ฉํ๋ค๋ฉด Entity์ Setter๋ฅผ ๋ฃ์ผ๋ฉด ์๋๋ ๊ฒ์ด์์.
์ด๋ฒ์๋ Service ์ฆ, Businees Logic์ ๋ง๋๋ฌ ๊ฐ๋ณผ๊ฒ์!
๐ฝ Businees Logic
๐ฆ MybatisPagingTestService
์ฃผ๋ํ๋์ SOLID์ OCP (Open/Closed Principle) : ๊ฐ๋ฐฉ - ํ์ ์์น์ ์ค์ํ๊ธฐ ์ํด Interface์ ๊ตฌํ์ฒด๋ฅผ ๋๋์ด ์ฃผ์์ด์.
๊ตฌํ์ฒด์ getPaging()์ ๋ณด๊ฒ ๋๋ฉด Client์๊ฒ ์ ๋ฌ ๋ฐ์ Paging ์ฒ๋ฆฌ์ ํ์ํ ๊ฐ๊ณผ ๊ฒ์ ์ฒ๋ฆฌ์ ํ์ํ ๊ฐ์ ๋ฐ๊ณ , ์ด๋ฅผ Mybatis๋ฅผ ์ด์ฉํด DB ์กฐํ๋ฅผ ์ํด Mapper์ findByPagingAndSearch()๋ฅผ ํธ์ถํ์ฌ ํด๋น ๊ฐ์ฒด๋ฅผ ์ ๋ฌํด ์ฃผ๊ณ , ์กฐํ๋ ์ฌ๋ฌ ์ข
๋ฅ์ ๊ฒฐ๊ณผ๊ฐ์ List๋ก ์ ๋ฌ์ ํ๋๋ฐ, BoardResponseVO Type์ ๋ง๋ ๊ฐ์ ๊ฐ์ ธ์ค๊ธฐ ์ํด Return Type์ ์ง์ ํด ์ฃผ์์ด์.
๐ฝ DataBase Query
๐ฆ MybatisPagingTestMapper
์ด ์น๊ตฌ๋ ์ค์ ๋ก Annotation์ ํตํด Query๋ฅผ ์ ์ด์ค ์๋ ์๋ ๊ณณ์ด๊ณ , ๋ฐ๋ก xml์ ๋ง๋ค์ด ๋์ Query๋ฅผ ๋ง๋ค์ด Mappingํ ์ ์๋ Mapper Class์์.
24๋ฒ์งธ ์ค์ Client์๊ฒ ์จ ๊ฐ์ฒด๋ฅผ ์ ๋ฌ ๋ฐ๊ณ ์๊ณ , Service ๋์ ๋ง์ฐฌ๊ฐ์ง๋ก DB์์ ์กฐํ๋ ๊ฒฐ๊ณผ๊ฐ์ List๋ก ๋ฐํํ๋๋ฐ, BoardResponseVO์ ๋ง๋ ๊ฐ์ ์ ๋ฌ ํด ์ฃผ๊ณ ์์ด์.
๋ฐ์ํ
๐ฆ MybatisPagingTestMapper.xml
์ค์ Query๋ฅผ ์์ฑํ๋ xml File๋ด์ฉ์ด์์.
18๋ฒ์งธ์ค ๋ถํฐ ๋ชฉ๋ก ์กฐํ๋ฅผ ์ํ Query๋ฌธ์ ์์ฑํ ๊ณณ์ธ๋ฐ, board Table์ ๋ชจ๋ ๋ด์ฉ์ ๊ฐ์ ธ์ค๋๋ฐ, ๊ฒ์ Type์ด null์ด ์๋๊ณ , ๊ณต๋ฐฑ์ด ์๋๊ณ , ๊ฒ์ Type์ด title์ธ๋ฐ, ๊ฒ์์ด๊ฐ ์
๋ ฅ์ด ์ ๋์์ ๋ Error๋ฅผ ๋ฐฉ์ง ํ๊ธฐ ์ํด ๋ชจ๋ ๋ด์ฉ์ ๋ฐํํ๋ ค๊ณ ํ์์ด์. ๊ทธ๋์ 26๋ฒ์งธ ์ค์ ๊ฒ์์ด๊ฐ ๋น์ด ์๊ฑฐ๋, ๊ณต๋ฐฑ์ด๋ฉด ๋ชจ๋ ๋ด์ฉ์ ์กฐํํ์ฌ ๋ฐํํ๊ฒ ํด ์ฃผ์๊ณ , ๋น์ด ์์ง ์๋ค๋ฉด 30๋ฒ์งธ ์ค์ ํด๋น๋์ด์ ๊ฒ์์ด์ ํด๋นํ๋ ๋ด์ฉ์ DB์์ ์กฐํํ๋๋ก ๋์ด ์์ด์.
๋ง์ฝ ๊ฒ์ Type์ด contents๋ผ๋ฉด ๋ด์ฉ์ ๊ฒ์ํ๋๋ก ๊ฒ์ ๊ธฐ๋ฅ์ ๊ตฌํํ์์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ , ๋ฐํ Type์ BoardResponseVO ๊ฐ์ฒด๋ก ํด์ฃผ์๊ณ , ๋งค๊ฐ ๋ณ์๋ BoardListSearchDTO๋ก ํด์ฃผ์์ด์.
๊ทธ๋ฐ๋ฐ, ์ฌ๊ธฐ์ ์ฃผ๋ชฉํด์ผ ํ๋ ๋ถ๋ถ์ SQL์ ํตํด Paging ์ฒ๋ฆฌ๋ฅผ ํ์ง ์๋๋ค๋ ๊ฒ์ด์์.
์ฆ, LIMIT Query๋ฌธ์ด ์๋ ๊ฒ์ด ๋ณด์ด์๋์?
์ด๊ฒ์ Page Helper๋ผ๋ ์น๊ตฌ๊ฐ SQL์ ํ์ ๋น๋ฆฌ์ง ์๊ณ , Code ์์์ Paging์ฒ๋ฆฌ๋ฅผ ํ ์ ์๊ฒ ํด์ค๋ค๋ ์ฅ์ ์ ๊ฐ๊ณ ์๋ ๊ฒ์ด์์.
๐ฝ Response DTO
๐ฆ BoardResponseVO
DB์์ ์กฐํ๊ฐ ๋๋๋ฉด ์ VO ๊ฐ์ฒด์ ๋ง๊ฒ id, title, contents๋ฅผ ๋ฐํํ๋๋ก VO๋ฅผ ๊ตฌ์ฑํด ์ฃผ์์ต๋๋ค.
๐ฝ ์ ์ ์๋ ๊ฒ์ฌ
๋จผ์ POSTMAN์ ํตํด ํ์ฌ ์ด์ฉ์ ์์น Page๋ฅผ 1 Page(pageNum = 1)๋ก ์ฃผ๊ณ , ํ Page ๋น ์ถ๋ ฅ๋ ๊ฒ์๊ธ ๊ฐ์๋ฅผ 10(pageSize)๋ก ์ค์ ์ ํด ์ฃผ์์ด์.
{
"errorCode": 0,
"title": "",
"message": "",
"data": {
"total": 7,
"list": [
{
"id": 1,
"title": "์ ๋ชฉ ์
๋๋ค!",
"contents": "๋ด์ฉ ์
๋๋ค!"
},
{
"id": 2,
"title": "ํ์ด์ผ!",
"contents": "์ฃผ๋ํ๋ ์
๋๋ค!"
},
{
"id": 3,
"title": "์ฝ๋ฉ์ ์ฌ๋ฐ์ด์!",
"contents": "๋๋ ์ฌ๋ฐ์ด์!!"
},
{
"id": 4,
"title": "Full Stack!",
"contents": "Front๋ ์ด์ฌํ!"
},
{
"id": 5,
"title": "JAVA ๋ง์ธ!",
"contents": "JAVA๊ฐ ์ ์ผ ํธํด์!"
},
{
"id": 6,
"title": "Spring์ด ์ข์!",
"contents": "๋๋๋๋!"
},
{
"id": 7,
"title": "mariadb ์ต๊ณ !!",
"contents": "์ข์์!"
}
],
"pageNum": 1,
"pageSize": 10,
"size": 7,
"startRow": 1,
"endRow": 7,
"pages": 1,
"prePage": 0,
"nextPage": 0,
"isFirstPage": true,
"isLastPage": true,
"hasPreviousPage": false,
"hasNextPage": false,
"navigatePages": 8,
"navigatepageNums": [
1
],
"navigateFirstPage": 1,
"navigateLastPage": 1
},
"success": true
}
์ฐธ๊ณ ๋ก ์ฃผ๋ํ๋์ CustomBaseResponse๋ผ๋ ์๋ต ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด ์ฃผ์์ด์.
์ด์ ๋ํ ๋ด์ฉ์ ์ฃผ๋ํ๋ Git Hub์ ์ฐธ๊ณ ํด ์ฃผ์๊ณ , ์ด ์ค์ ๋ค์ ๋ฐ๋ผ ์์ ๊ฐ์ด ๋ฐํ๋๋ ๊ฒฐ๊ณผ๊ฐ์ด ์กฐ๊ธ์ ๋ค๋ฅผ ์ ์์ด์.
์ด๋ฒ์๋ ์ด์ฉ์๊ฐ 1 Page์ ์๊ณ , ์ด 5๊ฐ์ ๊ฒ์๊ธ์ ๊ฐ์ ธ์ค๋๋ก ํด ์ฃผ์์ด์.
{
"errorCode": 0,
"title": "",
"message": "",
"data": {
"total": 7,
"list": [
{
"id": 1,
"title": "์ ๋ชฉ ์
๋๋ค!",
"contents": "๋ด์ฉ ์
๋๋ค!"
},
{
"id": 2,
"title": "ํ์ด์ผ!",
"contents": "์ฃผ๋ํ๋ ์
๋๋ค!"
},
{
"id": 3,
"title": "์ฝ๋ฉ์ ์ฌ๋ฐ์ด์!",
"contents": "๋๋ ์ฌ๋ฐ์ด์!!"
},
{
"id": 4,
"title": "Full Stack!",
"contents": "Front๋ ์ด์ฌํ!"
},
{
"id": 5,
"title": "JAVA ๋ง์ธ!",
"contents": "JAVA๊ฐ ์ ์ผ ํธํด์!"
}
],
"pageNum": 1,
"pageSize": 5,
"size": 5,
"startRow": 1,
"endRow": 5,
"pages": 2,
"prePage": 0,
"nextPage": 2,
"isFirstPage": true,
"isLastPage": false,
"hasPreviousPage": false,
"hasNextPage": true,
"navigatePages": 8,
"navigatepageNums": [
1,
2
],
"navigateFirstPage": 1,
"navigateLastPage": 2
},
"success": true
}
์ด๋ฒ์๋ ์ด์ฉ์๊ฐ 2 Page์ ์๊ณ , 5๊ฐ์ ๊ฒ์๊ธ์ ๊ฐ์ ธ์ค๋๋ก ํด ์ฃผ์์ด์.
{
"errorCode": 0,
"title": "",
"message": "",
"data": {
"total": 7,
"list": [
{
"id": 6,
"title": "Spring์ด ์ข์!",
"contents": "๋๋๋๋!"
},
{
"id": 7,
"title": "mariadb ์ต๊ณ !!",
"contents": "์ข์์!"
}
],
"pageNum": 2,
"pageSize": 5,
"size": 2,
"startRow": 6,
"endRow": 7,
"pages": 2,
"prePage": 1,
"nextPage": 0,
"isFirstPage": false,
"isLastPage": true,
"hasPreviousPage": true,
"hasNextPage": false,
"navigatePages": 8,
"navigatepageNums": [
1,
2
],
"navigateFirstPage": 1,
"navigateLastPage": 2
},
"success": true
}
Controller์์ Client๊ฐ pageNum์ด๋, pageSize๋ฅผ ๋ณด๋ด์ง ์์๋ค๋ฉด 400 Error๊ฐ ํฐ์ง๋๋ก ํด ์ฃผ์์ด์.
์ด ๋ถ๋ถ์ ๋ํด ํ๋ฒ Test ํด ๋ณผ๊ฒ์.
๋จผ์ pageNum์ ๊ฐ์ด ๋ค์ด์ค์ง ์์์ ๋ ์์ ๊ฐ์ด 400 Error๊ฐ ํฐ์ง๋ ๊ฒ์ ํ์ธํ ์ ์์ด์.
๋ง์ฐฌ๊ฐ์ง๋ก pageSize๋ ๋ค์ด์ค์ง ์๋๋ค๋ฉด 400 Error๊ฐ ๋ฐํ๋๋๋ก ๋์ด ์์ต๋๋ค.
์ด๋ฒ์ ๊ฒ์ ๊ธฐ๋ฅ์ด ์ ๋๋ก ๊ตฌํ ๋๋์ง ํ๋ฒ ํ์ธ ํด ๋ณผ๊ฒ์.
์ฌ๊ธฐ์ ์ ๋ชฉ์ด JAVA ๋ง์ธ๋ผ๋ ๋ด์ฉ์ ๊ฒ์ํด ๋ณผ๊ฒ์.
JAVA๋ผ๋ ๊ฐ๋ง ๋ฃ์ด์ ๋ค์ ๊ฒ์์ ํด ๋ณผ๊น์?
์ด๋ ๊ฒ JAVA๋ง ๋ฃ์๋๋ฐ๋ JAVA ๋ง์ธ๊ฐ ๊ฒ์๋๋ ์ด์ ๋ SQL์ ์ ์ XML์ CONCAT('%', #{~~}, '%')๋ฅผ ๋ฃ์ด์ฃผ์๊ธฐ ๋๋ฌธ์ธ๋ฐ, ์ด ๊ฒ์ ์,๋ค์ ์ค๊ฐ ๋ด์ฉ์ ํฌํจํ๋ ๋ชจ๋ ๋ด์ฉ์ ๊ฐ์ ธ์ค๋ผ๋ ์๋ฏธ์์.
"์ด ํฌ์คํ ์ ์ฟ ํก ํํธ๋์ค ํ๋์ ์ผํ์ผ๋ก, ์ด์ ๋ฐ๋ฅธ ์ผ์ ์ก์ ์์๋ฃ๋ฅผ ์ ๊ณต๋ฐ์ต๋๋ค."
728x90
๋ฐ์ํ
'Back-End ์์ ์ค > Spring Framework' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Spring Boot] Spring Security Basic - ๊ธฐ๋ณธ API ๋ฐ Filter ์ดํดํธ (0) | 2022.08.10 |
---|---|
[SpringBoot][MyBatis] Logging(Show SQL Query) (0) | 2022.06.19 |
[Spring] Spring์ด๋? (0) | 2022.04.07 |
[Spring] Spring Security - Method Security (0) | 2022.03.30 |
[Spring] Spring Security ์ธ์ฆ ์ ์ฐจ Interface | UserDetails์ UserDetailsService (0) | 2022.03.29 |