개인 포트폴리오/술렁술렁(전통주 플렛폼)

술렁술렁 프로젝트 - 개인 백엔드 작업, 전통주 정보 API

roalwh 2023. 10. 12. 20:02

술렁술렁 프로젝트 - 전통주 컨트롤러

  • 전통주 조회, 등록, 수정 등의 API
  • 지역별 전통주 조회 페이지에서 지역 기준으로 리스트 표시
  • 사용자가 찾고자 하는 데이터를 선택 시 전통주 상세 데이터 표시
  • 전통주 데이터의 경우 관리자가 등록 및 삭제를 진행하므로 해당 컨트롤러는 삭제가 없음.

1. 컨트롤러 설정

@RestController
@RequestMapping("/dri")
public class DrinkController {

  @Autowired
  private DrinkService drinkService;

  @Autowired
  EntityManager em;

  @GetMapping("/")
  public String DrinkController() {
    return "The Drink is up running....";
  }
  • @RequestMapping("/dri") -> 기본 url 설정
  • @GetMapping("/") 컨트롤러 동작 체크용 GetMapping 주소
  • 컨트롤러에서 요청에 참조할 서비스 등록

2. 전통주 검색, 목록, 등록 등 API

2-1. GET, 전통주 목록 가져오기 API

2-1-1.컨트롤러

  // 전통주 목록 가져오기
  @GetMapping("/all")
  public ResponseEntity<List<DrinkListResponseDto>> findAllDrinks() {
    List<DrinkListResponseDto> drinks = drinkService.findAll()
        .stream()
        .map(DrinkListResponseDto::new)
        .toList();
    return ResponseEntity.ok().body(drinks);
  }
  • 전체 전통주 정보 조회

2-1-2. 서비스

  // 전체 전통주 리스트
  @Transactional // 메서드가 포함하고 있는 작업 중에 하나라도 실패할 경우 전체 작업을 취소 //Id 관련 auto increment는 롤백안됨
  public List<Drink> findAll() {
    List<Drink> drinkList = drinkRepository.findAll();
    return drinkList;
  }
  • 전체 데이터 요청

2-1-3. 레파지토리

@Repository
public interface DrinkRepository extends JpaRepository<Drink, Long> {

}
  • JpaRepository를 상속받기 때문에 findAll() 별도로 추가하지 않아도 동작한다.

2-2. GET, 전통주 상세정보

2-2-1. 컨트롤러

  // 전통주 상세정보 조건 : 술 번호
  @GetMapping("/{did}")
  public Drink getDrinkinfo(@PathVariable Long did, Model model) {
    Drink drink = drinkService.findByDid(did);
    return drink;
  }
  • 등록된 전통주 번호로 해당 전통주 정보를 요청한다.

2-2-2. 서비스

  // id기준 전통주 정보
  @Transactional 
  public Drink findByDid(Long did) {
    Optional<Drink> drinks = drinkRepository.findById(did);
    return drinks.orElseThrow(() -> new IllegalArgumentException("not found : id"));
  }

2-2-3. 레파지토리

@Repository
public interface DrinkRepository extends JpaRepository<Drink, Long> {

}
  • JpaRepository를 상속받기 때문에 findByid() 별도로 추가하지 않아도 동작한다.

2-3. GET, 전통주 정보 목록 가져오기 - 전통주 종류(1차), 이름(2차)

2-3-1. 컨트롤러

 // 글목록 가져오기 - 전통주 종류(1차), 이름(2차) 기준 검색
  @GetMapping(path = "/search", params = { "category", "name" })
  public List<Drink> getDnameToNameLike(@RequestParam(value = "category") String category,
      @RequestParam(value = "name") String name, Model model) {
    List<Drink> drinkList = drinkService.searchDnameTonameLike(category, name);
    return drinkList;
  }
  • 카테고리 메인검색 기능과 같은 기능
  • 1차로 지역조건, 2차로 이름기준 이름은 Like %이름% 조건이 필요하다

2-3-2. 서비스

