#05 중요 로직들 - 1 (feat. Paging)

김대진·2023년 3월 20일
0

Sekkison Project

목록 보기
6/22
post-thumbnail

이제 API 서버를 만드는 데 있어서 중요하다고 생각하는 로직들을 엔티티별로 분류하여 적어보도록 하겠다.

Appoint

약속만들기 로직

먼저, 약속 엔티티에 대해 설명하겠다. 컨트롤러에는 약속을 만드는 로직이 있는데, 프론트에서 약속에 대한 정보를 받아 AppointRepositorysave한다.
이 때, 날짜와 시간을 yyyy.mm.dd, HH:mm:ss 형식 문자열로 받게 되는데, 이것을 LocalDateTime 타입으로 바꿀 필요가 있었다.

AppointController

@ResponseBody
@PostMapping("/{user_id}")
// 약속 만들기
public ResponseForm create(
		@PathVariable("user_id") Long user_id,
		Appoint appoint,
		Integer typeInteger,
		String date,
		String time) {
	return appointService.createAppoint(user_id, appoint, typeInteger, date, time);
}

날짜와 시간을 String 으로 받아 Service에 넘겨주었다.

AppointService

public ResponseForm createAppoint(Long user_id, Appoint appoint, Integer typeInteger,
                                      String date, String time) {
	ResponseForm res = new ResponseForm();

	//.. 유효성 검사 및 값 세팅 로직

	// dday 세팅
	appoint.setDday(makeDateTime(date, time));

	// appoint 저장
	appoint = appointRepository.save(appoint);

	//.. myAppoint 세팅 및 인원 세팅 로직

	return res.setSuccess(appoint.getId());
}
private LocalDateTime makeDateTime(String date, String time) {
	String[] dates = date.split("\\.");
	String[] times = time.split(":");
	Integer y = Integer.parseInt(dates[0]);
	Integer m = Integer.parseInt(dates[1]);
	Integer d = Integer.parseInt(dates[2]);
	Integer hh = Integer.parseInt(times[0]);
	Integer mm = Integer.parseInt(times[1]);
	return LocalDateTime.of(y, m, d, hh, mm, 00);
}

makeDateTime 함수로 String으로 받은 datetimesplit을 사용해 나누고 LocalDateTime을 만들어 내었다.
(기호 .을 기준으로 split할 때, . 대신 \\.을 사용해야 한다.)

참고로, Appoint엔티티에는 type이라는 Column이 있는데, 이것은 Enum 타입이다.

C

public class C {
    public enum appointType {
        FTF, NFTF, SOLO
    }
}

AppointService

// type 세팅
C.appointType type;
if (typeInteger == 0) type = C.appointType.FTF;
else if (typeInteger == 1) type = C.appointType.NFTF;
else type = C.appointType.SOLO;
appoint.setType(type);

Enum 타입 변수를 통해 FTF(만남), NFTF(온라인), SOLO(나만의)
약속을 세 가지 타입으로 구분하였다.

( 자바의 Enumint타입으로 형변환하려고 시도해 보았으나, JavaCC++과는 다르게 int로 형변환이 되지 않는다. )

약속 검색하기

처음 프로젝트를 기획했을떄는 친구끼리만 약속을 할 수 있게 하려 했지만, 친구가 아니어도 방을 검색해서 참여할 수 있는 플랫폼적인 성격을 갖도록 바꾸어 약속 검색 기능을 추가하였다.

그리고 효율적으로 데이터를 보내기 위해 페이징을 적용하였다.

AppointController

	@ResponseBody
    @GetMapping("/search/{is_public}/{is_recruit}/{is_ftf}/{page}")
    // 약속 검색
    public ResponseForm searchAppointList(
            String search,
            @PathVariable("is_public") Integer is_public,
            @PathVariable("is_recruit") Integer is_recruit,
            @PathVariable("is_ftf") Integer is_ftf,
            @PathVariable("page") Integer page) {
        return appointService.getSearchAppointList(search, is_public, is_recruit, is_ftf, page);
    }

공개방여부, 모집중여부, 만남여부, 검색어, 페이지를 인자로 받아 해당하는 페이지의 검색결과를 리턴하도록 만들었다.

AppointService

public ResponseForm getSearchAppointList(
		String search, 
		Integer isPublic, 
		Integer isRecruit, 
		Integer isFtf, 
		Integer page) {
	ResponseForm res = new ResponseForm();

	//...카테고리 세팅

	// 페이징 설정
	int pageSize = 10;
	Pageable pageable = PageRequest.of(page, pageSize, Sort.by("id").descending());

	// 조건에 맞는 appoint리스트 검색
	Page<Appoint> appointList =
   		appointRepository.findByIsPublicAndIsRecruitAndTypeAndTitleContainsAndDdayAfter(
                        is_public, is_recruit, is_ftf, search, LocalDateTime.now() ,pageable);

	//...Null 체크

	//...방장 정보 세팅

	return res.setSuccess(appointList.getContent());
}

JPA Repository 함수로 작성하여 불가피하게 함수명이 길어졌지만,
PageRequest.of(page, pageSize, Sort.by("id").descending());으로 Pageable 객체를 만들어 페이징을 적용시킬 수 있었다.

( Paging을 적용시킬 때에는 객체 타입이 Page<> 타입이어야 한다. )

참고로, Appoint객체를 DTO의 역할도 동시에 수행할 수 있도록 memo 변수에 방장의 idname을 담았다.

AppointService

// 방장 이름 세팅
for(Appoint a : appointList.getContent()) {
	List<MyAppoint> ma = myAppointRepository.findByAppointIdAndIsMaster(a.getId(), true);

	if (ma == null || ma.size() == 0) { a.setMemo("0&unknown"); continue; }

	User u = userRepository.findById(ma.get(0).getUserId()).orElse(null);
	if (u == null) { a.setMemo("0&unknown"); continue; }

	a.setMemo(u.getId() + "&" + u.getName());
}

Appoint 엔티티에서 중요하다 싶은 로직은 대부분 설명한 듯 하다. 기본적인 CRUD 로직은 제외하였다.

profile
만재 개발자

0개의 댓글