회원목록조회

 

1.MemberController클래스에서 멤버조회하도록 MemberList.html구문작성

 

사진

 

사진, *변수를 합쳐 단축시켜주는 refactor inline 기능 (ctrl + alt + n)

*타임리프의 장점

-html 태그를 그대로 가져다 사용한다.

-MemberController클래스에서 작성한 List<member>구문에 있는 model에서 members를 담아서 사용한 것을 그대로 

 memberList.html파일로 가져와서 binding이 된다. 그래서 그대로 출력하는 구문만 작성하면 된다.

 

타임리프에서 address?

-null이면 그대로 진행 안한다는 의미

 

마주한 문제(회원목록화면 출력이 안된다.)

에러메세지 발생

-에러메시지만 보았을 때는 이해가 안된다..

가설1

MemberControll클래스에서 return "user/userList"으로 해주어서 출력이 안되었을 것이다.

 

결과- 그대로

 

가설 2

회원이름 입력을 하지 않았을 때에 submit을 누르면

필수항목입니다 메시지가 나오는지 재확인 및 재작동됨을 확인했다.

 

이름을 우리나라말로 바꾸어 보았다. submit이 되고 처음화면으로 redirect가 된다.

처음엔 hello1 로 했었는데. 영어 또는 숫자 입력이 안되게 구문을 작성한 것으로 짐작했지만

h2.database에 들어가니 정보가 입력이 되어 있다.

 

가설 3

회원목록이 나오지 않는다는 것은 못받아 온다는 뜻이라고 가설을 세웠다.

GetMapping(“ members/”)에서 /members로 바꾸어 보았다...

 

결과-동일한 에러

 

가설 4

회원목록이 나오지 return 으로 memberList가 받아 오지 못한다고 가설을 세웠다.

확인해보니 return("members/memberList")로 괄호안에 설정 되어 있었다.

return "member/memberList"; 로 수정완료

 

그래도 에러가 나온다.

 

가설5

다시 회원목록조회 구문을 잠시 주석처리하니,

회원가입시 작성하였던 데이터가 Member 테이블에 잘 나오고 에러도 없다.

 

회원가입 항목을 작성하니 에러가 나오고

member_id를 처음 데이터 작성한 첫행으로 인식을 하여

현재 보유한 데이터가 7개이면 회원가입작성 및 submit후에 에러가 나오고 8번을 새로고침해야 작성한 내용이 데이터베이스에 들어가있음을 확인함.

 

현재 application.yml에서 ddl-auto(초기화옵션)은 create이고,

create는 엔티티자체를 전부 없애고 다시 새로 만들어주는 역할이니 그러한 현상이 발생하는 것으로 짐작하여 update로 변경해주었다.

 

결과-회원가입작성은 잘된다.

 

가설6

-회원목록을 클릭하면 회원가입작성페이지가 나온다.

-home.html 파일에 들어가서 확인을 했다.

<p class="lead">회원 기능</p>

<p>

<a class="btn btn-lg btn-secondary" href="/members/new">회원가입</a>

<a class="btn btn-lg btn-secondary" href="/members/new">회원목록</a>

</p>

로 회원가입과 동일하게 하이퍼텍스트 리퍼런스가 동일하게 되어 있다.

-<a class="btn btn-lg btn-secondary" href="/members">회원목록</a> 으로 수정

 

회원목록출력성공 완료

 

사진

 

권장사항

엔티티를 폼으로 사용하면 화면 종속적 기능이 되어버려서

엔티티가 지저분해지게 된다. 유지보수가 하기 어려워진다.

핵심 로직을 수정하니 화면이 나오지 않는다라는 상황이 발생한다.

엔티티는 순수하게 유지하라는 얘기가 있음.

 

jpa 사용할 때 조심해야 하는 것은 순수하게 간결하게 엔티티를 작성해야 한다.

핵심 비즈니스로직에만 디펜던시가 있도록 작성해야 한다.

그래야 어플리케이션을 만들어도 더 커지지 않는다. 유지보수하기가 좋아진다.

 

엔티티 대신 폼객체나 DTO(Data Transfer Object)권장을 한다.

회원등록할때에는 MemberForm객체를 사용했는데 데이터를 memberList로 보낼 때에는 Member로 보낸다.

 

