diff --git "a/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/build.gradle" "b/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/build.gradle" index d55c8a7..b9027fe 100644 --- "a/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/build.gradle" +++ "b/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/build.gradle" @@ -1,7 +1,14 @@ +buildscript { + ext { + queryDslVersion = "5.0.0" + } +} + plugins { id 'java' id 'org.springframework.boot' version '2.7.11' id 'io.spring.dependency-management' version '1.0.15.RELEASE' + id "com.ewerk.gradle.plugins.querydsl" version "1.0.10" //querydsl } group = 'com.example' @@ -26,6 +33,9 @@ dependencies { implementation "io.swagger:swagger-models:1.5.21" implementation group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.9.2' + implementation "com.querydsl:querydsl-jpa:${queryDslVersion}" + implementation "com.querydsl:querydsl-apt:${queryDslVersion}" + implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' @@ -39,3 +49,37 @@ dependencies { tasks.named('test') { useJUnitPlatform() } + +//querydsl 사용 경로 +def querydslDir = "$buildDir/generated/querydsl" + +//querydsl 사용 설정 +querydsl { + jpa = true + querydslSourcesDir = querydslDir +} + +// build 시 사용할 sourceSet +sourceSets { + main.java.srcDir querydslDir +} + +// compileClasspath와 annotationProcessor 상속 +configurations { + compileOnly { + extendsFrom annotationProcessor + } + querydsl.extendsFrom compileClasspath +} + +//feature/improve-all +// querydsl 컴파일 시 사용할 옵션. +compileQuerydsl { + options.annotationProcessorPath = configurations.querydsl +} + +//feature/improve-all +// QType 정리 +clean { + delete file(querydslDir) +} diff --git "a/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Config/QuerydslConfiguration.java" "b/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Config/QuerydslConfiguration.java" new file mode 100644 index 0000000..e787745 --- /dev/null +++ "b/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Config/QuerydslConfiguration.java" @@ -0,0 +1,21 @@ +package com.example.umc_board.Config; + +import com.querydsl.jpa.impl.JPAQueryFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import javax.persistence.Entity; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; + +@Configuration +public class QuerydslConfiguration { + + @PersistenceContext + private EntityManager entityManager; + + @Bean + public JPAQueryFactory jpaQueryFactory(){ + return new JPAQueryFactory(entityManager); + } +} diff --git "a/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Controller/BoardController.java" "b/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Controller/BoardController.java" index d00e57c..8850ad4 100644 --- "a/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Controller/BoardController.java" +++ "b/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Controller/BoardController.java" @@ -27,6 +27,7 @@ import java.net.URISyntaxException; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; +import java.util.List; @RestController @RequiredArgsConstructor @@ -48,6 +49,12 @@ public ResponseEntity> list(@PageableDefault Pageable pageable, Mode return ResponseEntity.ok(boardService.findBoardList(pageable)); } + @GetMapping("/search") + @ApiOperation(value = "게시물 검색 API") + public ResponseEntity> getSearchBoards(@RequestParam(value = "search") String search){ + return ResponseEntity.ok(boardService.findBoardByTitle(search)); + } + @GetMapping("/{id}") @ApiOperation(value = "게시물 조회 API") @ApiImplicitParam(name = "id", value = "게시물 id") diff --git "a/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Controller/UserController.java" "b/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Controller/UserController.java" index 42572e0..18f6124 100644 --- "a/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Controller/UserController.java" +++ "b/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Controller/UserController.java" @@ -30,6 +30,6 @@ public ResponseEntity join(@RequestBody UserRequestDto requestD @PostMapping("/login") @ApiOperation(value = "로그인 API") public ResponseEntity login(@RequestBody LoginRequestDto requestDto){ - return ResponseEntity.ok(UserResponseDto.of(userService.findUser(requestDto.getEmail(), requestDto.getPassword()))); + return ResponseEntity.ok(UserResponseDto.of(userService.findByEmail(requestDto.getEmail(), requestDto.getPassword()))); } } diff --git "a/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Dto/BoardRequestDto.java" "b/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Dto/BoardRequestDto.java" index a913c55..abdd87b 100644 --- "a/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Dto/BoardRequestDto.java" +++ "b/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Dto/BoardRequestDto.java" @@ -1,17 +1,10 @@ package com.example.umc_board.Dto; -import com.example.umc_board.Entity.Board; -import com.example.umc_board.Entity.Category; -import com.example.umc_board.Entity.KakaoPlace; -import com.example.umc_board.Entity.User; import io.swagger.annotations.ApiModelProperty; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; import java.util.List; @Getter @@ -24,46 +17,22 @@ public class BoardRequestDto { @ApiModelProperty(example = "test content") private String content; - @ApiModelProperty(example = "커뮤니티") + @ApiModelProperty(example = "community") private String category; - @ApiModelProperty(example = "tester") - private User user; + @ApiModelProperty(example = "test@test.com") + private String email; - @ApiModelProperty(example = "[[\"20522613\", \"거북당\", \"http://place.map.kakao.com/20522613\"]]") - private List> placeList; + @ApiModelProperty(example = "[20522613]") + private List placeList; @Builder - public BoardRequestDto(String title, String content, String category, User user, - List> places){ + public BoardRequestDto(String title, String content, String category, String email, + List places) { this.title = title; this.content = content; this.category = category; - this.user = user; + this.email = email; this.placeList = places; } - - public Board toEntity() throws MalformedURLException { - List places = new ArrayList<>(); - - for(List place : placeList){ - Long id = Long.valueOf(place.get(0)); - String title = place.get(1); - URL url = new URL(place.get(2)); - KakaoPlace temp = KakaoPlace.builder() - .id(id) - .title(title) - .url(url) - .build(); - places.add(temp); - } - - return Board.builder() - .title(title) - .content(content) - .category(Category.valueOf(category)) - .user(user) - .list(places) - .build(); - } } diff --git "a/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Dto/BoardResponseDto.java" "b/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Dto/BoardResponseDto.java" index a8ce286..9c50e1f 100644 --- "a/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Dto/BoardResponseDto.java" +++ "b/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Dto/BoardResponseDto.java" @@ -1,14 +1,15 @@ package com.example.umc_board.Dto; import com.example.umc_board.Entity.Board; +import com.example.umc_board.Entity.Category; import com.example.umc_board.Entity.KakaoPlace; +import com.example.umc_board.Entity.User; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import java.util.ArrayList; import java.util.List; @Getter @@ -24,32 +25,21 @@ public class BoardResponseDto { private String content; @ApiModelProperty(example = "커뮤니티") - private String category; + private Category category; @ApiModelProperty(example = "tester") - private String user; + private User user; @ApiModelProperty(example = "[[\"20522613\", \"거북당\", \"http://place.map.kakao.com/20522613\"]]") - private List> placeList; + private List placeList; public static BoardResponseDto of(Board board){ - List places = board.getPlaceList(); - List> list = new ArrayList<>(); - - for(KakaoPlace place : places){ - List tempList = new ArrayList<>(); - tempList.add(place.getId().toString()); - tempList.add(place.getTitle()); - tempList.add(place.getUrl().toString()); - list.add(tempList); - } - return BoardResponseDto.builder() .title(board.getTitle()) .content(board.getContent()) - .category(board.getCategory().getValue()) - .user(board.getUser().getName()) - .placeList(list) + .category(board.getCategory()) + .user(board.getUser()) + .placeList(board.getPlaceList()) .build(); } } diff --git "a/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Entity/Board.java" "b/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Entity/Board.java" index 24230d8..04dbb10 100644 --- "a/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Entity/Board.java" +++ "b/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Entity/Board.java" @@ -1,5 +1,6 @@ package com.example.umc_board.Entity; +import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -8,14 +9,14 @@ import java.util.ArrayList; import java.util.List; -@NoArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) @Getter @Entity @Table public class Board extends BaseTimeEntity{ @Id - @Column + @Column(name = "board_id") @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @@ -29,6 +30,7 @@ public class Board extends BaseTimeEntity{ private Category category; @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id") private User user; @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) @@ -44,6 +46,10 @@ public Board(String title, String content, this.placeList = list; } + public void setKakaoPlaces(KakaoPlace place){ + this.placeList.add(place); + } + public void update(String title, String content, Category category){ this.title = title; this.content = content; diff --git "a/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Entity/KakaoPlace.java" "b/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Entity/KakaoPlace.java" index 0c61464..c41dee8 100644 --- "a/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Entity/KakaoPlace.java" +++ "b/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Entity/KakaoPlace.java" @@ -1,5 +1,6 @@ package com.example.umc_board.Entity; +import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -7,14 +8,14 @@ import javax.persistence.*; import java.net.URL; -@NoArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) @Getter @Entity @Table public class KakaoPlace { @Id - @Column + @Column(name = "kakaoplace_id") private Long id; @Column diff --git "a/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Repository/BoardRepository.java" "b/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Repository/BoardRepository.java" index 0ea0650..8bf29fb 100644 --- "a/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Repository/BoardRepository.java" +++ "b/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Repository/BoardRepository.java" @@ -5,7 +5,9 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import java.util.List; + @Repository -public interface BoardRepository extends JpaRepository { - Board findByUser(User user); +public interface BoardRepository extends JpaRepository, BoardRepositoryCustom { + List findByUser(User user); } diff --git "a/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Repository/BoardRepositoryCustom.java" "b/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Repository/BoardRepositoryCustom.java" new file mode 100644 index 0000000..b5d78e1 --- /dev/null +++ "b/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Repository/BoardRepositoryCustom.java" @@ -0,0 +1,12 @@ +package com.example.umc_board.Repository; + +import com.example.umc_board.Entity.Board; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface BoardRepositoryCustom { + + List findByTitle(String title); +} diff --git "a/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Repository/BoardRepositoryImpl.java" "b/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Repository/BoardRepositoryImpl.java" new file mode 100644 index 0000000..868713d --- /dev/null +++ "b/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Repository/BoardRepositoryImpl.java" @@ -0,0 +1,21 @@ +package com.example.umc_board.Repository; + +import com.example.umc_board.Entity.Board; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; + +import java.util.List; + +import static com.example.umc_board.Entity.QBoard.board; + +@RequiredArgsConstructor +public class BoardRepositoryImpl implements BoardRepositoryCustom{ + + private final JPAQueryFactory jpaQueryFactory; + + public List findByTitle(String title){ + return jpaQueryFactory.selectFrom(board) + .where(board.title.eq(title)) + .fetch(); + } +} diff --git "a/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Repository/KakaoPlaceRepository.java" "b/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Repository/KakaoPlaceRepository.java" new file mode 100644 index 0000000..07be813 --- /dev/null +++ "b/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Repository/KakaoPlaceRepository.java" @@ -0,0 +1,10 @@ +package com.example.umc_board.Repository; + +import com.example.umc_board.Entity.KakaoPlace; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface KakaoPlaceRepository extends JpaRepository { + +} diff --git "a/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Repository/UserRepository.java" "b/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Repository/UserRepository.java" index 8599d57..c6ff0dc 100644 --- "a/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Repository/UserRepository.java" +++ "b/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Repository/UserRepository.java" @@ -7,4 +7,6 @@ @Repository public interface UserRepository extends JpaRepository { User findByEmail(String email); + + boolean existsByEmail(String email); } diff --git "a/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Service/BoardService.java" "b/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Service/BoardService.java" index 4555a46..4b8c222 100644 --- "a/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Service/BoardService.java" +++ "b/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Service/BoardService.java" @@ -3,7 +3,11 @@ import com.example.umc_board.Dto.BoardRequestDto; import com.example.umc_board.Entity.Board; import com.example.umc_board.Entity.Category; +import com.example.umc_board.Entity.KakaoPlace; +import com.example.umc_board.Entity.User; import com.example.umc_board.Repository.BoardRepository; +import com.example.umc_board.Repository.KakaoPlaceRepository; +import com.example.umc_board.Repository.UserRepository; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -12,12 +16,15 @@ import org.springframework.transaction.annotation.Transactional; import java.net.MalformedURLException; +import java.util.List; @RequiredArgsConstructor @Service public class BoardService { private final BoardRepository boardRepository; + private final UserRepository userRepository; + private final KakaoPlaceRepository kakaoRepository; public Page findBoardList(Pageable pageable){ return boardRepository @@ -26,6 +33,10 @@ public Page findBoardList(Pageable pageable){ )); } + public List findBoardByTitle(String title){ + return boardRepository.findByTitle(title); + } + public Board findBoardById(Long id){ Board board = boardRepository.findById(id).orElseThrow(() -> new IllegalArgumentException("글이 없습니다.")); return board; @@ -33,7 +44,10 @@ public Board findBoardById(Long id){ @Transactional public Board save(BoardRequestDto requestDto) throws MalformedURLException { - return boardRepository.save(requestDto.toEntity()); + User user = userRepository.findByEmail(requestDto.getEmail()); + List places = kakaoRepository.findAllById(requestDto.getPlaceList()); + return boardRepository.save(new Board(requestDto.getTitle(), requestDto.getContent(), + Category.valueOf(requestDto.getCategory()), user, places)); } @Transactional diff --git "a/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Service/UserService.java" "b/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Service/UserService.java" index 6cc6c70..f66e21f 100644 --- "a/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Service/UserService.java" +++ "b/\352\267\270\353\246\260_\354\225\210\354\212\271\354\227\260/week7/umc_board/src/main/java/com/example/umc_board/Service/UserService.java" @@ -15,11 +15,15 @@ public class UserService { @Transactional public User saveUser(UserRequestDto requestDto){ - return userRepository.save(requestDto.toEntity()); + if(!userRepository.existsByEmail(requestDto.getEmail())){ + return userRepository.save(requestDto.toEntity()); + }else{ + throw new RuntimeException("이미 가입된 이메일입니다."); + } } @Transactional - public User findUser(String email, String password){ + public User findByEmail(String email, String password){ User user = userRepository.findByEmail(email); if(user.getPassword().equals(password)) return user;