  // 전통주 종류, 이름 기준 전통주 정보
  @Transactional 
  public List<Drink> searchDnameTonameLike(String category, String name) {
    List<Drink> drinks = drinkRepository.findByDesclist_DnameAndNameContaining(category, name);

    return drinks;
  }

2-3-3. 레파지토리

@Repository
public interface DrinkRepository extends JpaRepository<Drink, Long> {
    // 전통주 종류 and %이름% 검색
    List<Drink> findByDesclist_DnameAndNameContaining(String category, String name);
}
  • Drink 엔티티 기준으로 Desclist 테이블의 Dname과 Drink 테이블의 Like % name% 조건으로 검색

2-4. GET, 전통주 정보 목록 가져오기 - 지역

2-4-1. 컨트롤러

  // 글목록 가져오기 조건 : 지역
  @GetMapping(path = "/search", params = "region")
  public List<Drink> getRegionLike(@RequestParam(value = "region") String region, Model model) {
    List<Drink> drinkList = drinkService.searchRegionLike(region);
    return drinkList;
  }
  • 전통주 지도 페이지에서 지역 기준으로 전통주 리스트를 요청함

2-4-2. 서비스

  // 지역 기준 전통주 정보
  @Transactional 
  public List<Drink> searchRegionLike(String region) {
    List<Drink> drinks = drinkRepository.findTop10ByRegionContaining(region);
    return drinks;
  }

2-4-3. 레파지토리

@Repository
public interface DrinkRepository extends JpaRepository<Drink, Long> {
  // %지역명% 검색
  List<Drink> findTop10ByRegionContaining(String region);
}
  • Like %region% 형태로 조건 검색을 진행하며 상위 10개까지 조회되도록 함.

2-5. POST, 전통주 등록

2-5-1. 컨트롤러

// 전통주 등록
  @PostMapping("/drinkIn")
  public ResponseEntity<?> addDrink(
      @RequestParam(value = "files", required = false) MultipartFile files[],
      @RequestParam(value = "orderuid") Long orderuid,
      @RequestParam(value = "name") String name,
      @RequestParam(value = "alc") double alc,
      @RequestParam(value = "ingre") String ingre,
      @RequestParam(value = "maker") String maker,
      @RequestParam(value = "address") String address,
      @RequestParam(value = "region") String region,
      @RequestParam(value = "price") Long price,
      @RequestParam(value = "food", required = false) String food,
      @RequestParam(value = "info") String info,
      @RequestParam(value = "category") String category,
      @RequestParam(value = "sweet", required = false, defaultValue = "0") int sweet,
      @RequestParam(value = "sour", required = false, defaultValue = "0") int sour,
      @RequestParam(value = "cool", required = false, defaultValue = "0") int cool,
      @RequestParam(value = "body", required = false, defaultValue = "0") int body,
      @RequestParam(value = "balance", required = false, defaultValue = "0") int balance,
      @RequestParam(value = "insense", required = false, defaultValue = "0") int insense,
      @RequestParam(value = "throat", required = false, defaultValue = "0") int throat,
      @RequestParam(value = "dyn", required = false, defaultValue = "N") String dyn) {

    // 요청자 권한 확인
    boolean drinkusercheck = drinkService.finduser(orderuid);
    if (!drinkusercheck) {
      return ResponseEntity.badRequest().body("계정이나 권한이 없습니다.");
    }

    AddDrinkRequestDto drinkRequest = new AddDrinkRequestDto(
        name, alc, ingre, maker, address, region, price, food, info, category, sweet, sour, cool, body, balance,
        insense, throat);
    Drink drink = drinkService.addDrink(drinkRequest);
    Long did = drink.getDid();

    // 이미지가 있는경우
    if (files != null) {
      for (int i = 0; i < files.length; i++) {
        MultipartFile multi = files[i];
        String path = "c:\\img";
        System.out.println(path);

        try {
          // 파일 경로 설정
          String uploadpath = path;
          String originFilename = multi.getOriginalFilename();
          long size = multi.getSize();
          String extName = originFilename.substring(originFilename.lastIndexOf("."), originFilename.length());
          // String saveFileName = genSaveFileName(extName);
          String saveFileName = "drink_" + did + extName;

          System.out.println("uploadpath : " + uploadpath);
          System.out.println("originFilename : " + originFilename);
          System.out.println("extensionName : " + extName);
          System.out.println("size : " + size);
          System.out.println("saveFileName : " + saveFileName);

          String path2 = System.getProperty("user.dir");
          // 파일 경로 최종
          //윈도우
          // String path3 = "\\src\\main\\resources\\img\\drink" + did + "\\dimg\\";
          // 리눅스
          String path3 = "/src/main/resources/img/drink" + did + "/dimg/";
          System.out.println("Working Directory = " + path2 + path3);

          // 디비 파일 경로
          String setpath = "/dimg/" + did + "/" + saveFileName;

          System.out.println("setpath =" + setpath);
          if (!multi.isEmpty()) {

            // 파일저장경로설정
            File forder = new File(path2 + path3);
            forder.mkdir();
            System.out.println(forder);

            // 해당 디렉토리가 없을경우 디렉토리를 생성합니다.
            if (!forder.exists()) {
              try {
                forder.mkdirs(); // 폴더 생성합니다.
                System.out.println("폴더가 생성되었습니다.");
              } catch (Exception e) {
                e.getStackTrace();
              }
            } else {
              System.out.println("이미 폴더가 생성되어 있습니다.");
            }
            // 파일 저장 경로/파일이름
            File file = new File(path2 + path3, saveFileName);
            // 파일 저장
            multi.transferTo(file);

            AddDimgRequestDto imgrequest = new AddDimgRequestDto(did, saveFileName, setpath, dyn);

            drinkService.addDimg(imgrequest);
          }
        } catch (Exception e) {
          System.out.println(e);
        }
      }
    }
    em.clear();
    Drink drinks = drinkService.findByDid(did);
    return ResponseEntity.status(HttpStatus.CREATED).body(drinks);
  }
  • 전통주 등록하는 사용자 권한 확인 해당 사용자의 정보 호출
  • 술등록 전 전통주 코드값으로 되어있기 때문에 Desclist 조회
  • 텍스트로 된 1차 저장 진행
  • 이미지가 있으면 이미지 업로드 작업 및 해당 이미지 경로 업로드 진행
  • 작업이 끝난 후 EntityManager.clear()를 사용하여 기존 엔티티를 캐시 정리 후 전통주 리스트를 재로딩함

2-5-2. 서비스

