주제와 관련된 더 많은 사진을 참조하십시오 [자바 웹을 다루는 기술] 31.11 마이 페이지 구현하기. 댓글에서 더 많은 관련 이미지를 보거나 필요한 경우 더 많은 관련 기사를 볼 수 있습니다.
주제에 대한 기사 평가 spring 마이 페이지
Author: Tartaglia_타르탈리아 TV
Views: 조회수 1,379회
Likes: 좋아요 14개
Date Published: 2019. 6. 11.
Video Url link: https://www.youtube.com/watch?v=IkyhROSMwQA
[spring/java] 웹사이트 만들기 5 – 회원정보 수정 / 마이페이지(my page)
spring/java를 이용하여 마이페이지를 구현하려고 하는 내용은 다음과 같다. 먼저 이메일 인증된 아이디를 통해 로그인을 하면 마이페이지로 이동할 수 있는 링크가 생긴다. 링크로 이동하면 session에 설정된 회원의 현재 정보를 보여준다. 정보를 수정하거나 비밀번호를 변경 후 버튼을 클릭하면 데이터베이스의 회원 정보를 수정한 후 session을 재설정하는 방식을 이용하도록 하겠다.
그러면 먼저 index 페이지에 로그인이 되었을 때 마이페이지 링크를 추가한다.
[스프링] 마이페이지 구현 – 회원 활동로그와 작성한 게시글,댓글,스크랩 목록
728×90
이번엔 마이페이지로 이동해서 , 그곳에서 회원 활동로그와 작성한 게시글,댓글,스크랩 목록을 볼 수 있도록 구현했다.
OKKY 사이트처럼 다른사람도 그 정보를 닉네임을 클릭하는 등의 행위를 통해서 볼 수 있도록 만들었다.
다른 커뮤니티처럼 내 정보는 따로 검색을 하거나 등을 제외하면 나만 볼 수 있도록 할까… 생각을 했지만
IT커뮤니티이니 만큼 (?) 이상한 짓을 못하도록 그냥 모든 정보를 회원들이 서로 볼 수 있도록 만들었다.
실제로 나도 OKKY 커뮤니티를 사용하면서 다른 커뮤니티들과 다른 그런 정보공개?가 처음에는 낯설었지만
꽤나 괜찮다는 생각을 받기도 했다.
단, 너무 행동에 조심하게? 되는 부분에 대해 게시글과 댓글을 삭제하면 활동로그가 아예 삭제되도록 구현해서
해당 부분을 보완했다.
일단 해당 기능 또한 검색을 해도 따로 힌트나 도움이 될 만한 정보가 나오진 않았다.
그래서 내 생각대로 만들었는데 , 부족한 실력이다보니 꽤나 하드코딩이 된 것 같아서 마음이 아프다,,,
이전 이전 01 슬라이드쇼 2장
먼저 okky의 마이페이지 디자인을 따라서 구현해봤고 (허접함 주의)
해당페이지에서 최근활동, 게시물 , 스크랩을 클릭했을때
주소창에서 회원의 PR은 유지되면서 뒤의 주소창에 변화가 일어나는 부분을 보고,
get 방식으로 회원PR받으며, PR기준으로 select문을 구별해서 구현하면 되겠구나하는 생각이 들었다.
구현 로직을 먼저 설명하자면
회원의 활동로그를 저장 할 테이블을 생성
글작성,좋아요,싫어요,DEV,댓글작성,채택 등의 행위를 할 때 insert 되도록 코드 추가
반대로 글삭제,좋아요취소,싫어요취소 등의 행위를 할 때에는 따로 기록을 남기지 않기 위해 delete 되도록 추가
insert시에는 활동로그 테이블에 카테고리별로 구분되어 어떤 활동을 했는지 기록됨
활동로그 테이블과 게시판 테이블 , 댓글테이블을 join을 해서 List로 출력
뷰에서 List의 카테고리 컬럼을 기준으로 if문을 통해 출력 될 문장을 나눠줌
내 게시글, 내 댓글 , 내 스크랩을 출력하기 위해 select문을 위와 동일하게 List로 가져와서 출력
활동로그 , 게시글 , 댓글 , 스크랩은 get 방식을 사용해서 주소창에서 “/주소?select=” 로 나눠주고
어떤 회원의 프로필을 볼 건지는 “/주소?select=# &memberId=#”으로 나눠준다.
결과
‘1234’회원의 활동기록이다.
아직 추가적으로 디자인을 좀 더 깔끔하게 가꾸고 , 페이징 기능을 추가해야하지만 1차적으로 필요한 기능은 구현됐다.
주소창 부분에 select=log ( 활동기록 ) , memberId=1234 (회원PR) 로 나누어서 출력한다.
활동기록 테이블 생성
create table MP_LOG ( LOGNO number not null, MEMBER_ID varchar2(50) not null, bno number, rno number, questionid varchar2(50), categori number , logdate date default sysdate, constraint log_pk PRIMARY key (LOGNO), constraint log_fk FOREIGN key (MEMBER_ID) references MP_MEMBER(MEMBER_ID) on delete cascade );
LogNO
Member_ID ( 회원PR )
Bno ( 게시글PR )
Rno ( 댓글PR )
Questionid (채택받은 사람의 id인데 설계시에는 추가했지만 구현하고보니 rno를 기준으로 join하면 값이 나오기 때문에 생략해도 무방함)
게시글 작성등의 활동에는 rno가 들어가지 않기 때문에 jdbcType을 사용해서 null값을 허용해주자.
(mybatis 사용시 insert에 null값이 들어가면 nullpoint에러 발생)
delete from MP_LOG where MEMBER_ID = #{memberId} and BNO = #{bno} and CATEGORI = #{categori} delete from MP_LOG where MEMBER_ID = #{memberId} and RNO = #{rno} and CATEGORI = #{categori}
게시글 삭제 , 게시글 추천 취소 , 댓글 삭제 , 댓글 추천 취소 등에 들어갈 delete 문이다.
게시글PR , 댓글PR기준이기 때문에 두개의 delete문을 만들어줬다.
로그 테이블에 회원PR을 기준 , BNO에 해당하는 게시글의 활동(Categori로 구분)을 삭제한다.
글 작성은 bno로 구분되고 ,
글 추천 등의 행위는 회원당 1번으로 제한했기 때문에 카테고리를 기준으로 삭제해도 문제가 없다.
Mapper를 작성했으니 VO를 작성해서 편하게 파라미터를 받아보자.
public class LogVO { private String memberId; private int bno; private int rno; private String questionId; private int categori; private Date logdate; private BoardVO boardVO; private ReplyVO replyVO; //getter&setter 생성 }
jojn 쿼리때에 사용 할 게시판VO와 댓글VO도 추가해준다.
이제 글작성 , 글삭제 등의 로직에 활동기록 테이블에 insert되도록 추가해준다.
이때 난 service에 넣어줬는데 처음에 잘 못 된 설계와 구현방법으로 인해 controller에서
service에 구현해야 할 항목들을 그냥 Controller에서 구현했다.
후에 로직을 여러가지 추가하려고 하니 결합성이 강해져서 고생이 늘어버렸다.
앞으론 Controller에선 파라미터를 받고 , 간단한 구분정도만 해주기로 하고
Service에서 컨트롤러에서 받은 파라미터로 로직을 작성하도록 할 예정이다.
(Controller에서 로직을 작성하는 바람에 받은 매개변수를 두,세번씩 선언하는 등 코드도 길어지고 복잡해졌다)
[Spring Boot/JPA] #3 View와 Controller 제작 : 마이페이지 만들기 (1)
개인적으로 시작한 개발이며, 틀린 점이나 부족한 부분이 많을 수 있으니 보완할 사항이나 질문은 댓글로 남겨주세요!
개발 환경
Database : mysql community Server 8.0.23
language : Java 11
Framework : Spring
IDE : IntelliJ ultimate ver.
OS : MS Win10 64bit
컨트롤러와 뷰 개발
지난 번 기본적인 서비스에 대한 개발을 했으니 필요한 뷰와 컨트롤러를 만들었고,
나는 로그인 이후 마이페이지를 맡기로 했다.
기본적인 URI를
~/mypage/me : 닉네임 또는 이메일 변경 / 정보 표시
~/mypage/contents : 내가 쓴 게시글
~/mypage/comments : 내가 쓴 댓글
~/mypage/scrap : 내가 스크랩한 글
~/mypage/password : 비밀번호 변경
로 정했다.
mypage/me
우선 제일 기본이 되는 페이지인 /mypage/me의 뷰를 만들었다.
JSP에 대해 잘 알지 못하는 관계로 진입장벽이 그나마 낮은 Thymeleaf(View Template)을 사용했다.
mypage/me.html
< html xmlns: th = " http://www.thymeleaf.org " > < head th: replace = " fragments/header :: header " /> < body > < div th: replace = " fragments/nav :: fragment-nav " > div > < th: block th: insert = " fragments/mypage-body :: mypage-body " /> < div class = " col-lg-4 " > < div class = " useredit " > < div class = " fa-user " > 개인정보 수정 div > < form role = " form " th: action = " @{/mypage/me} " th: object = " ${memberForm} " method = " post " > < div class = " form-group " > < label th: for = " name " > 닉네임 label > < input type = " text " th: field = " *{name} " class = " form-control " placeholder = " 닉네임을 입력하세요 " th: class = " ${#fields.hasErrors('name')}? 'form-control fieldError' : 'form-control' " > < p th: if = " ${#fields.hasErrors('name')} " th: errors = " *{name} " > Incorrect input p > div > < div class = " form-group " > < label th: for = " email " > 이메일 label > < input type = " email " th: field = " *{email} " class = " form-control " placeholder = " None " th: class = " ${#fields.hasErrors('email')}? 'form-control fieldError' : 'form-control' " > < p th: if = " ${#fields.hasErrors('email')} " th: errors = " *{email} " > Incorrect input p > div > < button type = " submit " class = " btn btn-primary " > 수정 button > form > < br /> div > div > body >
controller/MemberForm
@Getter @Setter public class MemberForm { @NotEmpty ( message = “닉네임은 필수입니다.” ) private String name ; @NotEmpty ( message = “이메일은 필수입니다.” ) private String email ; }
회원 정보 수정 DTO인 memberForm을 넘겨 받아, 그 안의 변수인 name과 string을 각 입력 field로 사용한다. 수정 button을 눌렀을 때 form과 함께 HTTP post 메서드로 요청할 주소를
뷰를 열심히 뚝딱뚝딱 만들었으니 이를 보여주고 post요청을 처리할 컨트롤러가 필요하다.
controller/MyPageController
@GetMapping ( “/mypage/me” ) public String myPageHome ( Model model , @AuthenticationPrincipal Member currentMember ) { List < Category > categoryList = categoryService . findAll ( ) ; MemberForm memberForm = new MemberForm ( ) ; memberForm . setName ( currentMember . getUsername ( ) ) ; memberForm . setEmail ( currentMember . getEmail ( ) ) ; model . addAttribute ( “categoryList” , categoryList ) ; model . addAttribute ( “memberForm” , memberForm ) ; return “mypage/me” ; }
category에 대한 정보는 모든 뷰에 공통으로 들어가는 side-bar fragments에서 사용되는 것이므로 추후에 설명하도록 한다.
“/mypage/me”의 URL로 Get요청으로 들어올 경우 위에서 만든 뷰를 보여줘야 한다.
해당 뷰에는 개인정보를 수정할 Form이 필요하므로 MemberForm을 새로 생성해주고 현재 로그인한 정보를 @AuthenticationPrincipal을 통해 접근하여 set한 후 model에 Attribute로 추가시켜준다.
Form의 field를 set하는 이유는 빈칸의 form이 아닌 현재 사용자의 정보를 담게 하고 싶어서이다.
@AuthenticationPrincipal
Spring Security에서 현재 로그인한 사용자 정보를 Session에서 조회할 수 있도록 제공한다. @AuthenticationPrincipal을 통해 UserDetails를 구현한 구현체인 Member 클래스를 반환한다. UserDetails를 구현해야하는 이유는, Spring Security가 UserDetailsService를 구현한 구현체의 오버라이딩된 메서드인 loadUserByUsername()을 통해 현재 사용자를 리턴하기 때문이다.
회원의 Role에 맞는 권한을 부여하고 새 Member 객체를 리턴한다. 여기서 Member가 UserDetails를 구현한 구현체이므로 Member를 리턴할 수 있다. UserDetails를 구현한 구현체가 여러 개라면 new User 또는 new UserDetails라고 하는 게 낫겠으나, 우리는 구현체가 Member 클래스 하나 뿐이므로 Member를 리턴하도록 하였다.
돌아와서
Get 요청을 받아 해당 뷰를 보여주는 컨트롤러를 만들었으니 Form을 받아 Post 요청을 처리하는 컨트롤러도 만들어야 한다.
controller/MyPageController
@PostMapping ( “/mypage/me” ) public String userEdit ( MemberForm form , BindingResult result , @AuthenticationPrincipal Member currentMember ) { if ( result . hasErrors ( ) ) { return “redirect:/mypage/me” ; } memberService . updateInfo ( currentMember . getUsername ( ) , form . getName ( ) , form . getEmail ( ) ) ; currentMember . setUsername ( form . getName ( ) ) ; currentMember . setEmail ( form . getEmail ( ) ) ; return “redirect:/mypage/me” ; }
service/MemberSerivceImple
@Transactional @Override public Long updateInfo ( String username , String newName , String email ) { Member member = memberRepository . findByUsername ( username ) . orElseThrow ( ( ) -> new UsernameNotFoundException ( username ) ) ; member . setUsername ( newName ) ; member . setEmail ( email ) ; return member . getId ( ) ; }
memberService의 updateInfo를 호출해 DB의 username과 email을 변경한다. JPA 변경 감지를 통해 수정한다. JPA 변경 감지는 자세한 공부를 위해 다른 포스트에서 설명해야할 것 같다.
그리고 컨트롤러에서 현재 로그인한 사용자의 username과 email도 바꿔줘야 한다.
@AuthenticationPrincipal을 통해 사용자를 리턴받을 때 Session에 있는 username을 통해 검색을 하는데, 그게 바뀌지 않을 경우 아무리 getUsername을 해봐야 update 이전의 username을 뱉어낸다.(DB에는 update되어 있지만 Session에는 update되지 않은 정보가 남아 있다.)
이게 맞는 방법인지는 모르겠다. Session update에 대해 더 찾아봐야겠다.
currentMember의 userName을 set한 경우/하지 않은 경우를 테스트 해보면
원래 닉네임이 ddd11이고 ddd22로 변경
set한 경우
GetMapping된 컨트롤러에서 memberForm의 기본 정보를 현재 사용자 정보로 설정해주므로 이렇게 변경된 닉네임이 나오는 게 맞다.
set을 안 한 경우
아무리 변경해봐야 얘는 안 바뀐다.
mypage/contents
mypage/contents.html
< html xmlns: th = " http://www.thymeleaf.org " > < head th: replace = " fragments/header :: header " /> < body > < div th: replace = " fragments/nav :: fragment-nav " > div > < th: block th: insert = " fragments/mypage-body :: mypage-body " /> < div class = " container d-flex mt-5 " > < table class = " box shadow table " > < thead > < tr > < td class = " h4 " colspan = " 6 " > 내가 쓴 글 td > tr > < tr > < th style =" width : 10% " > 번호 th > < th style =" width : 50% " > 제목 th > < th style =" width : 10% " > 이름 th > < th style =" width : 10% " > 추천 th > < th style =" width : 10% " > 날짜 th > < th style =" width : 10% " > 조회 th > tr > thead > < tbody > < tr th: each = " post: ${posts} " > < td style =" width : 10% " th: text = " ${post.id} " > td > < td style =" width : 10% " > < a th: href = " @{/content/{postId}(postId=${post.id},prev=1,prev_content='/board/'+${post.category.id})} " th: text = " ${post.title} " > a > td > < td style =" width : 10% " th: text = " ${post.member.username} " > 익명 td > < td style =" width : 10% " th: text = " ${post.likes} " > 추천 td > < td style =" width : 10% " th: text = " ${#temporals.format(post.createDate, 'HH:mm')} " > 날짜 td > < td style =" width : 10% " th: text = " ${post.visit} " > 조회 td > tr > tbody > table > div > < div class = " container " > < nav aria-label = " Page navigation example " > < ul class = " pagination justify-content-center " th: with = " start=${T(Math).floor(posts.number/10)*10 + 1}, last=(${start + 9 < posts.totalPages ? start + 9 : posts.totalPages}) " > < li class = " page-item " > < a th: href = " @{/contents/(page=1)} " aria-label = " First " > < span aria-hidden = " true " > First span > a > li > < li class = " page-item " th: class = " ${posts.first} ? 'disabled' " > < a th: href = " ${posts.first} ? '#' : @{/contents/(page=${posts.number})} " aria-label = " Previous " > < span aria-hidden = " true " > < span > a > li > < li class = " page-item " th: each = " page: ${#numbers.sequence(start, last)} " th: class = " ${page == posts.number + 1} ? 'active' " > < a th: text = " ${page} " th: href = " @{/contents/(page=${page})} " > a > li > < li class = " page-item " th: class = " ${posts.last} ? 'disabled' " > < a th: href = " ${posts.last} ? '#' : @{/contents/(page=${posts.number+2})} " aria-label = " Next " > < span aria-hidden = " true " > > span > a > li > < li class = " page-item " > < a th: href = " @{/contents/(page=${posts.totalPages})} " aria-label = " Last " > < span aria-hidden = " true " > Last span > a > li > ul > nav > div > body > html >
아래와 같이 나온다. 임의로 게시글을 여러개 만들었다. 테이블을 만들어 Thymeleaf 문법을 사용해 반복문으로 td를 만들게 했다.
html의 class=”container”인 div는 page에 관한 태그들인데, First, Last 1, 2 …를 나타내기 위함이다.
controller/MyPageController
@GetMapping ( “/mypage/contents” ) public String myContents ( Model model , @AuthenticationPrincipal Member currentMember , @PageableDefault Pageable pageable ) { Member member = memberService . findByUsername ( currentMember . getUsername ( ) ) . orElseThrow ( ( ) -> new UsernameNotFoundException ( currentMember . getUsername ( ) ) ) ; Page < Post > posts = postService . getPostListByMember ( member , pageable ) ; List < Category > categoryList = categoryService . findAll ( ) ; model . addAttribute ( “categoryList” , categoryList ) ; model . addAttribute ( “posts” , posts ) ; return “mypage/contents” ; }
새로운 어노테이션인 @PageableDefault … JPA는 어렵다. Paging에 관련된 어노테이션이다. 컨트롤러는 간단하게 페이징한 목록을 model에 추가해 뷰를 리턴하는 구조이다.
여기서 눈여겨볼 것은 @PageableDefault, 페이징에 대해 열심히 구글링 해보면서 여러 페이징 방법이 있지만 가장 편하게? 할 수 있는 방법 같다.
이 방법을 사용하지 않고서 할 수 있는 방법은 VO를 만들고, 페이지에 해당하는 select SQL 쿼리를 날려 얻는 방법이 있다. 이는 데이터베이스마다 페이징 쿼리가 다를 수 있고 여러 요구 사항을 만족하기 어려울 수 있다. SQL이 아닌 java 코드 관점에서 DB를 접근하기 위해 Spring Data JPA를 사용하는 것이고 이를 이용하면 비즈니스 로직에 더욱 집중할 수 있기에 이 방법을 선택했다.
@PageableDefault
JPA에서 제공하는 Paging을 위한 어노테이션이다. Pageable 인터페이스를 구현한 구현체를 파라미터로 받는다.
@Documented @Retention ( RetentionPolicy . RUNTIME ) @Target ( ElementType . PARAMETER ) public @interface PageableDefault { int value ( ) default 10 ; int size ( ) default 10 ; int page ( ) default 0 ; String [ ] sort ( ) default { } ; Direction direction ( ) default Direction . ASC ; }
Client로부터 쿼리스트링을 통해 페이징 정보가 주어지지 않는다면 PageDefault에 이 디폴트 값으로 설정된다.
디폴트 값이 아닌 원하는 값을 지정해주고 싶다면 @PageableDefault(page = 1, size = 20) 과 같이 파라미터로 넣어주면 된다.
나는 서비스의 메서드에서 값을 설정해주었는데, 이 방법보다는 파라미터로 넣어주는 것이 이후의 유지보수에도 효율적일 것 같다는 생각이 든다.
service/PostServiceImple
@Override public Page < Post > getPostListByMember ( Member member , Pageable pageable ) { int page = ( pageable . getPageNumber ( ) == 0 ) ? 0 : ( pageable . getPageNumber ( ) – 1 ) ; pageable = PageRequest . of ( page , 10 , Sort . by ( “id” ) . descending ( ) ) ; return postRepository . findByMember ( member , pageable ) ; }
Page 인터페이스를 AbstractPageRequest라는 추상클래스가 구현하고, 이 추상클래스를 PageRequest라는 클래스가 상속받는 구조로 되어있다.
PageRequest.of()를 통해 새로운 PageRequest를 생성하여 리턴받는다.
postRepository 수정
@Repository public interface PostRepository extends JpaRepository < Post , Long > { public List < Post > findByMember ( Member member ) ; public List < Post > findByCategory ( Category category ) ; Page < Post > findByMember ( Member member , Pageable pageable ) ; }
JpaRepository는 Page를 리턴 타입으로 갖고, Pageable을 파라미터로 받는 메서드를 만들어주면 알아서 해당 Pageable의 정보를 갖고 Paging해서 리턴한다. 이는 JpaRepository 인터페이스가 PagingAndSoringRepository 인터페이스를 상속받고 있기 때문이다.
—
쓰다보니 너무 길어져
다음에 myPage/comments와 password에 대한 글을 포스팅해야겠다…
JAVA / SPRING 프로젝트 삼삼하개(3) 마이페이지(개인/업체) 내 작성글, 작성댓글 조회 구현
팀프로젝트가 끝나고 되돌아보는 시간 (3) 마이페이지(개인/업체) 내 작성글, 작성댓글 조회 구현
내 작성글, 작성댓글을 불러오는 페이지를 작업하면서 돌이킬수 없는 후회가 생겼습니다.
바로 테이블 설정..
구성 당시에는 먼 미래를 생각하며 각게시판을 카테고리화해서 구성하면 데이터가 많이 쌓였을때 성능저하가 생기지 않을까? 라는 의문으로 프로젝트를 구성할때 각 게시판 테이블을 따로 만들었는데(심지어 필드명도 다 다르게..)
우리는 빌드하여 프로젝트로만 활용할 뿐 실제 배포 및 운영은 계획이 없었기에 고려하지 않아도 되는 상황인데다가
검색 기능이나 이렇게 한번에 조회하는 페이지를 구현할때 불필요하게 동일한 코드를 여러번 적게끔 만들었습니다
이미 거의 막바지에 다와서 수정하면서 생긴 문제이기도 하고 고치게되면 한둘도 아니고 팀원 모두가 본인이 작성한 코드를 다 수정해야되었기에 그대로 적용하게 되었습니다
작성글 / 작성댓글 탭은 input type = radio 로 구현하였고,
데이터는 한번에 불러온 후 자바스크립트로 5개만 보이고 나머지는 숨김 처리하여 더보기 클릭시 5개씩 추가로 보이게 했습니다.
public String updatePOST (MemberVO vo) throws Exception {
l.info( “C: 회원정보수정 입력페이지 POST” );
service.updateMember(vo);
return “/member/main” ;
}
(value = “/delete” , method = RequestMethod.GET)
public String deleteGET (HttpSession session) throws Exception {
l.info( “C: 회원정보 삭제 GET” );
String id = (String) session.getAttribute( “id” );
if (id == null ) {
return “redirect:/member/main” ;
}
return “/member/deleteForm” ;
}
(value = “/delete” , method = RequestMethod.POST)
public String deletePOST (MemberVO vo, HttpSession session) throws Exception {
l.info( “C: 회원정보 삭제 POST” );
l.info( “C: deleteForm전달정보 ” +vo);
service.deleteMember(vo);
session.invalidate();
return “redirect:/member/main” ;
}
[Final Project] 마이페이지 기능 구현 정리
– 클래스 목록 resultmap
public class ClassVO { //이거 추가 private ClassPayInfoVO payinfo;
– MypageChefmapper.xml
-MypageChefDAOInter
package kr.co.ikosmo.mvc.dao; import java.util.List; import java.util.Map; import kr.co.ikosmo.mvc.vo.ClassVO; import kr.co.ikosmo.mvc.vo.Recipe_infoVO; public interface MypageChefDAOInter { //——————– //(쉐프)레시피 목록 – 페이징 //——————– public List getList(Map map); //페이징 처리 public int getTotalCount();//페이징 카운트 //—————– //(쉐프)클래스 목록 출력 //—————– public List getClassList(int mem_no);//클래스 리스트 //————————— //(쉐프)가 수강중인 클래스 목록 출력 //————————— public List getClassList_std(int mem_no);//쉐프가 수강중인 클래스 리스트 //———————– //(쉐프)statistic 숫자 카운트 //———————– public int getMyRecipeCount(Map map); //내 레시피 갯수 public int getMyReviewCount(Map map); //내 레시피에 달린 리뷰 갯수 public int getMyClassCount(Map map); //쉐프가 수강중인 클래스 갯수 public int getMyClientCount(Map map); //내가 진행중인 클래스를 듣는 고객의 수 public int getMyScrapCount(Map map); //스크랩한 레시피 갯수 public int getMyStarAvgCount(Map map); //내가 쓴 레시피의 별점 평균 }
– MypageChefDAOImple
package kr.co.ikosmo.mvc.dao; import java.util.List; import java.util.Map; import org.mybatis.spring.SqlSessionTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import kr.co.ikosmo.mvc.vo.ClassVO; import kr.co.ikosmo.mvc.vo.Recipe_infoVO; @Repository public class MypageChefDAOImple implements MypageChefDAOInter{ @Autowired private SqlSessionTemplate ss; //——————– //(쉐프)레시피 목록 – 페이징 //——————– @Override public List getList(Map map){ //nowPage등으로 연산이 된 start,end return ss.selectList(“mppc.listc”,map); } @Override public int getTotalCount() {//전체 데이터를 기준으로 페이지를 나눌것이기 때문에.. return ss.selectOne(“mppc.totalCountc”); } //—————– //(쉐프)클래스 목록 출력 //—————– @Override public List getClassList(int mem_no) { //클래스 리스트 출력 return ss.selectList(“mppc.classlistC”, mem_no); } //————————— //(쉐프)가 수강중인 클래스 목록 출력 //————————— public List getClassList_std(int mem_no) {//쉐프가 수강중인 클래스 리스트 return ss.selectList(“mppc.classlist_std”, mem_no); } //———————– //(쉐프)statistic 숫자 카운트 //———————– @Override public int getMyRecipeCount(Map map) { //내 레시피 갯수 return ss.selectOne(“mppc.myRecipeCount”, map); } @Override public int getMyReviewCount(Map map) { //내 레시피에 달린 리뷰 갯수 return ss.selectOne(“mppc.myReviewCount”, map); } @Override public int getMyClassCount(Map map) { //쉐프가 수강중인 클래스 갯수 return ss.selectOne(“mppc.myClassCount”, map); } @Override public int getMyClientCount(Map map) { //내가 진행중인 클래스를 듣는 고객의 수 return ss.selectOne(“mppc.myClientCount”, map); } @Override public int getMyScrapCount(Map map) { //스크랩한 레시피 갯수 return ss.selectOne(“mppc.myScrapCount”, map); } @Override public int getMyStarAvgCount(Map map) { //내가 쓴 레시피의 별점 평균 return ss.selectOne(“mppc.myStarAvgCount”, map); } }
– MypageChefController
[Spring] 쇼핑몰 프로젝트(4)
<개인 정보 확인>
개인정보는 Controller까지만 작성해된다.
왜냐면 이미 로그인한 session에 로그인한 user의 회원가입 정보가 담겨있기 때문이다.
<정보 수정>
정보 수정 또한, 기존의 데이터를 수정하는 것이기 때문에 session을 가져와 session.setAttribute(“member”, m);처럼 수정한 새로운 정보를 member에 담아준다. jsp에서는 ${member.userId}이런 식으로 값을 출력
<회원 탈퇴>
수정할때는 session을 받아오고 밑에서 따로 꺼내왔는데 매개변수에 @SessionAttribute(“member”) Member m을 사용해서 한번에 session 꺼내와서 담기 가능하다.
@SessionAttribute는 HttpSession에 저장되어있는 값을 Handler의 매개변수에 맵핑해주는 어노테이션이다.
이번에는 마이페이지를 구현해보도록 하겠습니다.
마이페이지를 구현할 때, 마이페이지 에는 내가 쓴 글을 같이 확인 하기 위해서 테이블의 Join 을 한번 해보도록 할 겁니다.
마이페이지 구현
위 처럼 확인 할 수 있도록 할 건데요
먼저 테이블의 JOIN 이 있다는 걸 알아야 합니다.
즉. User 의 개인정보를 가지고 있는 테이블, 게시판에 대한 테이블 을 JOIN 합니다.
그러려면 JOIN 에 대한 기본 지식을 알고 있어야 합니다. LEFT OUTER JOIN, INNER JOIN 등등…
JOIN 은 이런 식으로 수행하면 되는데요
두 테이블의 병합 이기 때문에, 값을 받아주는 곳에서 문제가 생깁니다.
바로, 유저는 1개지만, 게시판에 대한 정보가 여러개가 될 수 있겠죠?
즉. 1 : N 의 관계가 되어 버립니다.
그래서 값을 가지고 나올 때, 1 의 관계를 가지는 UserVO 에 N 의 관계를 가지는 FreeBoardVO 를 List 로 추가 합니다.
※ Lombok 을 사용 중 ( setter, getter, 생성자 자동 생성 )
그러면, 문제는 List 로 들어가는 게시판에 대한 정보를 어떻게 넣어주냐 는 것인데요
resultMap 을 이용하면 됩니다.
resultMap 을 이용하면, 각각의 변수를 의 property, column 을 통해서 데이터를 넣어주어야 합니다.
이 때, 게시판에 대한 정보는 List 로 되어 있기 때문에, 한번 더 resultMap 을 이용해서 타고 들어 갑니다.
이렇게 완료했다면, 가지고 나온 데이터를 컨트롤러에서 저장한 후 , 화면에서 뿌려주면 됩니다.
키워드에 대한 정보 spring 마이 페이지
다음은 Bing에서 spring 마이 페이지 주제에 대한 검색 결과입니다. 필요한 경우 더 읽을 수 있습니다.
이 기사는 인터넷의 다양한 출처에서 편집되었습니다. 이 기사가 유용했기를 바랍니다. 이 기사가 유용하다고 생각되면 공유하십시오. 매우 감사합니다!
사람들이 주제에 대해 자주 검색하는 키워드 [자바 웹을 다루는 기술] 31.11 마이 페이지 구현하기
This website uses cookies so that we can provide you with the best user experience possible. Cookie information is stored in your browser and performs functions such as recognising you when you return to our website and helping our team to understand which sections of the website you find most interesting and useful.
Strictly Necessary Cookies
Strictly Necessary Cookie should be enabled at all times so that we can save your preferences for cookie settings.
If you disable this cookie, we will not be able to save your preferences. This means that every time you visit this website you will need to enable or disable cookies again.