토이 프로젝트/간단한 Springboot CRUD
SpringBoot + JPA + Thymeleaf + H2를 사용한 간단한 CRUD 프로젝트
코딍코딍
2022. 8. 6. 14:12
SpringBoot + JPA + Thymeleaf + H2(DB)를 사용한 간단한 CRUD 프로젝트
프로젝트 구조
- controller : UserController
- model : User
- repository : UserRepository
- Service : UserService, UserServiceImpl
프로젝트 생성
H2 데이터베이스 연동
application.properties
#h2 console 활성화 및 경로 설정
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
#h2 데이터베이스 설정
spring.datasource.url=jdbc:h2:tcp://localhost/~/springbootCRUD;
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
#hibernate 설정
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.hibernate.ddl-auto=create
spring.output.ansi.enabled=always
C:\Users\xxx에 springbootCRUD.mv.db 생성
H2 데이터베이스 처음 연결 시 URL 경로
이후 URL 경로
MySql 연동
application.properties
# MySQL 설정
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# DB Source URL
spring.datasource.url=jdbc:mysql://localhost:3306/springCRUD?useSSL=false&useUnicode=true&serverTimezone=Asia/Seoul
# DB username
spring.datasource.username=root
# DB password
spring.datasource.password=1234
# true 설정시 JPA 쿼리문 확인 가능
spring.jpa.show-sql=true
# DDL(create, alter, drop) 정의시 DB의 고유 기능을 사용할 수 있다.
spring.jpa.hibernate.ddl-auto=update
# JPA의 구현체인 Hibernate가 동작하면서 발생한 SQL의 가독성을 높여준다.
spring.jpa.properties.hibernate.format_sql=true
깃허브 연동
Model
User
package com.khm.springbootCRUD.model;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
@Getter @Setter
public class User {
@Id
@GeneratedValue
private Long id;
private String name;
private int age;
private String address;
public void change(String name, int age, String address) {
this.name=name;
this.age=age;
this.address=address;
}
}
repository
UserRepository
package com.khm.springbootCRUD.repository;
import com.khm.springbootCRUD.model.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}
Service
UserService
package com.khm.springbootCRUD.service;
import com.khm.springbootCRUD.model.User;
import com.khm.springbootCRUD.repository.UserRepository;
import java.util.List;
public interface UserService {
void createUser(User user);
void deleteUser(Long id);
void updateUser(User user);
List<User> findUsers();
User findUser(Long id);
}
UserServiceImpl
package com.khm.springbootCRUD.service;
import com.khm.springbootCRUD.model.User;
import com.khm.springbootCRUD.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Optional;
@Service
@RequiredArgsConstructor
@Transactional
public class UserServiceImpl implements UserService{
private final UserRepository userRepository;
@Override
public void createUser(User user) { //생성
userRepository.save(user);
}
@Override
public void deleteUser(Long id) { //삭제
Optional<User> findUserOptional = userRepository.findById(id);
User user = findUserOptional.orElseThrow(() -> new NoSuchElementException());
userRepository.delete(user);
}
@Override
public void updateUser(User user) { //수정
Optional<User> findUserOptional = userRepository.findById(user.getId());
if(findUserOptional.isPresent()) {
User findUser = findUserOptional.get();
findUser.change(user.getName(), user.getAge(), user.getAddress());
}
}
@Override
public List<User> findUsers() { //전체조회
return userRepository.findAll();
}
@Override
public User findUser(Long id) { //조회
return userRepository.findById(id).get();
}
}
Controller
UserController
package com.khm.springbootCRUD.controller;
import com.khm.springbootCRUD.model.User;
import com.khm.springbootCRUD.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import java.util.List;
@Controller
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
@GetMapping("/")
public String home() {
return "createUser";
}
@PostMapping("/")
public String createUser(@ModelAttribute User user) {
userService.createUser(user);
return "redirect:/";
}
@GetMapping("/users")
public String users(Model model) {
List<User> users = userService.findUsers();
model.addAttribute("users",users);
return "users";
}
@GetMapping("/user/edit/{id}")
public String editUser(@PathVariable("id") Long id, Model model) {
model.addAttribute("user", userService.findUser(id));
return "editUser";
}
@PostMapping("/user/edit")
public String edit(@ModelAttribute("user") User user) {
userService.updateUser(user);
return "redirect:/users";
}
@GetMapping("/user/delete/{id}")
public String deleteUser(@PathVariable("id") Long id) {
userService.deleteUser(id);
return "redirect:/users";
}
}
view
createUser.html
<!DOCTYPE html>
<html>
<head><title>Title</title></head>
<body>
<h2>User 생성 (Create)</h2>
<form action="/" method="post">
<p>이름: <input type="text" name="name" placeholder="이름을 입력해주세요." size="15">
<p>나이: <input type="text" name="age" placeholder="나이를 입력해주세요." size="15">
<p>주소: <input type="text" name="address" placeholder="주소를 입력해주세요." size="15">
<p><input type="submit" value="User 생성">
<a href="/users"><input type="button" value="User 리스트 보기"></a>
</form>
</body>
</html>
editUser.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><title>Title</title></head>
<body>
<h2>User 수정 (Update)</h2>
<form action="/user/edit" method="post" th:object="${user}">
<p>ID: <input type="text" th:field="*{id}" size="15" readonly>
<p>이름: <input type="text" th:field="*{name}" size="15">
<p>나이: <input type="text" th:field="*{age}" size="15">
<p>주소: <input type="text" th:field="*{address}" size="15">
<p><input type="submit" value="User 수정">
</form>
</body>
</html>
users.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><title>Title</title></head>
<body>
<h2>User 리스트 (Read)</h2>
<table>
<tr>
<th>ID</th>
<th>이름</th>
<th>나이</th>
<th>주소</th>
<th>수정</th>
<th>삭제</th>
</tr>
<div th:if="${!#lists.isEmpty(users)}">
<tr th:each="user : ${users}">
<td th:text="${user.id}"></td>
<td th:text="${user.name}"></td>
<td th:text="${user.age}"></td>
<td th:text="${user.address}"></td>
<td><a th:href="@{/user/edit/{userId} (userId=${user.id})}">수정</a></td>
<td><a th:href="@{/user/delete/{userId} (userId=${user.id})}">삭제</a></td>
</tr>
</div>
</table>
<hr>
<a href="/"><button>User 생성</button></a>
</body>
</html>
동작 과정
1. 생성 폼
2. 생성
3. 리스트 폼
4. 수정
5. 삭제
끝으로
Springboot와 더 친숙해지기위해 시작한 프로젝트입니다. 아직 배우고있는 단계라 미흡한 점이 많습니다. 지적해주시면 감사하겠습니다.