  // 계정 검증
  @Transactional
  public Boolean finduser(Long uid){
    Members member = memberRepository.findById(uid).get();
    if(member==null)
    return false;

    if(member.getAuthority().equals(Authority.ROLE_ADMIN) || member.getAuthority().equals(Authority.ROLE_SADMIN))
    return true;
    return false;
  }

  // 전통주 등록
  @Transactional // 메서드가 포함하고 있는 작업 중에 하나라도 실패할 경우 전체 작업을 취소 //Id 관련 auto increment는 롤백안됨
  public Drink addDrink(AddDrinkRequestDto request) {
    // 1. Drink 저장
    Optional<Desclist> optdname = desclistRepository.findByDname(request.getCategory());
    // 2. Drink 저장 후 리턴
    return drinkRepository.save(request.toEntityDrink(optdname.get()));
  }

  //전통주 이미지 등록
  @Transactional
  public Dimg addDimg(AddDimgRequestDto imgrequest){
    Optional<Drink> optDrink = drinkRepository.findById(imgrequest.getDid());
    return dimgRepository.save(imgrequest.toEntityDimg(optDrink.get()));
  }

2-5-3. 레파지토리

@Repository
public interface MemberRepository  extends JpaRepository<Members, Long>{

}

public interface DesclistRepository extends JpaRepository<Desclist, Long>{
  //dname 기준 검색, 코드값으로 전통주 종류값 가져오기
  Optional<Desclist> findByDname(String dname);

}

@Repository
public interface DrinkRepository extends JpaRepository<Drink, Long> {

    }

2-6. PUT, 전통주 수정

2-6-1. 컨트롤러

// 전통주 수정
  @PutMapping("/drinkedit/{did}")
  public ResponseEntity<?> updateDrink(
      @PathVariable Long did,
      @RequestParam(value = "files", required = false) MultipartFile files[],
      @RequestParam(value = "orderuid") Long orderuid,
      @RequestParam(value = "name", required = false) String name,
      @RequestParam(value = "alc", required = false, defaultValue = "0") Integer alc,
      @RequestParam(value = "ingre", required = false) String ingre,
      @RequestParam(value = "maker", required = false) String maker,
      @RequestParam(value = "address", required = false) String address,
      @RequestParam(value = "region", required = false) String region,
      @RequestParam(value = "price", required = false) Long price,
      @RequestParam(value = "food", required = false) String food,
      @RequestParam(value = "info", required = false) String info,
      @RequestParam(value = "category", required = false) String category,
      @RequestParam(value = "sweet", required = false) Integer sweet,
      @RequestParam(value = "sour", required = false) Integer sour,
      @RequestParam(value = "cool", required = false) Integer cool,
      @RequestParam(value = "body", required = false) Integer body,
      @RequestParam(value = "balance", required = false) Integer balance,
      @RequestParam(value = "insense", required = false) Integer insense,
      @RequestParam(value = "throat", required = false) Integer throat,
      @RequestParam(value = "imgid", required = false) Long imgid,
      @RequestParam(value = "imgdyn", required = false) String imgdyn) {
    // null 값 처리를 위해 맛부분 은 Integer 로 처리


    // 요청자 권한 확인
    boolean drinkusercheck = drinkService.finduser(orderuid);
    if (!drinkusercheck) {
      return ResponseEntity.badRequest().body("계정이나 권한이 없습니다.");
    }

    UpdateDrinkRequestDto drinkRequest = new UpdateDrinkRequestDto(
        did, name, alc, ingre, maker, address, region, price, food, info, category, sweet, sour, cool, body, balance,
        insense, throat);
    Drink drink = drinkService.updateDrink(drinkRequest);

    // 이미지가 있는경우
    if (files != null) {
      for (int i = 0; i < files.length; i++) {
        MultipartFile multi = files[i];
        String path = "c:\\img";
        System.out.println(path);

        try {
          // 파일 경로 설정
          String uploadpath = path;
          String originFilename = multi.getOriginalFilename();
          long size = multi.getSize();
          String extName = originFilename.substring(originFilename.lastIndexOf("."), originFilename.length());
          // String saveFileName = genSaveFileName(extName);
          String saveFileName = "drink_" + did + extName;

          System.out.println("uploadpath : " + uploadpath);
          System.out.println("originFilename : " + originFilename);
          System.out.println("extensionName : " + extName);
          System.out.println("size : " + size);
          System.out.println("saveFileName : " + saveFileName);

          String path2 = System.getProperty("user.dir");
          // 파일 경로 최종
          // String path3 = "\\src\\main\\resources\\img\\drink" + did + "\\dimg\\";
          // 리눅스
          String path3 = "/src/main/img/drink" + did + "/dimg/"; 

          System.out.println("Working Directory = " + path2 + path3);

          // 디비 파일 경로
          String setpath = "/dimg/" + did + "/" + saveFileName;

          System.out.println("setpath =" + setpath);
          if (!multi.isEmpty()) {

            // 파일저장경로설정
            File forder = new File(path2 + path3);
            forder.mkdir();
            System.out.println(forder);

            // 해당 디렉토리가 없을경우 디렉토리를 생성합니다.
            if (!forder.exists()) {
              try {
                forder.mkdirs(); // 폴더 생성합니다.
                System.out.println("폴더가 생성되었습니다.");
              } catch (Exception e) {
                e.getStackTrace();
              }
            } else {
              System.out.println("이미 폴더가 생성되어 있습니다.");
            }
            // 파일 저장 경로/파일이름
            File file = new File(path2 + path3, saveFileName);
            // 파일 저장
            multi.transferTo(file);

            UpdateDimgRequestDto imgrequest = new UpdateDimgRequestDto(imgid, did, saveFileName, setpath, imgdyn);
            drinkService.updateDimg(imgrequest);
          }
        } catch (Exception e) {
          System.out.println(e);
        }
      }

      // 사진 삭제 요청으로 imgdyn이 null이 아닐때
      if (imgdyn != null) {
        String saveFileName = null;
        String setpath = null;
        UpdateDimgRequestDto imgrequest = new UpdateDimgRequestDto(imgid, did, saveFileName, setpath, imgdyn);
        drinkService.updateDimg(imgrequest);
      }
    }
    em.clear();
    Drink drinks = drinkService.findByDid(did);
    return ResponseEntity.status(HttpStatus.CREATED).body(drinks);
  }
  • 전통주 등록하는 사용자 권한 확인 해당 사용자의 정보 호출
  • 텍스트로 된 정보부터 업데이트 진행
  • 이미지 등록 확인 후 이미지가 있으면 이미지 업로드 작업 및 해당 이미지 경로 업로드 진행
  • 작업이 끝난 후 EntityManager.clear()를 사용하여 기존 엔티티를 캐시 정리 후 전통주 리스트를 재로딩함

2-6-2. 서비스

// 전통주 데이터 수정
  public Drink updateDrink(UpdateDrinkRequestDto updateRequest){
    Drink drink = drinkRepository.findById(updateRequest.getDid()).get();
    if(updateRequest.getName()!=null){
      drink.setName(updateRequest.getName());
    }
    if (updateRequest.getAlc()!=null) {
      drink.setAlc((double) updateRequest.getAlc());
    }
    if (updateRequest.getIngre()!=null) {
      drink.setIngre(updateRequest.getIngre());
    }
    if (updateRequest.getMaker()!=null) {
      drink.setMaker(updateRequest.getMaker());
    }
    if (updateRequest.getAddress()!=null) {
      drink.setAddress(updateRequest.getAddress());
    }
    if (updateRequest.getRegion()!=null) {
      drink.setRegion(updateRequest.getRegion());
    }
    if (updateRequest.getPrice()!=null) {
      drink.setPrice(updateRequest.getPrice());
    }
    if (updateRequest.getFood()!=null) {
      drink.setFood(updateRequest.getFood());
    }
    if (updateRequest.getInfo()!=null) {
      drink.setInfo(updateRequest.getInfo());
    }
    if (updateRequest.getCategory()!=null) {
      Desclist desclist = desclistRepository.findByDname(updateRequest.getCategory()).get();      
      drink.setDesclist(desclist);
    }
    if (updateRequest.getSweet()!=null) {
      drink.setSweet(updateRequest.getSweet());
    }
    if (updateRequest.getSour()!=null) {
      drink.setSour(updateRequest.getSour());
    }
    if (updateRequest.getCool()!=null) {
      drink.setCool(updateRequest.getCool());
    }
    if (updateRequest.getBody()!=null) {
      drink.setBody(updateRequest.getBody());
    }
    if (updateRequest.getBalance()!=null) {
      drink.setBalance(updateRequest.getBalance());
    }
    if (updateRequest.getInsense()!=null) {
      drink.setInsense(updateRequest.getInsense());
    }
    if (updateRequest.getThroat()!=null) {
      drink.setThroat(updateRequest.getThroat());
    }

    return drinkRepository.save(drink);
  }

