본 포스팅은 Slipp - Spring-Boot, JPA로 질문/답변 게시판 구현 과정을 참조하여 작성한 내용입니다. 개인적 학습 내용을 복습하기 위한 내용이기 때문에 내용상 오류가 있을 수 있습니다. 소스코드의 자세한 내용은 https://github.com/walbatrossw/boot-qna 를 참조해주세요.
3. slipp 반복주기 3
데이터베이스에 사용자 데이터 추가
개인정보 수정 기능 구현
질문하기, 질문목록 기능 구현
3-1) QnA HTML 템플릿, H2 데이터베이스 설치, 설정, 관리툴 확인
QnA 템플릿 추가
H2 데이터베이스 설치
pom.xml
에 h2 database engine 의존성 추가<scope>test</scope>
를runtime
으로 변경<dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>1.4.193</version> <scope>runtime</scope> </dependency>
application.properties
에 H2 데이터베이스 설정 추가spring.datasource.driver-class-name=org.h2.Driver spring.datasource.url=jdbc:h2:~/boot-qna;AUTO_SERVER=TRUE spring.datasource.username=sa spring.datasource.password= spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
3-2) 자바 객체와 테이블 매핑, 회원가입 기능 구현
spring-starter-data-jpa 의존성 추가
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
domain 패키지 추가
web 패키지에 있던 User 클래스를 domain 패키지로 이동
User 클래스에 annotation 추가
@Entity
: Entity 클래스라는 것을 나타내는 애너테이션 (반드시 필요)@Table(name="테이블명")
: Entity 클래스에 할당되는 테이블을 지정 (생략가능)@Id
: primary key 설정 (반드시 필요)@GenerateValue
: primary key 자동생성@Column
: 해당 필드에 할당할 칼럼을 지정 (생략가능)name
- 칼럼명 지정length
- 최대 길이를 지정nullable
- null 의 허용여부 지정(true, false)
repository 인터페이스 작성
아래와 같이 작성한다.
public interface UserRepository extends JpaRepository<User, Long> { }
Controller 변경
@Autowired
애너테이션을 통해 UserRepository 인스턴스를 필드와 연동@Autowired
: 애플리케이션에 있는 Bean 객체와 연동하기 위한 애너테이션@Autowired private UserRepository userRepository;
create() 메서드 : 회원가입
@PostMapping("/create") public String create(User user) { userRepository.save(user); return "redirect:list"; }
list() 메서드 : 회원목록
@GetMapping("/list") public String list(Model model) { model.addAttribute("users", userRepository.findAll()); return "list"; }
3-3) HTML 정리, URL 정리
HTML 템플릿 정리
└── resources : └── static : 정적 파일 | ├── css : css 파일 | ├── font : font 파일 | ├── images : image 파일 | └── js : js 파일 └── templates : 동적 파일 ├── ex : 기존의 연습한 파일들 ├── include : HTML 중복코드 정리 (navigation, header, footer) ├── qna : QnA 게시판 관련 HTML └── user : 회원가입 관련 HTML
html 중복코드를 정리하기 위해 include 폴더에 navigation, header, footer html파일 작성
mustache 템플릿의 include 방법
{{> /include/header}} {{> /include/navigation}} {{> /include/footer}}
URL 정리
UserController
회원관련 모든 URL 에
/users
가 추가될 수 있도록@Controller
애너테이션 하단에@RequestMapping("/users")
추가회원가입 처리 후 리스트로 redirect 하기 위해서
redierct:/users/list
로 변경
3-4) 개인정보 수정 기능 구현
UserController 에 회원정보 수정화면, 수정처리 메서드 추가
회원정보 수정화면
@GetMapping("/{id}/form") public String updateForm(@PathVariable Long id, Model model) { User user = userRepository.findOne(id); model.addAttribute("user", user); return "/user/updateForm"; }
회원정보 수정처리
@PutMapping("/{id}") public String update(@PathVariable Long id, User updatedUser) { User user = userRepository.findOne(id); // 기존의 아이디 정보를 조회 user.update(updatedUser); // 아이디의 정보 변경 userRepository.save(user); // 변경된 정보를 저장 return "redirect:/users/list"; }
User 클래스에 update() 메서드 추가 : email, name, password 만 변경
public void update(User updatedUser) { this.email = updatedUser.email; this.name = updatedUser.name; this.password = updatedUser.password; }
updateForm.html 작성 : 회원정보 수정 화면
<div class="container" id="main"> <div class="col-md-6 col-md-offset-3"> <div class="panel panel-default content-main"> {{#user}} <form name="question" method="post" action="/users/{{id}}"> <input type="hidden" name="_method" value="put"> <!--@PutMapping 을 사용하기 위한 방법--> <div class="form-group"> <label for="userId">사용자 아이디</label> <input class="form-control" id="userId" name="userId" value="{{userId}}" placeholder="User ID" readonly> </div> <div class="form-group"> <label for="password">비밀번호</label> <input type="password" class="form-control" id="password" name="password" value="{{password}}" placeholder="Password"> </div> <div class="form-group"> <label for="password">비밀번호 확인</label> <input type="password" class="form-control" id="password2" name="password" placeholder="Password"> </div> <div class="form-group"> <label for="name">이름</label> <input class="form-control" id="name" name="name" value="{{name}}" placeholder="Name"> </div> <div class="form-group"> <label for="email">이메일</label> <input type="email" class="form-control" id="email" name="email" value="{{email}}" placeholder="Email"> </div> <button type="submit" class="btn btn-success clearfix pull-right">개인정보 수정</button> <div class="clearfix"/> </form> {{/user}} </div> </div> </div>
html 에서는 get, post 만 사용할 수 있는데 put 을 사용하기 위한 방법
<input type="hidden" name="_method" value="put">
3-5) 원격 서버에 소스코드 배포
원격 서버에 배포한 뒤 include 한 파일을 찾지 못하는 문제가 발생
원인 : mustache 템플릿 엔진 문제로 추정
해결 방법
jar 파일이 아닌 maven 에서 spring-boot 프로젝트 실행하기
$ ./mvnw spring-boot:run &