권장사항2

api를 만들 때에는 엔티티를 절대 외부로 반환하면 안된다. api는 스펙이기 때문이다.

 

예를 들어 패스워드가 그대로 노출(private String userpassword;)될 수도 있고,

엔티티의 로직을 변경했는데 api스펙이 변하게 된다. 그래서 api를 만들 때에는 엔티티를 절대 외부로 반환하면 안된다.

 

사진

문제상황

 

1.RealMember 클래스이름을 다시 기억하기 쉽게 Member이름으로 변경(테스트용 Member클래스파일은 바로삭제)

연동되는 클래스파일이름을 RealMember로 안해주고 그냥 Member를 사용한상태로 테이블을 생성했었었다.

그리고, 다시 기존 Member 클래스파일을 지우고 RealMember 클래스파일 이름을 MemberRENAME으로 바꿔주었다.

 

2. 의문점

이미 한번 과거 Member 안에 작성된 코드를 이용해서 생성된 테이블 을 한번 만들어줬다가

이름만 바꿔서 코드내용 바꿔주어서 다시 생성하면 변경된대로 적용되는지 궁금하다.

 

3. 디비 h2 맞고, 연동도 되어 있다.

H2 데이터베이스 콘솔접속해서 테이블들을 확인해보니 RealMember는 그대로 있고 Member도 그대로 있다.

테이블에서는 영향을 미치지않아 내가 직접 drop해주어야 하는 건지 모르겠다.

 

문제해결시도과정

1. 이름이 변경된 Member클래스에서 Member를 import 설정

Build completed with 2 errors and 0 warnings in 11 s 105 ms

빌드하는 과정에서 에러가 두가지 있었는데 Memberimport를 해주었다.

바로 밑에 코드 에도 (Member)로 설정

 

 

2.초기화옵션 ddl-auto:create, 데이터베이스에서 기존 Member 테이블 삭제시도

 

사진

 

ddl-auto:create옵션인 상태에서 h2 데이터베이스 접속해서 기존 MEMBER 테이블 삭제하려고 하니

다음과 같은 에러가 나온다.

------------------------------------------------------------------------

Cannot drop "MEMBER" because "FKPKTXWHJ3X9M4GTH5FF6BKQGEB" depends on it; SQL statement:

DROP TABLE member [90107-200] 90107/90107 (도움말)

org.h2.jdbc.JdbcSQLSyntaxErrorException: Cannot drop "MEMBER" because "FKPKTXWHJ3X9M4GTH5FF6BKQGEB" depends on it; SQL statement:

DROP TABLE member [90107-200]

at org.h2.message.DbException.getJdbcSQLException(DbException.java:576)

at org.h2.message.DbException.getJdbcSQLException(DbException.java:429)

at org.h2.message.DbException.get(DbException.java:205)

at org.h2.command.ddl.DropTable.prepareDrop(DropTable.java:98)

at org.h2.command.ddl.DropTable.update(DropTable.java:124)

at org.h2.command.CommandContainer.update(CommandContainer.java:198)

at org.h2.command.Command.executeUpdate(Command.java:251)

at org.h2.server.TcpServerThread.process(TcpServerThread.java:406)

at org.h2.server.TcpServerThread.run(TcpServerThread.java:183)

at java.lang.Thread.run(Unknown Source)

 

at org.h2.message.DbException.getJdbcSQLException(DbException.java:576)

at org.h2.engine.SessionRemote.done(SessionRemote.java:611)

at org.h2.command.CommandRemote.executeUpdate(CommandRemote.java:237)

at org.h2.jdbc.JdbcStatement.executeInternal(JdbcStatement.java:228)

at org.h2.jdbc.JdbcStatement.execute(JdbcStatement.java:201)

at org.h2.server.web.WebApp.getResult(WebApp.java:1459)

at org.h2.server.web.WebApp.query(WebApp.java:1116)

at org.h2.server.web.WebApp$1.next(WebApp.java:1078)

at org.h2.server.web.WebApp$1.next(WebApp.java:1065)

at org.h2.server.web.WebThread.process(WebThread.java:178)

at org.h2.server.web.WebThread.run(WebThread.java:94)

at java.lang.Thread.run(Unknown Source)

------------------------------------------------------------

 

