Do to others as you would have them do to you.
[Luke 6:31]
2. Database
2. 4 . JPA
The Java Persistence API (JPA) is a Java standard interface for handling relational databases in Java applications. JPA is a form of Object-Relational Mapping (ORM) technology, which automates the mapping between objects in object-oriented programming languages and relational databases.
Using JPA, developers can implement database-to-Java object mapping easily, abstracting interactions with databases and enabling simpler storage, retrieval, modification, and deletion of data.
Key benefits of using JPA include:
1. Object-Oriented Approach: JPA enables writing object-oriented code, leveraging the advantages of object-oriented programming. By mapping tables in databases to Java classes, developers can benefit from object-oriented programming principles.
2. Database Operations Without Complex SQL**: With JPA, developers don't need to write complex SQL queries. Instead, they can perform database operations using the provided JPA API.
3. Advantages of ORM: ORM automates the mapping between objects and databases, allowing developers to manipulate data using objects. This enhances code readability and increases development productivity.
4. Standardized Interface: JPA is a Java standard interface, allowing flexibility when switching between various implementations (e.g., Hibernate, EclipseLink). Developers code against the JPA interface, providing flexibility to change implementations.
5. Performance Optimization Features: JPA offers performance optimization features such as caching and lazy loading, enhancing application performance.
Using JPA abstracts interactions with databases, enabling developers to manipulate data in an object-oriented manner, and improving code maintainability and productivity.
Here's a detailed list of the topics
- 2.4.1 Basic Springboot JPA Project:
2.4.1 Basic Springboot JPA Project:
[ File ] - [ New ] - [ Spring Start Project ]
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
//DB Setting
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
runtimeOnly 'com.mysql:mysql-connector-j'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
}
2.4.2 JPA Configuration:
application.properties
spring.application.name=MyJPAExam
# Database Setting
spring.datasource.dbcp2.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/jpaexam
spring.datasource.username=root
spring.datasource.password=1111
# JPA
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.show_sql=true
create Database
create User.java Class
package com.example.myjpaexam;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.Data;
@Data
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer uno;
private String uid;
private String upw;
}
After writing User.java, when you run the server, the table is automatically generated.
2.4.3 Create, Read (list, detail):
Repository
T - Table Name
ID - 1st Field's Type
package com.example.myjpaexam;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Integer> {
}
Service
package com.example.myjpaexam;
import java.util.List;
public interface UserService {
void create(User user);
List<User> readlist();
User readdetail(Integer uno);
}
package com.example.myjpaexam;
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserRepository userRepository;
@Override
public void create(User user) {
userRepository.save(user);
}
@Override
public List<User> readlist() {
return userRepository.findAll();
}
@Override
public User readdetail(Integer uno) {
Optional<User> user = userRepository.findById(uno);
return user.get();
}
}
Controller
package com.example.myjpaexam;
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;
@Controller
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/create")
public String create() {
return "create";
}
@PostMapping("/create")
public String create(User user) {
userService.create(user);
return "redirect:/";
}
@GetMapping("/")
public String readlist(Model model) {
model.addAttribute("users", userService.readlist());
return "readlist";
}
@GetMapping("/readdetail/{uno}")
public String readdetail(@PathVariable("uno") Integer uno,
Model model) {
model.addAttribute("user", userService.readdetail(uno));
return "readdetail";
}
}
create.html
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
<h2> Create </h2>
<form action="/create" method="post">
<p>id : <input type="text" name="uid">
<p>pw : <input type="text" name="upw">
<p><input type="submit" value="join">
</form>
</body>
</html>
readlist.html
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
<h2> Read List </h2>
<a href="/create">CREATE</a><br><br>
<th:block th:each="user: ${users}">
[[${user.uno}]] /
<a th:href="@{|/readdetail/${user.uno}|}" th:text="${user.uid}"></a>
/ [[${user.upw}]] <br>
</th:block>
</body>
</html>
In Thymeleaf, [[ ]]
is a syntax used for evaluating variables or expressions in templates. This expression is one of the standard expression syntaxes in Thymeleaf. It's primarily used in HTML or XML templates and gets processed before the template is rendered by the template engine. The [[ ]]
expression is the natural expression syntax of Thymeleaf. This syntax is employed when Thymeleaf needs to evaluate and display values in the template. When the template engine encounters such an expression, it evaluates the variables or expressions within it to generate the final result and reflects it in the HTML output. For instance, to output the value of the variable name
in a Thymeleaf template, you can use the [[${name}]]
expression like this:
<p>Hello, [[${name}]]!</p>
In the above example, ${name}
is an expression in the Thymeleaf template that retrieves the value of the variable name
and outputs it. This gets replaced with the actual name when the template is rendered. The [[ ]]
expression is one of the powerful features of Thymeleaf, used for dynamic content generation, conditional rendering, iteration, and more. Thymeleaf also provides other expression syntaxes like #{ }
, @{ }
, *{ }
, etc., for performing various tasks.
readdetail.html
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
<h2> Read Detail </h2>
[[${user.uno}]] <br>
[[${user.uid}]] <br>
[[${user.upw}]] <br>
</body>
</html>
2.3.4 Update, Delete:
repository
package com.example.myjpaexam;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Integer> {
}
Service
package com.example.myjpaexam;
import java.util.List;
public interface UserService {
void create(User user);
List<User> readlist();
User readdetail(Integer uno);
void update(User user);
void delete(Integer uno);
}
package com.example.myjpaexam;
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserRepository userRepository;
@Override
public void create(User user) {
userRepository.save(user);
}
@Override
public List<User> readlist() {
return userRepository.findAll();
}
@Override
public User readdetail(Integer uno) {
Optional<User> user = userRepository.findById(uno);
return user.get();
}
@Override
public void update(User user) {
userRepository.save(user);
}
@Override
public void delete(Integer uno) {
Optional<User> user = userRepository.findById(uno);
userRepository.delete(user.get());
}
}
Controller
package com.example.myjpaexam;
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;
@Controller
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/create")
public String create() {
return "create";
}
@PostMapping("/create")
public String create(User user) {
userService.create(user);
return "redirect:/";
}
@GetMapping("/")
public String readlist(Model model) {
model.addAttribute("users", userService.readlist());
return "readlist";
}
@GetMapping("/readdetail/{uno}")
public String readdetail(@PathVariable("uno") Integer uno,
Model model) {
model.addAttribute("user", userService.readdetail(uno));
return "readdetail";
}
@GetMapping("/update/{uno}")
public String update(@PathVariable("uno") Integer uno,
Model model) {
model.addAttribute("user", userService.readdetail(uno));
return "update";
}
@PostMapping("/update")
public String update(User user) {
userService.update(user);
return "redirect:/";
}
@GetMapping("/delete/{uno}")
public String delete(@PathVariable("uno") Integer uno) {
userService.delete(uno);
return "redirect:/";
}
}
update.html
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
<h2> Update </h2>
<form action="/update" method="post">
<input type="hidden" name="uno" th:value="${user.uno}">
<p>id : <input type="text" name="uid" th:value="${user.uid}">
<p>pw : <input type="text" name="upw" th:value="${user.upw}">
<p><input type="submit" value="update">
</form>
</body>
</html>
readdetail.html
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
<h2> Read Detail </h2>
[[${user.uno}]] <br>
[[${user.uid}]] <br>
[[${user.upw}]] <br>
<a th:href="@{|/update/${user.uno}|}">update</a><br>
<a th:href="@{|/delete/${user.uno}|}">delete</a><br>
</body>
</html>