문제상황

 

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폴더를 새로 만드는 것과도 같다.

주문(order)엔티티클래스파일에서

실습

 

order_id

-DB컬럼의 id이름을 테이블명으로 가져와 테이블명_id형태로 설정해준다.

DBA포지션 엔지니어가 이러한 형태로 설정해주는 것을 원한다.

 

참고

엔티티의 식별자는 id를 사용하고 PK 컬럼명은 member_id를 사용했다. 엔티티는 타입(여기서는 Member)이 있으므로 id 필드만으로 쉽게 구분할 수 있다. 테이블은 타입이 없으므로 구분이 어렵다. 그리고 테이블은 관례상 테이블명 + id를 많이 사용한다. 참고로 객체에서 id 대신에 memberId를 사용해도 된다. 중요한 것은 일관성이다.

 

-@ManyToOne : 주문과 회원의 관계, 다대 1관계를 설정해주는 어노테이션

-@JoinColumn(name = "member_id")

*@JoinColumn 어노테이션은 외래 키를 매핑 할 때 사용

*name 속성에는 매핑 할 외래키(연관관계주인) 이름지정

-member_id = foregien key(외래키)

-주문회원테이블에서 주문회원에 대한 정보를 매핑

 

 

 

회원엔티티클래스(RealMember)에서

어노테이션 설정

-@OneToMany : 회원과 주문의 관계, 1대 다 관계를 설정해주는 어노테이션

-@OneToMany (mapped by = "member")

*foreign key가 있는 order클래스에 있는 member가 연관관계의 주인이다.

*mapped by - order 테이블에 있는 member필드에 의해 맵핑된 거울일 뿐이야라는 뜻

*여기에 무엇을 넣는다고 해서 order에 있는 member필드의 foreign key 값이 변경되지

 않는다.

*order엔티티클래스에 있는 order테이블에 있는 member필드 값을 변경하면

 member_idforeign key 값이 변경된다.

 

 

연관관계의 주인설정이 필요한 이유

연관관계 맵핑 분석을 다시 확인해보자

회원과 주문

-회원도 오더로 갈 수 있고, 오더도 회원으로 갈 수 있도록 설계 했다.(양방향 연관관계)

-일대다, 다대일의 양방향 관계다. 따라서 연관관계의 주인을 정해야 한다.

 관계형데이터베이스에서는 1대 다의 관계에서는 다에 무조건 외래키가 있게 된다.

 외래 키가 있는 주문을 연관관계의 주인으로 정하는 것이 좋다.

 

이유

-주문클래스에서 멤버값을 바꾸거나, 멤버클래스에서 오더값을 바꿀 수도 있기 때문에

 JPA는 혼란스러울 수 있다.

-회원엔티티로 본다면 Order도 멤버정보를 가지고 있고, Member도 주문정보를 가지고 있

 다. 데이터베이스에서 MemberOrder테이블에서 볼 때에 foreign keyOrder테이블에

 한 개 밖에 없는 상태이다.

-추후 일어날 수 있는 문제라고 한다면, 회원과 주문테이블 관계를 바꾸고 싶을 때 foreign

 key를 변경해야 하는 상황에 처하게 된다.

-Member테이블에도 orders라는 컬렉션 필드가 있는거고, Order테이블에도 member라는

 필드가 있어 JPA에서는 둘다 정보를 확인해서 값을 바꾸어야 하나라는 혼란에 빠진다.

 즉, 어디에 값이 바뀌었을 때 foreign key를 바꾸어야 하는지에 대한 혼란을 겪게 된다.

-극단적으로 Order엔티티에서는 member 값을 세팅했는데, Member엔티티에서 order 값을

 세팅 안한다던가, Member엔티티에서는 order값을 넣었는데, Order엔티티에서는 member

 값을 안넣었다던가 하는 경우가 생기면, JPA는 둘중에 무엇을 믿고 order테이블의 foreign

 key 값을 업데이트를 해야 하지?라고 혼란을 겪는다.

 

여기서 foreign keyupdate하게 하기 위해서 JPA에서 둘중에 하나를 선택하라고 약속을 했다. 엔티티에서의 객체는 변경 포인트가 두군데이지만, 테이블은 foreign key하나만 변경하면 되기 때문에, 쉽게 맞추기 위해 규칙을 정했다.

