โโ Thymeleaf์ JPA๋ฅผ ์ด์ฉํ CRUD โโ
- JSP + EL
- thymeleaf ( html + Spring EL )
Natural Templating: DB, Front End
1. Spring boot ํ๋ก์ ํธ ์๋ก ์์ฑ
2. application.properties, pom.xml ๋ณต์ฌ
3. application.properties, pom.xml์ thumeleaf ๊ด๋ จ ์ค์ ์ถ๊ฐ
โโThymeleaf ์ค์ ํ๊ธฐโโ
-application.properties
# Thymeleaf
spring.thymeleaf.cache=false
spring.thymeleaf.prefix=classpath:/templates/
templates๋ผ๋ ํด๋ ๊ฒฝ๋ก์
spring.thymeleaf.suffix=.html
ํ์ฅ์๊ฐ html
spring.thymeleaf.view-names=thymeleaf/*
thymeleaf ์ด๋ฆ์ผ๋ก ์์๋๋ ๋ชจ๋ ๋ทฐ๋ค
templates๋ผ๋ ํด๋ ๊ฒฝ๋ก์ thymeleaf ์ด๋ฆ์ผ๋ก ์์๋๋ ๋ชจ๋ ๋ทฐ๋ค์ด ํ์ฅ์๊ฐ html๋ก ์ ์ฅ๋๋ค.
-pom.xml
โโThymeleaf๋ฅผ ํ์ฉํ eclipse ์์ html ์ฝ๋ฉ ์์ โโ
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
27
28
29
30
31
|
import java.util.*;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import jakarta.servlet.http.HttpServletRequest;
@Controller
@RequestMapping("/th")
public class ThymeleafController {
@GetMapping("/")
public String index(Model m, HttpServletRequest session) {
m.addAttribute("greeting", "Hello world!");
m.addAttribute("url", "th/");
m.addAttribute("msg", "Happy New Year!");
m.addAttribute("success", true);
m.addAttribute("gender", "M");
m.addAttribute("nums", new int[] { 1, 3, 5, 7, 9 });
m.addAttribute("scores", Arrays.asList(5, 7, 9, 10));
m.addAttribute("names", Arrays.asList("smith", "mary", "jone"));
// asList = List ๋ฅผ ์์ฑํด์ค
session.setAttribute("userid", "login-userid");
m.addAttribute("emp", new Emp(11, "smith", 20, java.sql.Date.valueOf("2022-12-25")));
Map<String, Integer> map = new HashMap<>();
map.put("smith", 78);
map.put("mary", 88);
map.put("jone", 66);
m.addAttribute("credit", map);
return "thymeleaf/index";
}
}
|
cs |
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>์ฐ์ต์ฅ</title>
</head>
<body>
<h3>์๋
ํ์ธ์</h3>
<!-- Variable Expression -->
<div th:text="${greeting}"></div>
<div>[[${greeting}]]</div>
<p>
<a href="/th/">index.html</a>
<p>
<!-- URL Expression -->
<a th:href="@{'/' + ${url} }">index.html</a>
<p>
<a th:href="${'/' + url }">index.html</a>
<p>
<input type="text" value="1+2">
<p>
<input type="text" th:value="1+2"> <!-- 3ํ์๋จ -->
<p>
<div th:text="${msg}"></div>
<p>
<div th:text="${success} ? '์ฑ๊ณต' : '์คํจ'" ></div>
<div th:text="${success ? 'true':'false'}" ></div>
<p>
<div th:if="${gender=='M'}" >๋จ์</div>
<div th:unless="${gender=='M'}" >์ฌ์</div><!-- ํ์ ์๋จ -->
<p>
<!-- switch case -->
<div th:switch="${gender}">
<span th:case="M">Male</span>
<span th:case="F">Female</span>
<span th:case="*">Others</span>
</div>
<!-- ๋ฆฌ์คํธ ์ฌ์ด์ฆ -->
<div th:text="'๋ฐฐ์ด ์์์:' + ${nums.length} + '๊ฐ'"></div>
<div th:text="${nums[0]}"></div><!-- ๋ฐฐ์ด์ ์์ ์ถ๋ ฅ -->
<div th:text="'๋ฆฌ์คํธ ์์์:' + ${#lists.size(scores)} + '๊ฐ'"></div>
<!-- ๋ฐ๋ณต๋ฌธ -->
<div>
<span th:each="n : ${nums}">
[[${n}]]
</span>
</div>
<div> <!-- ์ํ๋ณ์: index, count, size, even/odd, first, last -->
<span th:each="name, iStat : ${names}">
[[${iStat.index}]].[[${name}]]
</span>
</div>
<!-- Map ๋ค๋ฃจ๊ธฐ -->
<p th:each="user :${credit}">
<span th:text="${user.key}"></span>
<span th:text="${user.value}"></span>
</p>
<!-- ์์ญ ์ค๋ธ์ ํธ -->
<p th:text="${param.q}">Test</p> <!--์์ฒญ ํ๋ผ๋ฏธํฐ localhost/th/๋ฉ์๋getmapping์ฃผ์๋ช
?q=์ฌ๊ธฐ์ ๊ฐ์ด์์ผํจ-->
<p th:text="'์ด์ฉ์ ์์ด๋:' + ${session.userid}">
<!-- ๊ฐ์ฒด์ ์์ฑ -->
<p th:text="${emp.empno} +'/'+ ${emp.ename}">
</main>
</body>
</html>
|
cs |
โโThymeleaf, JPA, Spring ํ๋ ์์ํฌ ํ์ฉํ์ฌ ์ฌ์ CRUD ํ๊ธฐโโ
@Entity๋ฅผ ์ํ VO Class์ธ Emp.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
27
28
29
30
31
32
|
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.SequenceGenerator;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
@Data
@ToString
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Table(name="emp5")
public class Emp
{
@Id
@SequenceGenerator(sequenceName = "EMP5_EMPNO_SEQ", allocationSize =1, name="EMP5_EMPNO_GEN" )
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator="EMP5_EMPNO_GEN")
private int empno;
@Column(name="ename")
private String name;
private int deptno;
private int sal;
private java.sql.Date hiredate;
}
|
cs |
JpaRepository ๋ฅผ ์์๋ฐ๊ธฐ ์ํ Emp5Repository class
1
2
3
4
5
|
import org.springframework.data.jpa.repository.JpaRepository;
public interface Emp5Repository extends JpaRepository<Emp,Integer> {
}
|
cs |
Controller : EmpController
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import lombok.extern.slf4j.Slf4j;
@Controller
@Slf4j
@RequestMapping("/jpaemp")
public class EmpController {
@Autowired
private Emp5Repository repo;
@GetMapping("/add")
public String add() {
return "thymeleaf/empAdd";
}
@PostMapping("/add")
public void addemp(Emp emp) {
repo.save(emp);
}
@GetMapping("/list")
public String list(Model m) {
List<Emp> saved = repo.findAll();
m.addAttribute("list",saved);
return "thymeleaf/empList";
}
@GetMapping("/detail/{empno}")
public String findById(@PathVariable int empno, Model m) {
Optional<Emp> op = repo.findById(empno);
if(op.isEmpty()) {
return empno+"๋ฒํธ๋ก ๊ฒ์์คํจ";
}
m.addAttribute("emp",op.get());
return "thymeleaf/empDetail";
}
@GetMapping("/update/{empno}")
public String updateByEmpno(@PathVariable int empno, Model m) {
Optional<Emp> op = repo.findById(empno);
if(op.isEmpty()) {
return empno+"๋ฒํธ๋ก ๊ฒ์์คํจ";
}
m.addAttribute("emp",op.get());
return "thymeleaf/empUpdate";
}
@PostMapping("/edit")
@ResponseBody
public String edit(Emp emp) {
int empno = emp.getEmpno();
Optional<Emp> op = repo.findById(empno);
if(op.isEmpty()) {
return empno+"๋ฒํธ๋ก ๊ฒ์์คํจ";
}
Emp updateEmp = op.get();
updateEmp.setDeptno(emp.getDeptno());
updateEmp.setSal(emp.getSal());
repo.save(updateEmp);
return "์์ ์ฑ๊ณต";
}
@GetMapping("/delete/{empno}")
@ResponseBody
public String deleteByEmpno(@PathVariable int empno) {
Optional<Emp> op = repo.findById(empno);
if(op.isEmpty()) {
return empno+"๋ฒํธ๋ก ๊ฒ์์คํจ";
}
else repo.deleteById(empno);
return "์ญ์ ์ฑ๊ณต";
}
}
|
cs |
empAdd.html
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
27
28
29
30
31
32
33
34
|
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
</head>
<body>
<form action="/jpaemp/add" method="post" >
<div>
<label for="name">์ด๋ฆ</label>
<input id="name" type="text" name="name" value="">
</div>
<div>
<label for="deptno">๋ถ์</label>
<select id="deptno" name="deptno">
<option value="10">10</option>
<option value="20">20</option>
<option value="30">30</option>
</select>
</div>
<div><label>๊ธ์ฌ</label>
<input id="sal" type="number" name="sal" value="">
</div>
<div><label>์
์ฌ</label>
<input id="hiredate" type="date" name="hiredate" value="">
</div>
<div class="btn">
<button type="reset">์ทจ์</button>
<button type="submit">์ถ๊ฐ</button>
</div>
</form>
</body>
</html>
|
cs |
์คํ๊ฒฐ๊ณผ:
empList.html
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
27
28
29
30
31
32
33
34
|
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
</head>
<body>
<form action="/jpaemp/add" method="post" >
<div>
<label for="name">์ด๋ฆ</label>
<input id="name" type="text" name="name" value="">
</div>
<div>
<label for="deptno">๋ถ์</label>
<select id="deptno" name="deptno">
<option value="10">10</option>
<option value="20">20</option>
<option value="30">30</option>
</select>
</div>
<div><label>๊ธ์ฌ</label>
<input id="sal" type="number" name="sal" value="">
</div>
<div><label>์
์ฌ</label>
<input id="hiredate" type="date" name="hiredate" value="">
</div>
<div class="btn">
<button type="reset">์ทจ์</button>
<button type="submit">์ถ๊ฐ</button>
</div>
</form>
</body>
</html>
|
cs |
์คํ๊ฒฐ๊ณผ :
empDetail.html
1
2
3
4
5
6
7
8
9
10
11
12
|
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
</head>
<body>
<p th:text="${emp.empno} +'/'+ ${emp.name}+'/'+ ${emp.deptno}+'/'+ ${emp.sal}+'/'+ ${emp.hiredate}"></p>
<a th:href="@{'/jpaemp/update/'+${emp.empno}}">์ฌ์์ ๋ณด์์ </a>
<a th:href="@{'/jpaemp/delete/'+${emp.empno}}">์ฌ์์ ๋ณด์ญ์ </a>
</body>
</html>
|
cs |
์คํ๊ฒฐ๊ณผ :
empUpdate.html
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
27
28
29
30
31
32
33
34
35
36
37
38
|
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
</head>
<body>
<form action="/jpaemp/edit" method="post" >
<input type="hidden" name="empno" th:value="${emp.empno}">
<div>
<label for="empno">์ฌ๋ฒ</label>
<p th:text="${emp.empno}"></p>
</div>
<div>
<label for="name">์ด๋ฆ</label>
<p th:text="${emp.name}"></p>
</div>
<div>
<label for="deptno">๋ถ์</label>
<select id="deptno" name="deptno">
<option value="10">10</option>
<option value="20">20</option>
<option value="30">30</option>
</select>
</div>
<div><label>๊ธ์ฌ</label>
<input id="sal" type="number" name="sal" value="">
</div>
<div><label>์
์ฌ์ผ</label>
<p th:text="${emp.hiredate}"></p>
</div>
<div class="btn">
<button type="reset">์ทจ์</button>
<button type="submit">์์ </button>
</div>
</form>
</body>
</html>
|
cs |
์คํ๊ฒฐ๊ณผ :
์ฌ์ ์ญ์ ํ๊ธฐ
๋๊ธ