Bài 12: Spring Boot Data Access
1. Giới thiệu về Spring Data JPA
Spring Data JPA là một phần của dự án Spring Data, cung cấp các giải pháp để dễ dàng truy cập và quản lý dữ liệu trong các ứng dụng Spring. Spring Data JPA giúp giảm thiểu mã lệnh cần viết để thực hiện các thao tác CRUD (Create, Read, Update, Delete) bằng cách cung cấp một giao diện đơn giản và dễ sử dụng.
2. Cách cấu hình DataSource và Entity
2.1. Cấu hình DataSource
Đầu tiên, bạn cần cấu hình DataSource để kết nối với cơ sở dữ liệu. Điều này có thể được thực hiện bằng cách thêm các thuộc tính kết nối vào file application.properties.
Ví dụ:
# application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
2.2. Tạo Entity
Entity là các lớp Java ánh xạ tới các bảng trong cơ sở dữ liệu. Mỗi Entity được đánh dấu bằng annotation @Entity và phải có một trường khóa chính (primary key) được đánh dấu bằng annotation @Id.
Ví dụ:
// User.java
package com.example.myapp.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
// getters and setters
}
3. Thực hiện CRUD operations với Spring Data JPA
3.1. Tạo Repository
Spring Data JPA cung cấp một interface JpaRepository cho phép bạn thực hiện các thao tác CRUD một cách dễ dàng mà không cần phải viết nhiều mã lệnh. Bạn chỉ cần tạo một interface kế thừa JpaRepository.
Ví dụ:
// UserRepository.java
package com.example.myapp.repository;
import com.example.myapp.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
}
3.2. Tạo Service
Service là lớp trung gian giữa repository và controller, chứa các logic nghiệp vụ của ứng dụng.
Ví dụ:
// UserService.java
package com.example.myapp.service;
import com.example.myapp.entity.User;
import com.example.myapp.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public List<User> findAll() {
return userRepository.findAll();
}
public Optional<User> findById(Long id) {
return userRepository.findById(id);
}
public User save(User user) {
return userRepository.save(user);
}
public void deleteById(Long id) {
userRepository.deleteById(id);
}
}
3.3. Tạo Controller
Controller là lớp điều khiển, nhận các yêu cầu từ phía người dùng và trả về kết quả sau khi xử lý.
Ví dụ:
// UserController.java
package com.example.myapp.controller;
import com.example.myapp.entity.User;
import com.example.myapp.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Optional;
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping
public List<User> getAllUsers() {
return userService.findAll();
}
@GetMapping("/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
Optional<User> user = userService.findById(id);
return user.map(ResponseEntity::ok).orElseGet(() -> ResponseEntity.notFound().build());
}
@PostMapping
public User createUser(@RequestBody User user) {
return userService.save(user);
}
@PutMapping("/{id}")
public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody User userDetails) {
Optional<User> optionalUser = userService.findById(id);
if (optionalUser.isPresent()) {
User user = optionalUser.get();
user.setName(userDetails.getName());
user.setEmail(userDetails.getEmail());
return ResponseEntity.ok(userService.save(user));
} else {
return ResponseEntity.notFound().build();
}
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
userService.deleteById(id);
return ResponseEntity.noContent().build();
}
}
4. Cấu trúc dự án
myapp
|-- src
| |-- main
| | |-- java
| | | `-- com
| | | `-- example
| | | `-- myapp
| | | |-- MyApplication.java
| | | |-- entity
| | | | `-- User.java
| | | |-- repository
| | | | `-- UserRepository.java
| | | |-- service
| | | | `-- UserService.java
| | | `-- controller
| | | `-- UserController.java
| | `-- resources
| | `-- application.properties
|-- pom.xml
5. Ví dụ chi tiết
Dưới đây là một ví dụ chi tiết từ đầu đến cuối về việc tạo một ứng dụng Spring Boot sử dụng Spring Data JPA để thực hiện các thao tác CRUD với cơ sở dữ liệu MySQL.
5.1. Tạo dự án Spring Boot
Sử dụng Spring Initializr để tạo dự án với các dependency sau:
Spring Web
Spring Data JPA
MySQL Driver
5.2. Cấu hình application.properties
# application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
5.3. Tạo Entity
// User.java
package com.example.myapp.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
// getters and setters
}
5.4. Tạo Repository
// UserRepository.java
package com.example.myapp.repository;
import com.example.myapp.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
}
5.5. Tạo Service
// UserService.java
package com.example.myapp.service;
import com.example.myapp.entity.User;
import com.example.myapp.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public List<User> findAll() {
return userRepository.findAll();
}
public Optional<User> findById(Long id) {
return userRepository.findById(id);
}
public User save(User user) {
return userRepository.save(user);
}
public void deleteById(Long id) {
userRepository.deleteById(id);
}
}
5.6. Tạo Controller
// UserController.java
package com.example.myapp.controller;
import com.example.myapp.entity.User;
import com.example.myapp.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Optional;
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping
public List<User> getAllUsers() {
return userService.findAll();
}
@GetMapping("/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
Optional<User> user = userService.findById(id);
return user.map(ResponseEntity::ok).orElseGet(() -> ResponseEntity.notFound().build());
}
@PostMapping
public User createUser(@RequestBody User user) {
return userService.save(user);
}
@PutMapping("/{id}")
public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody User userDetails) {
Optional<User> optionalUser = userService.findById(id);
if (optionalUser.isPresent()) {
User user = optionalUser.get();
user.setName(userDetails.getName());
user.setEmail(userDetails.getEmail());
return Response
Entity.ok(userService.save(user));
} else {
return ResponseEntity.notFound().build();
}
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
userService.deleteById(id);
return ResponseEntity.noContent().build();
}
}
5.7. Chạy ứng dụng
Chạy ứng dụng bằng cách sử dụng Maven:
mvn spring-boot:run
Truy cập các URL sau để thực hiện các thao tác CRUD:
GET
http://localhost:8080/api/users- Lấy danh sách tất cả người dùngGET
http://localhost:8080/api/users/{id}- Lấy thông tin người dùng theo IDPOST
http://localhost:8080/api/users- Tạo người dùng mớiPUT
http://localhost:8080/api/users/{id}- Cập nhật thông tin người dùng theo IDDELETE
http://localhost:8080/api/users/{id}- Xóa người dùng theo ID
6. Kết luận
Trong bài viết này, chúng ta đã tìm hiểu về cách truy cập dữ liệu trong Spring Boot sử dụng Spring Data JPA. Chúng ta đã thấy cách cấu hình DataSource, tạo các Entity, Repository, Service và Controller để thực hiện các thao tác CRUD với cơ sở dữ liệu MySQL. Những kiến thức này giúp bạn xây dựng các ứng dụng Spring Boot mạnh mẽ và linh hoạt với khả năng truy cập và quản lý dữ liệu một cách hiệu quả.
Trong bài viết tiếp theo, chúng ta sẽ tìm hiểu về Spring Security và cách cấu hình bảo mật cho ứng dụng Spring Boot của bạn.