다음 포스팅은 인프런 백기준 님의 예제로 배우는 스프링 입문을 듣고 정리한 내용입니다.
과제 (Spring PetClinic Project)
- lastName으로 검색중인 항목을 firstName으로 검색하기
- firstName의 일부만 맞아도 검색 가능하게 하기
- ownerdp age 항목 추가하기
firstName으로 검색하기
- console 창에서 GET "owners/find", parameter {}를 통해 flow 확인하기
- return "owners/findOwners"; View 확인
- lastName -> firstName으로 변경하기
- Find Owner버튼의 Controller Mapping 되어있는 부분 찾기 -> 수정
OwnerController 수정
@GetMapping("/owners")
public String processFindForm(@RequestParam(defaultValue = "1") int page, Owner owner, BindingResult result,
Model 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
String firstName = owner.getFirstName();
Page<Owner> ownersResults = findPaginatedForOwnersFirstName(page, firstName);
if (ownersResults.isEmpty()) {
// no owners found
result.rejectValue("firstName", "notFound", "not found");
return "owners/findOwners";
}
else if (ownersResults.getTotalElements() == 1) {
// 1 owner found
owner = ownersResults.iterator().next();
return "redirect:/owners/" + owner.getId();
}
else {
// multiple owners found
firstName = owner.getFirstName();
return addPaginationModel(page, model, firstName, ownersResults);
}
}
- getLastName ➡️ getFistName, setLastName ➡️ setFirstName 등으로 설정해주면서 lastName으로 검색하고 있는 것을 firstName으로 검색해서 매핑할 수 있도록 한다.
OwnerRepository(DAO) 수정
@Query("SELECT DISTINCT owner FROM Owner owner left join owner.pets WHERE owner.firstName LIKE :firstName% ")
@Transactional(readOnly = true)
Page<Owner> findByFirstName(@Param("firstName") String firstName, Pageable pageable);
firstName의 일부만 맞아도 검색 가능하게 하기
@Query("SELECT DISTINCT owner FROM Owner owner left join owner.pets WHERE owner.firstName LIKE %:firstName% ")
@Transactional(readOnly = true)
Page<Owner> findByFirstName(@Param("firstName") String firstName, Pageable pageable);
- 처음 lastName을 firstName으로 수정하기 위해
@Query("SELECT DISTINCT owner FROM Owner owner left join owner.pets WHERE owner.firstName LIKE :firstName% ")
를 작성했다. - 쿼리문의 LIKE문에서 검색어가 100% 정확하지 않아도 조회할 수 있게 하기 위해
LIKE %:firstName%
을 사용하여 해당 키워드가 들어가기만 해도 검색 결과가 나올 수 있게 할 수 있다.
Owner에 age 항목 추가하기
- 우선, Owner라는 db에 age라는 항목을 추가하기 위해서는 owner 클래스에 age라는 항목이 필요하다.
Owner 클래스에 age 추가하기
private Integer age;
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
DB schema.sql에 age 칼럼 추가하기
CREATE TABLE owners (
id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
first_name VARCHAR(30),
last_name VARCHAR_IGNORECASE(30),
age INTEGER,
address VARCHAR(255),
city VARCHAR(80),
telephone VARCHAR(20)
);
DB data.sql에 추가한 age 칼럼의 데이터 넣기
단, 위에서 CREATE한 칼럼 순서와 INSERT 할 때의 VALUES 데이터 값의 순서는 동일해야 한다!!
INSERT INTO owners VALUES (default, 'George', 'Franklin', 20, '110 W. Liberty St.', 'Madison', '6085551023');
INSERT INTO owners VALUES (default, 'Betty', 'Davis', 20, '638 Cardinal Ave.', 'Sun Prairie', '6085551749');
INSERT INTO owners VALUES (default, 'Eduardo', 'Rodriquez', 20, '2693 Commerce St.', 'McFarland', '6085558763');
INSERT INTO owners VALUES (default, 'Harold', 'Davis', 20, '563 Friendly St.', 'Windsor', '6085553198');
INSERT INTO owners VALUES (default, 'Peter', 'McTavish', 20, '2387 S. Fair Way', 'Madison', '6085552765');
INSERT INTO owners VALUES (default, 'Jean', 'Coleman', 20, '105 N. Lake St.', 'Monona', '6085552654');
INSERT INTO owners VALUES (default, 'Jeff', 'Black', 20, '1450 Oak Blvd.', 'Monona', '6085555387');
INSERT INTO owners VALUES (default, 'Maria', 'Escobito', 20, '345 Maple St.', 'Madison', '6085557683');
INSERT INTO owners VALUES (default, 'David', 'Schroeder', 20, '2749 Blackhawk Trail', 'Madison', '6085559435');
INSERT INTO owners VALUES (default, 'Carlos', 'Estaban', 20, '2335 Independence La.', 'Waunakee', '6085555487');
화면 수정하기 - createOrUpdateOwnerForm.html
<div class="form-group has-feedback">
<input
th:replace="~{fragments/inputField :: input ('First Name', 'firstName', 'text')}" />
<input
th:replace="~{fragments/inputField :: input ('Last Name', 'lastName', 'text')}" />
<input
th:replace="~{fragments/inputField :: input ('Age', 'Age', 'text')}" />
<input
th:replace="~{fragments/inputField :: input ('Address', 'address', 'text')}" />
<input
th:replace="~{fragments/inputField :: input ('City', 'city', 'text')}" />
<input
th:replace="~{fragments/inputField :: input ('Telephone', 'telephone', 'text')}" />
</div>
화면 수정하기 - ownerDetails.html
<table class="table table-striped" th:object="${owner}">
<tr>
<th>Name</th>
<td><b th:text="*{firstName + ' ' + lastName}"></b></td>
</tr>
<tr>
<th>Age</th>
<td th:text="*{age}"></td>
</tr>
<tr>
<th>Address</th>
<td th:text="*{address}"></td>
</tr>
<tr>
<th>City</th>
<td th:text="*{city}"></td>
</tr>
<tr>
<th>Telephone</th>
<td th:text="*{telephone}"></td>
</tr>
</table>
결과
'Back > Spring' 카테고리의 다른 글
FullCalendar 캘린더 db 일정 조회하기 (0) | 2022.03.04 |
---|---|
Spring - Clova Chatbot (0) | 2022.01.26 |
Spring - REST, Ajax (0) | 2022.01.11 |
Spring - AOP(Aspect Oriented Programming) (0) | 2022.01.05 |
Spring - Annotation(어노테이션) (0) | 2022.01.05 |