  // 전통주 수정 이미지 변경
  public Dimg updateDimg(UpdateDimgRequestDto imgrequest){
    Dimg dimg = dimgRepository.findByImgidAndDrink_Did(imgrequest.getImgid(),imgrequest.getDid());

    if(imgrequest.getDyn()!=null){
      dimg.setDyn(imgrequest.getDyn());
      return dimg;
    }
    if(imgrequest.getIname()!=null){
      dimg.setIname(imgrequest.getIname());
    }
    if(imgrequest.getPath()!=null){
      dimg.setPath(imgrequest.getPath());
    }
    System.out.println(LocalDateTime.now());
    dimg.setudatetime(LocalDateTime.now());
    return dimg;
  }
  • 각 컬럼당 변경할 데이터가 있으면 요청
  • 이미지의 imgdyn 값이 변경되면 바로 리턴처리

2-6-3. 레파지토리

@Repository
public interface DrinkRepository extends JpaRepository<Drink, Long> {

}

@Repository
public interface DesclistRepository extends JpaRepository<Desclist, Long>{
  Optional<Desclist> findByDname(String dname);

}
@Repository
public interface DimgRepository  extends JpaRepository<Dimg, Long>{
  Dimg findByImgidAndDrink_Did(Long imgid, Long did);
}
  • JpaRepository 상속받으며 save() 경우 상속받기 때문에 에러 없이 처리된다.