Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.softeer5.uniro_backend.univ.controller;

import com.softeer5.uniro_backend.univ.dto.SearchUnivResDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestParam;

@Tag(name = "대학교 관련 Api")
public interface UnivAPI {

@Operation(summary = "대학 이름 검색")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "대학 이름 검색 성공"),
@ApiResponse(responseCode = "400", description = "EXCEPTION(임시)", content = @Content),
})
ResponseEntity<SearchUnivResDTO> searchUniv(
@RequestParam(value = "name", required = false) String name,
@RequestParam(value = "cursor-id", required = false) Long cursorId,
@RequestParam(value = "page-size", required = false) Integer pageSize
);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.softeer5.uniro_backend.univ.controller;

import com.softeer5.uniro_backend.univ.dto.SearchUnivResDTO;
import com.softeer5.uniro_backend.univ.service.UnivService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
public class UnivController implements UnivAPI{
private final UnivService univService;

@Override
@GetMapping("/univ/search")
public ResponseEntity<SearchUnivResDTO> searchUniv(
@RequestParam(value = "name", required = false) String name,
@RequestParam(value = "cursor-id", required = false) Long cursorId,
@RequestParam(value = "page-size", required = false, defaultValue = "6") Integer pageSize){
SearchUnivResDTO searchResult = univService.searchUniv(name, cursorId, pageSize);
return ResponseEntity.ok().body(searchResult);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.softeer5.uniro_backend.univ.dto;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

import java.util.List;

@Schema(name = "SearchUnivResDTO", description = "대학 검색 DTO")
@Getter
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public class SearchUnivResDTO {

@Schema(description = "실제 data", example = "")
private final List<UnivInfo> data;

@Schema(description = "다음 페이지 요청을 위한 커서 ID (마지막 데이터의 ID)", example = "103")
private final Long nextCursor;

@Schema(description = "다음 페이지가 존재하는지 여부", example = "true")
private final boolean hasNext;

public static SearchUnivResDTO of(List<UnivInfo> univInfos, Long nextCursor, boolean hasNext) {
return new SearchUnivResDTO(univInfos,nextCursor,hasNext);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.softeer5.uniro_backend.univ.dto;

import com.querydsl.core.annotations.QueryProjection;
import lombok.Getter;

@Getter
public class UnivInfo {
private Long id;
private String name;
private String imageUrl;

@QueryProjection
public UnivInfo(Long id, String name, String imageUrl) {
this.id = id;
this.name = name;
this.imageUrl = imageUrl;
}

}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.softeer5.uniro_backend.univ;
package com.softeer5.uniro_backend.univ.entity;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.softeer5.uniro_backend.univ.repository;

import com.softeer5.uniro_backend.common.CursorPage;
import com.softeer5.uniro_backend.univ.dto.UnivInfo;

import java.util.List;

public interface UnivCustomRepository {
CursorPage<List<UnivInfo>> searchUniv(String name, Long cursorId, Integer pageSize);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.softeer5.uniro_backend.univ.repository;

import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.softeer5.uniro_backend.common.CursorPage;
import com.softeer5.uniro_backend.univ.dto.QUnivInfo;
import com.softeer5.uniro_backend.univ.dto.UnivInfo;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

import java.util.List;

import static com.softeer5.uniro_backend.univ.entity.QUniv.univ;

@Repository
@RequiredArgsConstructor
public class UnivCustomRepositoryImpl implements UnivCustomRepository {
private final JPAQueryFactory queryFactory;

@Override
public CursorPage<List<UnivInfo>> searchUniv(String name, Long cursorId, Integer pageSize) {

List<UnivInfo> universities = queryFactory
.select(new QUnivInfo(univ.id, univ.name, univ.imageUrl))
.from(univ)
.where(
nameCondition(name),
cursorIdCondition(cursorId)
)
.orderBy(univ.id.asc())
.limit(pageSize + 1)
.fetch();

boolean hasNext = universities.size() > pageSize;
Long nextCursor = hasNext ? universities.get(pageSize).getId() : null;

if (hasNext) {
universities.remove(universities.size() - 1);
}

return new CursorPage<>(universities, nextCursor, hasNext);
}

private BooleanExpression cursorIdCondition(Long cursorId) {
return cursorId == null ? null : univ.id.gt(cursorId);
}
private BooleanExpression nameCondition(String name) {
return name == null || name.isEmpty() ? null : univ.name.containsIgnoreCase(name);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.softeer5.uniro_backend.univ.repository;

import com.softeer5.uniro_backend.univ.entity.Univ;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UnivRepository extends JpaRepository<Univ, Long>, UnivCustomRepository {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.softeer5.uniro_backend.univ.service;

import com.softeer5.uniro_backend.common.CursorPage;
import com.softeer5.uniro_backend.univ.dto.SearchUnivResDTO;
import com.softeer5.uniro_backend.univ.dto.UnivInfo;
import com.softeer5.uniro_backend.univ.repository.UnivRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@Transactional
@RequiredArgsConstructor
public class UnivService {
private final UnivRepository univRepository;

public SearchUnivResDTO searchUniv(String name, Long cursorId, Integer pageSize) {
CursorPage<List<UnivInfo>> universities = univRepository.searchUniv(name,cursorId,pageSize);
return SearchUnivResDTO.of(universities.getData(),universities.getNextCursor(), universities.isHasNext());
}
}