Spring - 1 스프링 에제 프로젝트 PetClinic
해당 자료는 인프런 백기선님의 예제로 배우는 스프링 입문(개정판) 강의노트입니다..
1. 프로젝트 설정
준비물은 Intellij입니다.
https://github.com/spring-projects/spring-petclinic 해당 URL에서 적당한 폴더에 git clone을 해줘서 프로젝트를 가져오고 intellij에서 열어줬습니다.
강의를 보면 git bash가 intellij와 연동되어 있지만, 저는 연동되어 있지 않았습니다.
https://violetboralee.medium.com/intellij-idea%EC%99%80-git-bash-%EC%97%B0%EB%8F%99%ED%95%98%EA%B8%B0-63e8216aa7de
이 블로그를 통해 cmd에서 gitbash로 바꿀 수 있었습니다.
그리고 해당 깃 Readme.md에 있는 순서대로 초기설정을 해주었습니다.
1
2
./mvnw package
java -jar target/*.jar //jar파일을 실행함.
이후 FIND OWNERS 탭에서 ADD Owner와 ADD Pet을 통해 정보를 추가.
또한, Add visit을 통해 방문일정을 추가해주었습니다.
- 예전에 배운 Intellij에서 main method를 run을 시켜 실행해버리는 것은 ./mvnw package(메이븐 패키징)를 안해주면 오류가 날 수 있다고합니다. 플러그인이 먼저 동작해야하는데 하지 않으면 로컬에서 화면이 깨질 수도 있습니다.
2. 프로젝트 살펴보기
해당 웹이 어떻게 돌아가는 지 알려주셨다.
Log를 찍기 위해 application.properties에서 주석문을 제거해줍니다.
1
logging.level.org.springframework.web=DEBUG
- 디버거 찍는법은 vs와 같이 빨간점으로 찍고 디버그모드로 돌리면 된다.
3. 프로젝트 과제 풀이
- LastName이 아니라 FirstName으로 검색해 볼까?
- 정확히 일치하는게 아니라 해당 키워드가 들어있는 걸 찾아볼까?
- Owner에 age 추가
이 세가지를 고치기로 했습니다.
3.1. LastName을 FirstNamed으로 바꾸기
화면에 보이는 Lastname을 Firstname으로 바꾸기위해 findOwners.html에서
1
2
<input class="form-control" th:field="*{Lastname}" size="30"
-> <input class="form-control" th:field="*{firstName}" size="30"
OwnerController.java 파일에서
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@GetMapping("/owners")
public String processFindForm(Owner owner, BindingResult result, Map<String, Object> model) {
// allow parameterless GET request for /owners to return all records
if (owner.getFirstName() == null) {
owner.setFirstName(""); // empty string signifies broadest possible search
}
// find owners by first name
Collection<Owner> results = this.owners.findByFirstName(owner.getFirstName());
if (results.isEmpty()) {
// no owners found
result.rejectValue("lastName", "notFound", "not found");
return "owners/findOwners";
}
else if (results.size() == 1) {
// 1 owner found
owner = results.iterator().next();
return "redirect:/owners/" + owner.getId();
}
else {
// multiple owners found
model.put("selections", results);
return "owners/ownersList";
}
}
이렇게 LastName과 관련된 메소드를 다 firstName메소드로 바꿔줍니다.
또한 OwnerRepository.java 파일에서
1
2
3
@Query("SELECT DISTINCT owner FROM Owner owner left join fetch owner.pets WHERE owner.firstName LIKE :firstName%")
@Transactional(readOnly = true)
Collection<Owner> findByFirstName(@Param("firstName") String firstName);
이렇게 새로운 Query문을 만들어주고 firstName()을 반환하도록 합니다.
3.2. 정확히 일치하는게 아니라 해당 키워드가 들어있는 걸 찾아볼까?
위에서 작성한 쿼리문을 수정해줍니다.
1
2
3
@Query("SELECT DISTINCT owner FROM Owner owner left join fetch owner.pets WHERE owner.firstName LIKE %:firstName")
@Transactional(readOnly = true)
Collection<Owner> findByFirstName(@Param("firstName") String firstName);
- :%firstName이 아닌 %:firstName으로 적어야 :firtName이 매개변수로 치환된다고 합니다.
3.3.Owner에 age 추가
Owner.java 파일에
1
2
3
4
5
6
7
8
9
private Integer age;
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
을 추가해주고 서버를 재시작하면 DB에 age가 없기에 Query문 오류가 납니다.
따라서 resources/db/hsqldb/schema.sql을 수정해줘야합니다.
age INTERGER를 추가해주고, INSERT문에서 age도 추가해주기 위해 /resources/db/hsqldb/data.sql에 임의의 나이를 설정해줍니다.
1
2
3
4
5
6
7
8
9
10
INSERT INTO owners VALUES (1, 'George', 'Franklin', 20, '110 W. Liberty St.', 'Madison', '6085551023');
INSERT INTO owners VALUES (2, 'Betty', 'Davis',20, '638 Cardinal Ave.', 'Sun Prairie', '6085551749');
INSERT INTO owners VALUES (3, 'Eduardo', 'Rodriquez',20, '2693 Commerce St.', 'McFarland', '6085558763');
INSERT INTO owners VALUES (4, 'Harold', 'Davis',20, '563 Friendly St.', 'Windsor', '6085553198');
INSERT INTO owners VALUES (5, 'Peter', 'McTavish',20, '2387 S. Fair Way', 'Madison', '6085552765');
INSERT INTO owners VALUES (6, 'Jean', 'Coleman',20, '105 N. Lake St.', 'Monona', '6085552654');
INSERT INTO owners VALUES (7, 'Jeff', 'Black',20, '1450 Oak Blvd.', 'Monona', '6085555387');
INSERT INTO owners VALUES (8, 'Maria', 'Escobito',20, '345 Maple St.', 'Madison', '6085557683');
INSERT INTO owners VALUES (9, 'David', 'Schroeder',20, '2749 Blackhawk Trail', 'Madison', '6085559435');
INSERT INTO owners VALUES (10, 'Carlos', 'Estaban',20, '2335 Independence La.', 'Waunakee', '6085555487');
화면에서 나이를 물어봐야하기때문에 createOrUpdateOwnerForm.html도 고쳐줘야합니다.
1
2
<input
th:replace="~{fragments/inputField :: input ('Age', 'age', 'text')}" />
다음 코드를 추가해줍니다.
쿼리문을 보내려하면 에러가 뜨는데 강의 버전이랑 clone한 프로젝트 버전이 달라서 application.proterties를 바꿔줘야합니다.
1
2
database=h2 를
database=hsqldb로 바꿔줍니다.
검색을 했을 때 나이를 출력해주기 위해
ownerList.html의 코드를 손봐줍시다.
1
2
<th style="width: 200px;">Age</th>
<td th:text="${owner.age}"/>
이렇게 추가해주면
또한 User를 누르면 age에 대한 정보가 누락되어있으므로 해당사항도 해결해주어야 합니다.
ownerDetails.html에서 코드를 추가해줍니다.
1
2
3
4
5
6
~
<tr>
<th>Age</th>
<td><b th:text="*{age}"></b></td>
</tr>
~
성공했고 마지막에 유저를 임의적으로 만들었을 때 제대로 들어가는 지 확인해봅니다.
제대로 들어갔습니다.