그동안 백준 풀면서 스프링 공부를 소홀히 한 게 느껴져서 오랜만에 스프링 공부도 할 겸,
간단한 회원조회 실습을 해보기로 했다.
말그대로 기초적인 간단한 실습을 복습 겸 하는거라,
Domain에 Member(회원)밖에 없으며, CRUD 중 R(Read) 기능만 잘 되게 만들어보았다.
하다가 막히는 부분은 아래 내 깃헙에 있는 crud 간단하게 만들어봤던 코드를 참고하면서 하였다.
github.com/kth990303/RoastChickenSoup
환경세팅
일단 start.spring.io/ 에 들어가서 dependency 추가와 패키지명을 정해준다.
주의할 점!
**패키지 Group명은 반드시 영어로 시작해야 한다!**
처음에 210504 로만 그룹명을 짰다가, 스프링부트에서 세팅할 때 패키지명을 인식하지 못하는 경우가 발생했다.
사실 환경세팅 잘하는 사람들은 이것저것 만져서 잘 해결할 거 같지만, 난 이것저것 만지다가 실패해서 결국 그룹명을 위와 같이 shop210504로 수정하여 세팅을 성공적으로 마무리하였다.
추가한 dependency 목록
1. Spring Web
우리는 웹개발을 할 것이므로 반드시 추가해주자.
이걸 추가해주는 순간, tomcat이 내장돼있어 tomcat 버전충돌로 인한 고생길은 열리지 않을 것이다.
2. lombok
@Getter, @Setter, @RequiredArgsContructor 기능들을 가지고 있으며,
getter, setter 메소드를 어노테이션을 붙임으로써 자동생성해주며,
@Autowired 어노테이션 없이 자동으로 의존관계를 주입해준다.
@Setter를 붙이는 순간 모든 필드에 Setter method가 추가된다는 단점이 있지만, 난 추가하였다.
3. thymeleaf
템플릿 엔진 중 하나이다. jsp 코드 짜는 거 귀찮아서 추가한 디펜던시이다.
db 정보들을 템플릿 엔진을 통해 html로 띄워줄 수 있다.
thymeleaf 문법도 공부해야되는데..
4. mysql driver, Spring JPA
각각 mysql, jpa 관련 dependency이다. mysql driver에는 jdbc driver 또한 포함돼있으므로 따로 jdbc driver를 설치할 필요 없다.
Build.gradle
아마 프로젝트 압축을 해제하고 IntelliJ로 프로젝트를 열면
빌드하는 과정이 약 1~2분 정도 걸린 후 (내 컴이 똥컴일수도 있지만) 빌드 성공이라 뜰 것이다.
build.gradle 코드는 아래처럼 될 것이다. (버전은 좀 다를 수 있다.)
plugins {
id 'org.springframework.boot' version '2.4.5'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
group = 'shop210504'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'mysql:mysql-connector-java'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
test {
useJUnitPlatform()
}
+ 추가로 lombok을 사용하기 위해선
ctrl + alt + s를 눌러서 설정 (preference)에 들어가서 Annotation Processors 검색 후, 맨 위 상단의 Enable annotation processing에 체크해주자.
Application.properties
그럼 이제 내 mysql과 연동하기 위한 작업만 남았다.
예전엔 mysql 연동으로 몇 시간이 소모됐었는데,
이번엔 환경설정으로 고통받기 싫어서 예전에 작업해뒀던 코드를 복사하였다.
spring.datasource.username=root
spring.datasource.url=jdbc:mysql://localhost:3306/shop210504?characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.password=1234admin
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=none
username은 Mysql id이다. 난 연습용 root 계정으로 할 것이다.
url은 jdbc:mysql:// 부터가 중요한데, localhost:3306에서
3306은 Mysql 설치할 때 지정해뒀던 포트번호,
shop210504는 연동할 데이터베이스명을 의미한다. (패키지명이 아니다!)
password는 말 그대로 mysql 비밀번호이다. 이 비밀번호는 다른 사람들이 알게 되면 큰일나니까 github에 올라가지 않도록 주의하자. 물론, 난 연습용 mysql이라 알려져도 상관없다. (비번도 1234admin이다... 누구나 알듯ㅋㅋ)
spring.jpa.hibernate.ddl-auto=none에서
none: 딱히 db에 아무런 작업 안함. 그냥 기본형으로 none으로 놔두자.
create: 메인코드, 테스트코드를 실행할 때마다 db table을 (이미 존재하면 drop 후) 생성하여 작동한다.
즉, create는 테스트코드를 돌릴 때, 개발할 때는 좋으나, 실질적으로 배포할 땐 절대 create에 놓지 말도록 하자. 기존 정보를 싸그리 지우고 싶은게 아니라면 말이다... (실무에선 기존의 버릴 정보들 또한 따로 모아둔다고 한다.)
main/Resources
우선 html, css 파일 먼저 만들어볼까?
근데 난 귀찮아서 그냥 html, css 파일 또한 예전 꺼 복사붙여넣기 했다.
근데, css 파일은 왜 static 폴더 안에 있고,
html 파일은 왜 templates 폴더 안에 있냐?
html 파일은 MVC의 view에 해당하며, controller에서 사용자가 api에 따라 정보를 요청하면,
사용자에게 정보를 띄워주기 위해 html파일을 보여줄텐데,
이 때 db 정보 (회원조회니까)를 보여줘야 될테니,
템플릿 엔진이 db 정보를 보여주기 위해 작동할테고
따라서 templates 폴더 안에 넣었다. (동적 파일)
css 파일은 그냥 db 정보가 어떻든 간에 같은 디자인만 유지하면 돼서 static 폴더에 넣었다. (정적 파일)
static/css/index.css
body{
background-color: darkolivegreen;
font-family: Arial sans-serif;
color: white;
}
h1{
text-align: center;
}
table{
text-align: center;
}
templates/index.html
<!DOCTYPE html>
<html lang="en">
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>회원조회 연습 홈페이지</title>
<link href="../static/css/index.css" th:href="@{/css/index.css}" rel="stylesheet" />
</head>
<body>
<h1>너가 관리하는 회원들이 궁금해?</h1>
<a href="/login">로그인</a><br>
<a href="/createMemberForm">회원가입</a>
<hr>
<div class="container">
<table width="100%" border="1">
<thead>
<tr>
<th>회원번호</th>
<th>이름</th>
<th>티어</th>
<th>정보 수정</th>
</tr>
</thead>
<tbody>
<tr th:each="member : ${members}">
<td th:text="${member.id}"></td>
<td th:text="${member.name}"></td>
<td th:text="${member.tier}"></td>
<td><a href="/" th:href="@{'delete/'+${member.id}}">삭제</a></td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
thymeleaf 템플릿 엔진을 사용할 거면 head 위에
<html xmlns:th="http://www.thymeleaf.org">
를 추가해주자.
css 파일 적용 도한
<link href="../static/css/index.css" th:href="@{/css/index.css}" rel="stylesheet" />
(@{css 파일이 존재하는 폴더명})
를 추가해주자.
${members} 를 유심히 살펴보자.
나중에 포스팅하겠지만, controller의 model에서 회원정보를 보내주면 (model.attribute({key, value}))
템플릿 엔진이 key (attributeName)에 해당하는 ${members} 부분에 회원정보 리스트를 받게 되는 것이다.
다른 분께서 잘 정리해둔 포스팅을 참고하자. 도움이 많이 된 포스팅이다.
main/java
자바 폴더를 보기 전,
디렉토리 구조가 어떻게 돼있는지 보자.
Controller, Service, Repository로 나눴음을 알 수 있다.
나중에 main/java 디렉토리 코드들 또한 포스팅하겠다.
오랜만에 실습하면서 많이 알게된 점은
스프링 인강을 들어도 실습을 하지 않으면 실력이 녹슨다는 점,
실습을 통해 많은 걸 배워간다는 점이다.
특히 Controller에서 Model이 하는 기능을 난 아예 까먹고 있었는데,
엄청 중요한 기능이었다.. key, value 중에 attributeName이 key에 해당한다는 것도 헷갈리는 상태였었고 말이다.
attributeName에 해당하는 부분이 html 파일에서의 thymeleaf 템플릿엔진이 사용할 객체명에 해당한다.
그리고 Controller, Service, Repository 구현체에 @RequiredArgsContructor가 있어야 의존관계 자동주입이 되고, 없으면 AppConfig 클래스를 통해 configuration을 정해줘야 한다는 것도 다시 상기시켰으며,
@RequiredArgsConstructor가 있다 해도 생성자 주입만 해주므로, 주입할 필드는 존재해야 함을 다시 깨달았다.
이 부분은 다음 포스팅에 적을 것이다.
그 외에도 jpa 공부를 열심히 해야겠단 생각이 많이 들었다.
결국 백엔드 공부는 db가 정말 중요한데, jpa가 ORM이기 때문에 db와 직결되는 문제이므로 db공부, jpa 공부 또한 게을리하지 말아야겠다.
'JAVA > JAVA | Spring 학습기록' 카테고리의 다른 글
[Spring] 스프링이 태어난 이유_서블릿, JSP로 만든 MVC의 한계 (0) | 2021.07.06 |
---|---|
[Spring] lombok의 @Builder와 JpaRepository를 도입해보았다 (0) | 2021.05.17 |
[Spring] CRUD 기능 실습 중 @DeleteMapping 관련 에러 (0) | 2021.05.11 |
[Spring] MySQL+JPA+Spring+Gradle 회원조회 Read 실습 (0) | 2021.05.10 |
[Spring] Spring boot Test 코드 작성해보기 (TDD 연습) (2) | 2021.05.05 |