헤르메스 LIFE

[JPA] 정렬 Sort 본문

Spring Boot Framework

[JPA] 정렬 Sort

헤르메스의날개 2023. 3. 21. 23:57
728x90

요즘 JPA를 공부하고 있습니다. MyBatis 만 하다가, 개인적으로 공부를 진행하고 있습니다. 하다보니 막히고, 이해가 안되는 부분이 많네요. 그때마다 검색과 삽질로 해결하고 있습니다. 여기 그 삽질의 자취를 남겨봅니다.


개발환경

Spring Boot 2.7.9

H2 2.1.214

p6spy 1.8.1

slf4j 1.7.36

swagger2 2.6.1

lombok

devtools

postgresql


Spring Domain Class 중 org.springframework.data.domain.Sort Class가 있습니다.

Spring Data JPA를 사용할 경우 Pageable 인터페이스와 Sort 정보를 파라메터로 전달할 수 있습니다.

Sort 객체를 생성하는 방법

/* Sort.by(정렬방법, "컬럼명") */
Sort.by(Sort.Direction.ASC, "sortSeq")

/* Sort.by("컬럼명").ascending(), Sort.by("컬럼명").descending() */
Sort s1 = Sort.by("sortSeq").ascending();
Sort s2 = Sort.by("cd").descending();
Sort sortAll = s1.and(s2);

/* 특수한 경우 */
JpaSort.unsafe("LENGTH(cdNm)")

CodeDController.java

package octopus.backend.v1.controller;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import octopus.backend.service.ResponseService;
import octopus.backend.v1.dto.TCodeDDto;
import octopus.backend.v1.service.CodeDService;
import octopus.entity.CommonResult;
import octopus.entity.TCodeD;
import octopus.model.ListResult;
import octopus.model.SearchCriteria;
import octopus.model.SingleResult;

@Slf4j
@Api(tags = { "1. Detail Code" })
@RequiredArgsConstructor
@RestController
@RequestMapping("/v1/detail")
public class CodeDController {

	private final MessageSourceAccessor messageSourceAccessor;
	private final CodeDService codeDService;
	private final ResponseService responseService;
    
    @ApiOperation(value = "대분류 코드에 속한 공통코드 검색", notes = "대분류 코드에 속한 공통코드를 조회합니다.")
	@GetMapping("/code/{pCd}")
	public ListResult<TCodeDDto> findBypCd(@ApiParam(value = "대분류코드", required = true) @PathVariable String pCd) {
		List<TCodeDDto> list = codeDService.findBypCd(pCd);

		log.debug("list :: {}", list);

		return responseService.getListResult(list);
	}
}

CodeDService.java

package octopus.backend.v1.service;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import org.modelmapper.ModelMapper;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import octopus.backend.v1.dao.CodeDRepository;
import octopus.backend.v1.dto.TCodeDDto;
import octopus.entity.TCodeD;

@Service
//@AllArgsConstructor
@RequiredArgsConstructor
@Slf4j
public class CodeDService {
	// @AllArgsConstructor를 사용하는 경우
	// private CodeDRepository codeDRepository;

	private final CodeDRepository codeDRepository;
	private final ModelMapper modelMapper;
    
	@Transactional(readOnly = true)
	public List<TCodeDDto> findBypCd(String pCd) {
		List<TCodeDDto> list = codeDRepository.findBypCd(pCd, Sort.by(Sort.Direction.ASC, "sortSeq")).stream().map(data -> TCodeDDto.getDto(data))
				.collect(Collectors.toList());

		log.debug("list :: {}", list);

		return list;
	}
}

CodeDRepository.java

package octopus.backend.v1.dao;

import java.util.List;
import java.util.Optional;

import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import octopus.entity.TCodeD;

// @Repository : JpaRepository를 사용하면 @Repository를 사용하지 않아도 됨.
public interface CodeDRepository extends JpaRepository<TCodeD, String> {
    List<TCodeD> findBypCd(String pCd, Sort sort);
    
    Optional<TCodeD> findBypCdAndCd(String pCd, String cd);
    
    //
    // clearAutomatically : Persistence Context
    @Modifying(clearAutomatically = true)
    @Query("update TCodeD m set m.cdNm = :cdNm where m.pCd = :pCd and m.cd = :cd")
    int updateTCodeD(@Param(value = "pCd") String pCd, @Param(value = "cd") String cd,
            @Param(value = "cdNm") String cdNm);
}
728x90