Basic CRUD Operations¶
CRUD stands for Create, Read, Update, and Delete. These are the four basic operations you can perform on data in a database. Let’s see how to implement these operations using Spring Data JPA repositories.
Create Operation¶
To create a new entity, you use the save() method provided by the repository:
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public User createUser(User user) {
return userRepository.save(user);
}
}
Read Operations¶
Reading data can involve fetching a single entity or multiple entities:
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public User getUserById(Long id) {
return userRepository.findById(id)
.orElseThrow(() -> new EntityNotFoundException("User not found"));
}
public List<User> getAllUsers() {
return userRepository.findAll();
}
}
Update Operation¶
Updating an entity involves fetching it, modifying it, and then saving it back:
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public User updateUser(Long id, User userDetails) {
User user = userRepository.findById(id)
.orElseThrow(() -> new EntityNotFoundException("User not found"));
user.setUsername(userDetails.getUsername());
user.setEmail(userDetails.getEmail());
return userRepository.save(user);
}
}
Delete Operation¶
To delete an entity, you can use the deleteById() method:
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void deleteUser(Long id) {
if (!userRepository.existsById(id)) {
throw new EntityNotFoundException("User not found");
}
userRepository.deleteById(id);
}
}
Best Practices¶
Always use transactions for write operations (create, update, delete).
Handle exceptions properly, especially for cases where entities are not found.
Consider using DTOs (Data Transfer Objects) to separate your API model from your persistence model.
For bulk operations, consider using batch processing methods to improve performance.
Use pagination for methods that return large sets of data.
Example with Pagination¶
Here’s an example of how to implement pagination:
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public Page<User> getAllUsers(int page, int size) {
PageRequest pageRequest = PageRequest.of(page, size);
return userRepository.findAll(pageRequest);
}
}
This method returns a Page object, which not only contains the requested users but also the total number of pages, total number of elements, etc.
By implementing these CRUD operations in your service layer, you create a clean separation between your web layer (controllers) and your data access layer (repositories). This separation of concerns makes your code more maintainable and testable.