둘중에 하나를 주인이라는 개념으로 잡으면 되는데 이것이 연관관계의 주인이다.

Member엔티티에서 ordersOrder엔티티에서나 member중에 값이 바뀌었을 때에 foreign key를 바꿀 거야 라는 것을 결정을 하는 것이 연관관계의 주인이다.

 

그렇다면 연관관계의 주인은 누구로 하는가?

-foreign key가 가까운 테이블(Order)을 확인하고 Member_id를 연관관계주인이 있는 곳으

 로 맵핑을 하면 된다.

-Order엔티티의 member가 가까우니 여기를 연관관계주인으로 정한다.

-이렇게 하지 않으면 member의 무언가를 바꾸었는데, Order테이블에 무언가/foregin키가

 업데이트 되어버려서 있는 의도치 않은 일이 일어난다. 성능이슈가 생길 수도 있다.

 Member정보를 변경했는데, orders의 값이 바뀌지하고 헷갈리게 되어버린다.

-foreign key가 있는 Order테이블에 있는 member를 바꾸니까 order테이블에 있는 컬럼이

 바뀌는구나 하고 이해하기도 관리하기도 쉬워진다. 이렇게 규칙을 정하지 않으면 Member

 보를 변경했는데, orders의 값이 바뀌지하고 헷갈리게 된다.

1.4 연관관계 맵핑 분석

회원과 주문

-회원도 오더로 갈 수 있고, 오더도 회원으로 갈 수 있도록 설계 했다.(양방향 연관관계)

-일대다 , 다대일의 양방향 관계다. 따라서 연관관계의 주인을 정해야 한다.

 관계형데이터베이스에서는 1대 다의 관계에서는 다에 무조건 외래키가 있게 된다.

 외래 키가 있는 주문을 연관관계의 주인으로 정하는 것이 좋다.

 그러므로 ORDERS 엔티티에 있는 MEMBER가 연관관계의 주인이 되고,

 MEMBER엔티티의 ordersmapped by로 단순 읽기만 가능한 연관관계의 거울 즉 단순

 조회용으로만 이용한다.

-연관관계의 주인쪽에 값을 세팅해야 값이 변경된다.

 거울쪽값은 단순조회용이다.

 

-일대다, 다대일의 양방향 관계다. 따라서 연관관계의 주인을 정해야 하는데,

 외래 키가 있는 주문을 연관관계의 주인으로 정하는 것이 좋다.

 그러므로 Order.memberORDERS.MEMBER_ID 외래 키와 매핑한다.

 

*쉽게 얘기하면 주문이 한 개만 있는 것이 아니라 많아질 수 있다고 할 때에

주문쪽에서 PK생성으로 멤버를 참조하여야 하므로 1(MEMBER) (ORDERS)의 관계라고

할 수 있다. 주문측이 갑, 주인이 된다.

 

주문상품과 주문

-한번 주문할 때 주문수량과 주문수량에 따라 가격이 달라질 수 있기 때문에

 주문상품을 두게 된다.

-다른 사람이 주문한 정보가 주문상품에 있을 수 없다.

 주문한상품들이(OrderItem)에는 주문할 때 하나의 Order에만 연관관계가 걸린다.

 주문상품들의 정보들이 OrderItem : List에 오게 된다.

 그래서 다대(ORDERS_ITEM)1(ORDERS)관계가 된다.

 

->다대일 양방향 관계다. 외래 키가 주문상품에 있으므로 주문상품이 연관관계의 주인이다.

   그러므로 OrderItem.orderORDER_ITEM.ORDER_ID 외래 키와 매핑한다.

 

*연관관계 매핑 분석할 때에

-서비스의 특성과 일반적인 관계를 알고, 일반적으로 접근해볼 것

-외래키가 있는 곳이 연관관계의 주인

 

주문상품과 상품

-itemorderitem에서 의 정보를 맵핑 할 것이 없다.

-나를 주문한 orderitem을 찾아 할필요가 없고,

 orderitem을 찾고 싶을 때에 루트를 orderitem으로 쿼리를 찍으면 된다.

 즉, orderitem에서 item정보만 잘 맵핑해주면 된다.

