Chào các em ,chủ đề hôm nay của anh là về Spring JPA trong lập trình Spring ? Anh sẽ giải thích nó là gì ? Cấu hình dự án sử dụng JPA ra sao ? Đồng thời anh sẽ giới thiệu các cách truy vấn dữ liệu trong database.
ORM là viết tắt của Object Relational Mapping, là một quá trình ánh xạ (chuyển đổi) dữ liệu từ ngôn ngữ hướng đối tượng sang Database quan hệ và ngược lại. ORM giúp mình ánh xạ các tables,column,kiểu dữ liệu và mối quan hệ (1-1,1-n,n-n) trong database thành các Class và thuộc tính trong Java. Anh lấy ví dụ. Trong database mình có table (person) và các trường (id kiểu Integer , name kiểu varchar ) như sau.
1
2
3
4
CREATE TABLE persons (
id integer NOT NULL,
name varchar(50) NOT NULL, salary float, PRIMARY KEY(id)
);
Như vậy ORM nghĩa là tương ứng với table person trong database mình ánh xạ nó trong Class Java (POJO) như sau cho tương ứng.
1
2
3
4
5
public class Person {
public String name;
public float salary;
public Person(String name) { ... }
}
Như vậy trong database có gì, thì Class Java sẽ mô tả lại y chang vậy.
Sau đây là bản mapping các kiểu dữ liệu trong mysql tương ứng với kiểu Java
.
Trong Spring thì thường mình hay sử trong các dự án Java được cung cấp bởi nhà cung cấp sau.
JPA viết tắt của từ Java Persitent API . Tầng Persistent có nhiệm vụ thao tác với database như query lấy dữ liệu , lưu dữ liệu xuống database . JPA cung cấp cho mình cơ chế ORM mapping các bảng, column , mối quan hệ trong database thành các lớp java và đồng thời cung cấp cho mình các method cần thiết để thao tác dữ liệu trong database.
Sau đây mình sẽ làm một ứng dụng đơn giản để lấy dữ liệu từ database và trả kết quả về cho người dùng. Và mình sẽ sử dụng thư viện spring-data-jpa để kết nối và thao tác với database. Ngoài ra mọi người có thể xem qua bài viết Hibernate mà anh đã viết để thao tác với database nhé. Source code tại đây .
1
2
3
4
5
6
7
8
9
10
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Data
@Entity
@Table(name = "department")
@NamedQuery( name="findAllCustomersWithName",
query="SELECT c FROM Customer c WHERE c.name LIKE :custName" )
public class Department implements Serializable {
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
public int id;
@Column(name = "name")
public String name;
@Column(name = "description")
public String description;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Controller
public class CreationQueryController {
@Autowired
DepartmentQueryCreationService departmentQueryCreationService;
@GetMapping("/creationFindbyDepartmentName/{name}")
public ModelAndView findbyDepartment(@PathVariable("name") String name) {
ModelAndView modelAndView = new ModelAndView("creation");
List<Department> departments = departmentQueryCreationService.findByDepartment(name);
modelAndView.addObject("departments",departments);
return modelAndView;
}
}
Service có nhiệm vụ thực hiện các nghiệp vụ của ứng dụng . Đồng thời nhúng bean Repository để gọi tầng Persistence.
1
2
3
4
5
6
7
8
9
10
@Service
public class DepartmentQueryCreationService {
@Autowired
DepartmentQueryCreationRepository departmentQueryCreationRepository;
public List<Department> findByDepartment(String name) {
return departmentQueryCreationRepository.findByName(name);
}
}
Tầng này có nhiệm vụ thao tác lấy dữ liệu. Các cách lấy dữ liệu sẽ được giới thiệu riêng ở bài khác.
1
2
3
4
5
6
7
8
9
10
11
12
@Transactional
public interface DepartmentAnnotationRepository extends JpaRepository<Department,Integer> {
@Query("select department from Department department where department.name = ?1")
Department findByName(String departmentName);
@Query("select department from Department department where department.name like %?1")
List<Department> findByFirstnameEndsWith(String departmentName);
@Query(value = "select department from Department department where department.name = ?1", nativeQuery = true)
Department findByName2(String departmentName);
}
Luồng 1 : Lấy dữ liệu mình bắt đầu từ Client .
Client -> Controller -> Service -> JPA -> Query database .
Luống 2 : Trả dữ liệu từ Database .
Database -> JPA -> Service -> Controller -> Client .
Tổng hợp các các cách query xuống database .