-여기에서 내가 확인하고 이해한 에러 핵심은 다음과 같다.

-일단 MEMBER 테이블을 삭제할 수 없다. 그리고 Unknown Source 알려지지 않은 소스 Cannot drop "MEMBER"....

.

.

at java.lang.Thread.run(Unknown Source)

 

-기존에 MEMBER클래스파일을 삭제해서 테이블에서도 찾아내지 못해 삭제하지 못하는 것이라는 가설을 세웠다.

 

2. Real_Member 테이블 삭제 시도

-DROP TABLE Real_Member;

-지워진다..

-이것은 Real_Member 이름을 가진 클래스파일을 인식해서인지 삭제가 되었다.

-다시 h2 데이터베이스 재접속 상황은 같다.

 

3. 기존 MEMBER 클래스 파일을 다시 만들어서 삭제한다?

-이미 RealMember클래스파일 이름을 MEMBER파일로 바꾸었는데 다시 만들어서 테이블삭제는 말이 안되었다.

이미 변경한 MEMBER클래스파일은 어떻게 한단 말이지..

 

4. 테이블삭제시도전에 코드를 run하는 과정에서 drop if exists 문구와 error executing ddl를 확인한 것이 기억났다.

 

출처 https://galid1.tistory.com/610

구글링 해보니, 초기화 옵션을 (ddl-auto: update)update로 해주면 에러가 해결된다는 내용이 있었다.

물론 나와는 상황이 조금 달랐지만, 혹시 테이블도 update 되지 않을까 하는 생각으로 변경해주고 다시 테이블 설정을 했다.

 

 

결과는 클래스파일 RealMember에서 RENAME으로 변경한 Member클래스파일에 작성된 컬럼들이 생성됨을 확인했다. 즉 새롭게 변경해준 Member클래스파일 내용으로 update가 되었다.

 

5.기존에 있던 ID, USERNAME은 그대로 존재한다. 기존에 있는 컬럼에 합쳐진 것 같다.

 

맴버테이블을 연관관계없이 생성한 상태일 때에 삭제가 안될 수도 있다고 하여,

기존 멤버테이블 컬럼삭제된 상태에서, 테이블을 삭제 시도 해보았다.

 

하기와 같은 명령어를 이용해 ID, USERNAME을 삭제했다.

ALTER TABLE MEMBER

DROP COLUMN USERNAME;

 

삭제가 되어 현재 변경된 Member클래스 내용과 동일한 내용으로 업데이트하여 해결완료!

 

7.이왕 삭제하는 김에 테이블전부 삭제하고 다시 생성하기로 했다. (ddl-auto : create)

 

*맴버테이블을 연관관계없이 생성한 상태일 때에 삭제가 안될 수도 있다고 하여,

만약 연관관계가 있는 상태에서 삭제가 되지 않는다면 하기 명령어로 해볼 것

 

DROP TABLE : 테이블의 모든 데이터 및 구조를 삭제

-DROP TABLE 테이블명 [CASACADE CONSTRAINT];

 

기타공부내용

기타해결방법(기존 member 클래스파일을 realmember로 변경할 경우에 사용할 것)

-삭제된 member는 이제 더 이상 jpa가 관리하는 persist에 의해 영속성을 가지지 못하고

그냥 orm과는 관계 없고, 자바와는 관계없는 분리된 db테이블이 됨

더 이상 사용되지 않는 테이블이 되었다.

 

ddl-auto : create (ddl-auto옵션은 create)

멤버랑 리얼멤버 테이블을 drop시키고 다시 테이블을 새로 생성해도 무방하다.

의존성을 가진다면 테이블 스페이스를 전체를 다 날려버리면,

스프링이 재시작 될 때에 처음부터 다시 전체 테이블을 만들어줄 것이다.

바뀐 멤버엔티티에 영속성이 걸리게 되고, 연관관계매핑도 작성된대로 설정이 된다.

 

이해를 위한 ddl-auto : create옵션 추가설명

-예를들어, jpashop이라는 폴더를 만들고 그안에 member라는 폴더를 만들고 파일도 있다.

근데 이름을 realmember로 바꾸려하면 create 옵션은

기존 member는 그대로 냅두고 realmember폴더를 새로 만드는 것과도 같다.

+ Recent posts