->다대일 단방향 관계다. OrderItem.itemORDER_ITEM.ITEM_ID 외래 키와 매핑한다.

   주문과 배송

-일대일 양방향 관계다. Order.deliveryORDERS.DELIVERY_ID 외래 키와 매핑한다.

-주문정보에 배송정보가 들어가고 OrdersDelivery_ID(PK)가 넣어 두었다.

 

-DELIVERY_ID가 있는 외래키와 매핑하면 Orders가 연관관계의 주인이 된다.

 

카테고리와 상품

-@ManyToMany를 사용해서 매핑한다.

 (실무에서 @ManyToMany는 사용하지 말자. 여기서는 다대다 관계를 예제로 보여주기 위

 해 추가했을 뿐이다)

-편법이 아닌 정상적인 방법으로는 테이블관계는 ManyToMany로 표현할 수 있는 방법이

 없기 때문에, CATEGORY_ITEM 중간테이블로 풀어낸다..

 

카테고리와 상품관련하여 앞에서의 내용과 같은 내용

-객체에서는 카테고리가 아이템리스트를 가져도 되고

 아이템이 카테고리리스트를 가져도 된다.

 양쪽 컬렉션을 만들면 객체는 다대 다로 만들 수 있지만

 관계형데이터베이스는 일반적 설계로는 그렇게 할 수 없다.

 중간에 매핑 테이블(CATEGORY_ITEM)을 두어,

1(CATEGORY) (CATEGORY_ITEM) 관계 및 다대(CATEGORY_ITEM) 1(ITEM)로 풀어

낸다.

 

참고

-외래 키가 있는 곳을 연관관계의 주인으로 정해라.

 연관관계의 주인은 단순히 외래 키를 누가 관리하냐의 문제이지 비즈니스상 우위에 있다고

 주인으로 정하면 안된다..

-예를 들어서 자동차와 바퀴가 있으면, 일대다 관계에서 항상 다쪽에 외래 키가 있으므로

 외래 키가 있는 바퀴를 연관관계의 주인으로 정하면 된다.

 

주의 (연관관계를 잘못 설정하게 되면 생기는 현상)

-물론 자동차를 연관관계의 주인으로 정하는 것이 불가능 한 것은 아니지만,

 자동차를 연관관계의 주인으로 정하면 자동차가 관리하지 않는 바퀴 테이블의 외래 키 값이

 업데이트 되므로 관리와 유지보수가 어렵고, 추가적으로 별도의 업데이트 쿼리가 발생하는

 성능 문제도 있다. 자세한 내용은 JPA 기본편을 참고하자.

 

1. resources -> templates -> application.yml생성

yml 또는 properties를 사용하면 된다.

설정파일이 복잡해지면 yml이 더낫다.

여기에서는 application.yml을 생성하고

기존에 있던 application.properties삭제 한다.

 

*YAML이란 (위키백과 참고)

- XML, C, 파이썬, , RFC2822에서 정의된 e-mail 양식에서 개념을 얻어 만들어진

  '사람이 쉽게 읽을 수 있는' 데이터 직렬화 양식

-XMLJSON이 데이터 직렬화에 주로 쓰이기 시작하면서,

 많은 사람들이 YAML'가벼운 마크업 언어'로 사용하려 함

 

*PROPERTIES이란 (위키백과 참고)

-응용 프로그램의 구성 가능한 파라미터들을 저장하기 위해

 자바 관련 기술을 주로 사용하는 파일들을 위한 파일 확장자

-더 복잡한 설정 포맷을 원할 경우 XMLYAML이 사용된다.

 

2. Database connection : 데이터베이스 소스 설정

a. spring 세팅

datasource :

  url: (상기사진내용참고)

  username: sa

  password: 

  driver-class-name: (상기사진내용참고)

(주의: 칸 띄어쓰기가 제대로 되어 맞춰지지 않는다면 테스트시 에러발생할 가능성이 크다!!)

 

설명

application.yml 안에

하기와 같이 설정하게 되면

데이터베이스 연결과 관련된 데이터소스설정이 완료 된다.

