다이나믹 SQL
상황에 따라서 조건을 다르게 주고싶을때 사용한다.
♠ \ 참조 / ♠
( 1 )
< if test = " ">
xml 파일에서
if 문 활용 가능
( 2 )
롬복 , 로그백 사용
https://tinylittlelife.tistory.com/209
< 예제 >
HTML에서 검색창 SELECT BOX를 열어서
이름 또는 부서위치로 검색을 하고 싶을때 한번에 하는 법
basetime
https://tinylittlelife.tistory.com/212
페이징 처리 vo
https://tinylittlelife.tistory.com/220
Dept vo
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Dept extends BaseTimeEntity{
// DNO NUMBER NOT NULL PRIMARY KEY,
// DNAME VARCHAR2(255),
// LOC VARCHAR2(255),
// INSERT_TIME VARCHAR2(255),
// UPDATE_TIME VARCHAR2(255) <- extends
private Integer dno;
private String dname;
private String loc;
}
DAO (DB CONNECTION)
/**
* 다이나믹 SQL
*/
public List<Dept> findByDynamicContaining(
@Param("dname") String dname,
@Param("loc") String loc,
PageReq pageReq
);
/**
* 다이나믹 SQL 작성 전체 카운트 예제
*/
long countByDinamic(String dname , @Param("loc") String loc);
resources/mappers/dept.xml
( #2 는 페이징처리를 위함 )
( WHERE 1=1 은 AND 에 대해 가독성을 높일려고 그냥 사용 )
<!-- TODO: Dynamic func # 1 -->
<select id="findByDynamicContaining" parameterType="PageReq" resultType="Dept">
SELECT DNO
, DNAME
, LOC
<include refid="common.selectCol"/>
FROM TB_DEPT
WHERE 1=1
-- dname 이 빈문자열이 아니면
<if test="dname != '' ">
AND DNAME LIKE '%' || #{dname} || '%'
</if>
-- loc 이 빈문자열이 아니면
<if test="loc != '' ">
AND LOC LIKE '%' || #{loc} ||'%'
</if>
OFFSET #{pageReq.page} * #{pageReq.size} ROWS FETCH FIRST #{pageReq.size} ROWS ONLY
</select>
<!-- TODO :Dynamic func # 2 -->
<select id="countByDinamic" parameterType="String" resultType="long">
SELECT COUNT(dno)
FROM TB_DEPT
WHERE 1=1
-- dname 이 빈문자열이 아니면
<if test="dname != '' ">
AND DNAME LIKE '%' || #{dname} || '%'
</if>
-- loc 이 빈문자열이 아니면
<if test="loc != '' ">
AND LOC LIKE '%' || #{loc} ||'%'
</if>
</select>
Service
/**
* TODO : Dynamic SQL
*/
public PageRes<Dept> findByDynamicContaining(String dname , String loc , PageReq pageReq) {
// TODO : Dynamic SQL 조회 (like 됨)
dname = dname.toUpperCase();
loc = loc.toUpperCase();
List<Dept> list = deptDao.findByDynamicContaining(dname,loc,pageReq);
// TODO: 페이징 처리 로직
// 1) 총 테이블 개수
long totalCount = deptDao.countByDinamic(dname,loc);
// TODO : 생성자 페이지 결과 객체 (PageRes)
PageRes pageRes = new PageRes(
list, // 검색 결과(부서) 배열
pageReq.getPage(), // 현재 페이지 번호
totalCount, // 총 테이블 건수
pageReq.getSize());// 1페이지당 개수
return pageRes;
}
Controller
/**
* Dynamic SQL 조회
*/
@GetMapping("/dept/dynamic")
public ResponseEntity<Object> getDeptDynamic(
@RequestParam(defaultValue = "") String dname
, @RequestParam(defaultValue = "") String loc
, @RequestParam(defaultValue = "0") int page
, @RequestParam(defaultValue = "3") int size
) {
try {
PageReq pageReq = new PageReq(page, size);
PageRes<Dept> pageRes = deptService.findByDynamicContaining(dname, loc,pageReq);
// TODO: React 로 정보 전달 (부서배열 , 페이징정보)
Map<String, Object> map = new HashMap();
map.put("dept", pageRes.getContent()); // 부서 배열
map.put("currentPage", pageRes.getNumber()); // 현재페이지 번호
map.put("totalItems", pageRes.getTotalElements()); // 전체테이블 건수
map.put("totalPages", pageRes.getTotalPages()); // 전체 페이지개수
if(pageRes.isEmpty() == false) {
// TODO : 조회 성공
return new ResponseEntity<>(map , HttpStatus.OK);
} else {
// TODO: 조회 실패
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
} catch (Exception e) {
log.debug(e.getMessage());
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
'SpringBoot > code' 카테고리의 다른 글
WebSocket 을 사용해보자 - 2. Stomp 프론트 부분 (1) | 2024.01.04 |
---|---|
Springboot - OAuth2.0 Google API , kakao API , Naver API 로그인 (0) | 2023.12.14 |
SpringBoot - SSR에서 페이징 처리에 필요한 객체 PageReq , PageRes (0) | 2023.10.12 |
SpringBoot - model / common package (0) | 2023.10.12 |
SpringBoot - Optional (클래스) 예제 (1) | 2023.10.11 |