Spring Boot JPA: Database Access ด้วย Hibernate
#java13 เม.ย. 2569
Spring Data JPA คืออะไร
Spring Data JPA ทำให้ database access ง่ายขึ้นมาก ด้วย Repository pattern ที่ generate SQL ให้อัตโนมัติ
Entity
import jakarta.persistence.*;
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, length = 100)
private String name;
@Column(unique = true, nullable = false)
private String email;
@Column(name = "created_at")
private LocalDateTime createdAt;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
private List<Order> orders = new ArrayList<>();
@PrePersist
protected void onCreate() {
createdAt = LocalDateTime.now();
}
// constructors, getters, setters
}
Repository
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
public interface UserRepository extends JpaRepository<User, Long> {
// Spring Data สร้าง SQL ให้อัตโนมัติจากชื่อ method
Optional<User> findByEmail(String email);
List<User> findByNameContaining(String name);
List<User> findByCreatedAtAfter(LocalDateTime date);
boolean existsByEmail(String email);
long countByName(String name);
// Custom JPQL query
@Query("SELECT u FROM User u WHERE u.email LIKE %:domain")
List<User> findByEmailDomain(@Param("domain") String domain);
// Native SQL
@Query(value = "SELECT * FROM users WHERE YEAR(created_at) = :year",
nativeQuery = true)
List<User> findByYear(@Param("year") int year);
}
Pagination และ Sorting
// Controller
@GetMapping
public Page<User> getUsers(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size,
@RequestParam(defaultValue = "name") String sortBy) {
Pageable pageable = PageRequest.of(page, size, Sort.by(sortBy));
return userRepository.findAll(pageable);
}
Relationships
@Entity
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
private List<OrderItem> items = new ArrayList<>();
}
Transactions
@Service
@Transactional
public class OrderService {
public Order createOrder(Long userId, List<OrderItemRequest> items) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new UserNotFoundException(userId));
Order order = new Order(user);
items.forEach(item -> order.addItem(new OrderItem(item)));
return orderRepository.save(order);
// ถ้า exception เกิด transaction จะ rollback อัตโนมัติ
}
}
สรุป
Spring Data JPA ลด boilerplate code ได้มาก ด้วย Repository pattern ที่ generate SQL จากชื่อ method รองรับ pagination, sorting และ custom queries ครับ