[url: jdbc:h2:tcp://localhost/~/jpashop;MVCC=TRUE]

 

*MVCC TRUE

-> 여러개가 접근할 때 조금 더 빨리 처리가 된다. 넣어주는 것이 권장.

*스프링부트에서 hikaricp를 써서 데이터베이스 커넥션 풀 등 위의 세팅이 이루어지게 한다.

 

b. JPA 세팅

 hibernate:

  ddl-auto: create

 properties:

hibernate:

 #show_sql: true

    format_sql: true

 

*createtab을 자동생성해주는 역할을 한다.

application 실행시점에 내가가지고 있는 엔티티(테이블)정보를 전부 다 지우고,

다시 생성한다.

*properties (*hibernate와 관련된 특정한 properties 사용할 것을 여기에다가 타입한다.)

*설정하는 것을 어떻게 배우느냐

spring bootreference document를 참고해서 하나하나씩 공부해야 한다.

https://docs.spring.io/spring-boot/docs/2.2.6.RELEASE/reference/html/

Data Access ->configure JPA Properties를 찾아서 읽어볼 것!

 

c. LOG LEVEL세팅

logging:

   level:

    org.hibernate.SQL: debug

 

(주의 : 잘 안될 경우, logging.level:로 세팅할 것!)

 

*hibernate.SQLdebug모드로 사용한다는 의미가 있고,

jpahibernate가 생성하는 SQL전부 확인이 가능하다.

 

show_sqlorg.hibernate.SQL의 차이점

jpa:

show_sql: true

->system.out에 출력하는 것. 그래서 주석처리를 하여 사용하지 않도록 한다.

운영환경에서는 사용하지 않는다.

 

logging:

org.hibernate.SQL: debug

->log on을 통해 출력하는 것. 운영환경에서는 로그들을 log on을 통해 출력해야 한다.

 

스프링과 Thymeleaf

-view 환경 설정하는데 Thymeleaf엔진을 사용할 것이다.

-스프링은 Thymeleaf를 권장하는 편이고,

Thymeleaf도 스프링과 관련된 지원하는 기능들이 많다.

-스프링에서 권장하는 Template Engines

(Apache Freemarker, Mustache, Groovy Templates)

 

Thymeleaf Templates Engine

-웹과 standalone 환경을 위한 modern 서버사이드 자바 템플릿 엔진

*https://www.thymeleaf.org/ Thymeleaf 공식 홈페이지 참고

 

Thymeleaf 의 장점

-마크업을 깨지고 않고 그대로 사용 한다.

-보통 다른 Engine은 웹브라우저에서 열리지 않지만, Thymeleaf는 열린다.

-버전 2에서는 <BR></BR> 태그를 달아주는 스타일로 매칭해주지 않으면 에러가 났었지만

현재 버전 3.0에서는 <BR>작성해도 에러가 발생하지 않는다.

 

Thymeleaf 의 단점

-아직 그래도 불편한점이 있기 때문에 매뉴얼을 참고하면서 개발을 해야 한다.

 

 

스프링 

-스프링 공식 가이드

https://spring.io/guides/

-스프링 관련하여 개념이 혼란스러울 때에는 공식 가이드에서 검색을 통해

개념을 익히면 좋다.

*Serving Web Content with Spring MVC 검색을 해서 나와 있는 가이드 대로

따라해보면 좋다.

-스프링부트 매뉴얼 : 에러핸들링이나 기능이용시 궁금한점들을 공부할 수 있다.

https://docs.spring.io/spring-boot/docs/2.1.6.RELEASE/reference/html/boot-features-developing-web-applications.html#boot-features-spring-mvc-template-engines

 

Thymeleaf Template Engine을 위해 세팅해야 할 것은?

-스프링부트에서는 하기의 것을 이미 설치함으로,

자동으로 모든 세팅이 전부 되어 있으므로 오직 개발만 하면 된다.

org.springframework.boot:spring-boot-starter-thymeleaf

 

실습

스프링 부트 thymeleaf viewName 매핑

설명

-@Controller를 해줌으로써 annotation은 달아주어야 한다.

-@GetMapping(“hello”)라는 url로 오면 controller가 호출된다라는 뜻

-스프링 ui에 있는 Modelmodel에다가 어떤 데이터를 실어서 controller에서

  view로 데이터를 보낼 수 있다.

-attributeName"data"라는 키의 값(attributeValue)hello로 넘긴다.

-returnhello는 화면이름이다.

 spring initializer가 만들어 놓은 resources 안에 templates->new->file

 view name용으로 hello.html 생성한다.

 hello.html 파일생성후 추후 보이지 않아도 return hello.html 형태로 변환한다.

-return hello결과가 화면렌더링 할 때에 hello.html 화면으로 이동한다.

 

Thymeleaf 템플릿엔진 동작 확인(hello.html)

설명

-<html>xmlns:th(네임스페이스)"http://www.thymeleaf.org" 주었다.

-<p th:text${data}로 아까 hello라고 적어 두었던 데이터가 넘어온다.

  데이터(hello) 렌더링 된 것이 >안녕하세요. 손님</p>로 넘어간다.

 

 

내부경로를 인터넷주소칸에 입력해서 hello.html에 접속 및 소스코드확인

설명

-다른 template engine이면 if절부터 들어가는 것이 많은데

 thymeleaf template engine은 간결한 코드구성으로 화면렌더링이 가능하다.

 

 

서버사이드 렌더링=스프링부트메인실행

 

-스프링부트가 내장톰캣을 가지고 실행시킨다.

 

#마주한문제

hello.html 화면이 위에처럼 나와야 하는데 처음에는 나오지 않아 무엇이 문제인지 확인했다.

해본 것들

1. cmd창에서 실행한 프로세스를 taskkill /f /pid 프로세스넘버를 통해 종료

   ->실행 안됨

2. hello.html에서 복붙 없이 직접 작성해서 넣었기 때문에 확인해 보았더니

   두 번째 라인에 <html 안에 “ / ” 가 있어서 삭제하고

  <html xmlns:th="http://www.thymeleaf.org"> 로 수정

   -> 실행안됨..

3.서버사이드렌더링하는 스프링부트메인파일과 Hello.Controller파일이 같은 폴더내에 있는지 확인했더니, test폴더안에    있었다..

  스프링부트메인파일이 있는 jpabook.jpashop으로 Hello.Controller파일을 이동

->화면이 보인다.

해결!!!

 

 

어떻게 데이터 hellohello.html에 찾아가는건가?

화면렌더링 경로

 

>HelloController

attributeName인 데이터의 attributeValuehellohello.html에 있는 ${data}로 넘어간다.이때 찾아서 가는 요인은 HelloControllerreturn hello이 화면렌더링 할 때에 hello.html로 화면이 넘어가도록 한다.

 

서버사이드템플릿엔진이 내장톰캣 실행시킬 때에

스프링부트 thymeleaf viewName 매핑을 하기처럼 해주어서

resources:templates/ +{ViewName}+ .html

데이터 hellohello.html을 최종적으로 찾아갈 수 있게 된다.

 

 

127.0.0.1:8080 메인 화면에 정적화면 구현해보기

resources->static->file만들기->index.html 파일생성

*resource 폴더에 파일이 생성되었기 때문에 기본적으로 서버를 다시 실행시켜주어야 한다.

설명

href 가 데이터 hello로 넘어가는 하이퍼링크 역할을 한다.

*127.0.0.1:8080/hello에서 hello@GetMapping(“hello")url hello 역할을 한다.

 

 

devtools 라이브러리 역할

-html화면을 수정해야 할 일이 많은데 그때 마다 서버를 리스타트 하면 힘드니

 spring-boot-devtools 라이브러리를 추가한다.

-이 라이브러리가 cache제거와 reloading을 되게 해주는 역할을 한다.

 *build.gradle->dependencies->spring-boot-devtools추가->reimport

 

devtools추가후 다시 서버리스타트하면 restartedMain이라고 뜬다.

 

 

devtools와 recompiler를 이용한 수정화면

#마주한 문제 2

devtools 라이브러리가 설치되었다는 restartedmain 화면이 안보여서

계속 찾아보았더니.. spring-boot-starter-devtools로 되어 있었다.

spring-boot-devtools로 수정하고 reimport, 서버restart를 하니 작동이 된다.

 

 

View환경설정 끝!!!

+ Recent posts