개인프로젝트/기능프로그램_오늘뭐입지

20240515_유저 DB 조정

일일일코_장민기 2024. 5. 15. 15:19
728x90

1. 가입일 입력

//회원가입 진행
Instant registerDate = Timestamp.from(Instant.now()).toInstant();
createMemberData.setRegisterdate(registerDate);
log.info("Create member: " + createMemberData);

memberService.createMember(createMemberData);

 

기본값을 지정했는데 어째서인지 가입일이 입력되지를 않는다...(userid는 잘 됨)

이 부분은 postgreSQL을 좀 더 공부해야 하는 부분인 것 같다

 

 

2. DB에 Country와 area 컬럼 추가

VO

@Size(max = 50)
@NotNull
@Column(name = "country", length = 50)
private String country;

@Size(max = 50)
@NotNull
@Column(name = "area", length = 50)
private String area;

 

DTO

@Size(max = 50)
@NotBlank(message = "지역을 입력하세요")
String country;

@Size(max = 50)
@NotBlank(message = "위치를 입력하세요")
String area;

 

3. 회원가입 시 지역을 입력하면 위치 목록을 출력하는 ajax 생성

더보기

컨트롤러

package org.member.utilController;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

@RequiredArgsConstructor
@Controller
public class UtilController {

    private final UtilService utilService;

    @PostMapping("/findAreasByCountry")
    @ResponseBody
    public List<String> findAreasByCountry(String country) {
        return utilService.findAreasByCountry(country);
    }
}

 

 서비스

package org.member.utilController;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.member.Place;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@RequiredArgsConstructor
@Slf4j
@Service
public class UtilService {

    private final UtilRepository utilRepository;

    public List<String> findAreasByCountry(String country) {
        List<Place> places = utilRepository.findAreaByCountry(country);
        List<String> areas = new ArrayList<>();
        for (Place place : places) {
            areas.add(place.getArea());
        }
        return areas;
    }
}

 

 리포지토리

package org.member.utilController;

import org.member.Place;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface UtilRepository extends JpaRepository<Place, Integer> {

    List<Place> findAreaByCountry(String country);
}

 

js

function changeAreaByCountry(){
    var country = $("#country").val()
    var areaInput = $("#areaInput")

    $.ajax({
        type: "post",
        url: "/findAreasByCountry",
        data: {
            country: country
        },
        datatype: "json",
        success: function(response){

            let htmlSelection = "<select id='area' name='area'>";
            response.forEach(areaName => {
                htmlSelection += `<option value="${areaName}">${areaName}</option>`
            })
            htmlSelection +=  "</select>"
            areaInput.html(htmlSelection);
        },
        error: function(){
            console.log("지역에 따른 위치 출력 에러")
        }
    })
}

 

- 이 작업을 하면서 weather 모듈에서 사용하던 place 엔터티를 그대로 가져왔다

- 이걸 하나를 공용으로 쓰는 게 좋나? 싶으면서 나누는게 기능 오류 해결 면에서 유리하다고 생각이 들어 2개로 나누어 계속 사용할 예정이다.

 

4. 로그인 후 받아오는 정보 변경

지역과 위치가 추가되었기에 그에 따라 정보를 수정했다.

겸사겸사 코드 효율화도 함께 진행했다

또한 로그인 후 session에 저장되는 DTO도 새로 작성되었다.

다만 스프링 시큐리티 작업 후에 얼마나 쓸지 모르겠다.

 

더보기

유저 서비스

public Optional<MemberDTO> readMemberByUsernameAndPassword(String username, String password) throws Exception {
    Optional<MemberVO> memberVO = Optional.ofNullable(memberRepository.findByUsernameAndPassword(username, password));
    log.info("memberVO: {}", memberVO);
    if (memberVO.isPresent()) {
        MemberDTO memberDTO = new MemberDTO();
        BeanUtils.copyProperties(memberVO.get(), memberDTO);
        return Optional.of(memberDTO);
    }
    throw new Exception();
}

 

유저 컨트롤러

@PostMapping("/login")
public ModelAndView readMemberByUsernmaeAndPassword(String username, String password, HttpSession session) throws Exception {
    ModelAndView modelAndView = new ModelAndView();
    Optional<MemberDTO> member = memberService.readMemberByUsernameAndPassword(username, password);
    if(member.isPresent()){
        UseMemberDataDTO useMemberDataDTO  = new UseMemberDataDTO(member.get().getId(), member.get().getUsername(), member.get().getEmail(), member.get().getCountry(), member.get().getArea());
        session.setAttribute("useMemberDataDTO", useMemberDataDTO);
        modelAndView.addObject("useMemberDataDTO", useMemberDataDTO);
        modelAndView.setViewName("Member/MemberPage");
        return modelAndView;
    }
    modelAndView.setViewName("Member/LoginPage");
    return modelAndView;
}

 

DTO

package org.member;

import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Data;
import lombok.Value;

import java.time.Instant;

@Data
@Value
public class UseMemberDataDTO {

    @NotNull
    Integer id;

    @Size(max = 50)
    @NotBlank(message = "아이디를 입력하세요")
    String username;

    @Size(max = 100)
    @Email(message = "올바른 이메일 형식이 아닙니다")
    @NotBlank(message = "이메일을 입력하세요")
    String email;

    @Size(max = 50)
    @NotBlank(message = "지역을 입력하세요")
    String country;

    @Size(max = 50)
    @NotBlank(message = "위치를 입력하세요")
    String area;

}

 

 

5. 변경된 유저 정보에 맞춰서 Cloth 수정 + 유저 옷 불러오는 함수 효율화

더보기

컨트롤러

//옷 불러오기 메서드
@PostMapping("/selectAllClothes")
public List<ClothDTO> selectAllClothes(Integer userid, HttpSession session){
    
    //현재 유저의 옷 가져오기
    List<ClothDTO> clothDTOS = clothService.findAllByUserid(userid);
    log.info(clothDTOS.toString());

    return clothDTOS;
}

서비스

//옷 불러오기 메서드
public List<ClothDTO> findAllByUserid(Integer userid) {
    MemberVO member = new MemberVO();
        member.setId(userid);
    List<ClothVO> clothVOList = idRepository.findAllByMemberVO(member);
    List<ClothDTO> clothDTOList = new ArrayList<>(clothVOList.size());
    for (ClothVO clothVO : clothVOList) {
        ClothDTO clothDTO = new ClothDTO();
        BeanUtils.copyProperties(clothVO, clothDTO);
        clothDTOList.add(clothDTO);
    }
    return clothDTOList;
}
package org.member.clothController;

import org.member.ClothVO;
import org.member.MemberVO;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface ClothUseridRepository extends JpaRepository<ClothVO, MemberVO>{

    List<ClothVO> findAllByMemberVO(MemberVO member);
}

- 기존 리포지토리는 id로 정보를 찾고 불러오는데 이 경우에는 FK로 사용 중인 userId가 있는 MemberVo가 필요하기 때문에 리포지토리를 하나 더 팠다. 간단하게 구현되기는 하지만 이게 맞나? 싶긴 하다

 

 

개선점

- postgreSQL에서 기본값 지정을 통한 가입일 지정

- ajax를 통해 로그인 실패 상황 구현