在 Spring Data JPA 中,@Query
注解允许你在 Repository 接口中定义自定义的 JPQL 或原生 SQL 查询。此外,@Modifying
注解用于标记修改数据库的操作,例如更新或删除。对于删除操作,Spring Data JPA 还支持派生的 delete 方法,即通过方法签名自动生成删除查询。
@Query 注解
@Query
注解可以用来定义自定义的 JPQL 或原生 SQL 查询。它允许你在 Repository 接口中定义更复杂的查询逻辑。
示例
假设我们有一个 Product
实体类:
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private Double price;
private Integer quantity;
// 构造函数、getters 和 setters 省略
}
在 ProductRepository
接口中,我们可以使用 @Query
注解来定义查询:
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface ProductRepository extends JpaRepository<Product, Long> {
// 使用 @Query 定义 JPQL 查询
@Query("SELECT p FROM Product p WHERE p.price <= :maxPrice")
List<Product> findProductsByPrice(Double maxPrice);
// 使用 @Query 定义原生 SQL 查询
@Query(value = "SELECT * FROM products WHERE price <= ?1", nativeQuery = true)
List<Product> findProductsByPriceNative(Double maxPrice);
}
@Modifying 注解
@Modifying
注解用于标记修改数据库的操作,例如更新或删除。当你使用 @Query
注解定义修改操作时,必须同时使用 @Modifying
注解。
示例
在 ProductRepository
接口中,我们可以定义一个更新操作:
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Repository
public interface ProductRepository extends JpaRepository<Product, Long> {
// 更新操作
@Modifying
@Transactional
@Query("UPDATE Product p SET p.price = :newPrice WHERE p.id = :id")
void updateProductPriceById(@Param("id") Long id, @Param("newPrice") Double newPrice);
// 使用 @Query 定义原生 SQL 更新操作
@Modifying
@Transactional
@Query(value = "UPDATE products SET price = ?2 WHERE id = ?1", nativeQuery = true)
void updateProductPriceByIdNative(Long id, Double newPrice);
}
派生的 delete 方法
Spring Data JPA 支持通过方法签名自动生成删除查询。你可以定义一个方法,其名称暗示了要执行的删除操作,Spring Data JPA 会根据方法签名自动生成相应的删除查询。
示例
在 ProductRepository
接口中,我们可以定义一个派生的 delete 方法:
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface ProductRepository extends JpaRepository<Product, Long> {
// 派生的 delete 方法
void deleteProductById(Long id);
// 派生的 delete 方法
void deleteProductByName(String name);
}
示例代码
下面是一个完整的示例,展示如何使用 @Query
、@Modifying
以及派生的 delete 方法。
实体类
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private Double price;
private Integer quantity;
// 构造函数、getters 和 setters 省略
}
Repository 接口
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Repository
public interface ProductRepository extends JpaRepository<Product, Long> {
// 使用 @Query 定义 JPQL 查询
@Query("SELECT p FROM Product p WHERE p.price <= :maxPrice")
List<Product> findProductsByPrice(Double maxPrice);
// 使用 @Query 定义原生 SQL 查询
@Query(value = "SELECT * FROM products WHERE price <= ?1", nativeQuery = true)
List<Product> findProductsByPriceNative(Double maxPrice);
// 更新操作
@Modifying
@Transactional
@Query("UPDATE Product p SET p.price = :newPrice WHERE p.id = :id")
void updateProductPriceById(@Param("id") Long id, @Param("newPrice") Double newPrice);
// 使用 @Query 定义原生 SQL 更新操作
@Modifying
@Transactional
@Query(value = "UPDATE products SET price = ?2 WHERE id = ?1", nativeQuery = true)
void updateProductPriceByIdNative(Long id, Double newPrice);
// 派生的 delete 方法
void deleteProductById(Long id);
// 派生的 delete 方法
void deleteProductByName(String name);
}
使用示例
现在,我们可以创建一个简单的服务类来使用这些方法:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class ProductService {
private final ProductRepository productRepository;
@Autowired
public ProductService(ProductRepository productRepository) {
this.productRepository = productRepository;
}
public List<Product> findProductsByPrice(Double maxPrice) {
return productRepository.findProductsByPrice(maxPrice);
}
public List<Product> findProductsByPriceNative(Double maxPrice) {
return productRepository.findProductsByPriceNative(maxPrice);
}
public void updateProductPriceById(Long id, Double newPrice) {
productRepository.updateProductPriceById(id, newPrice);
}
public void updateProductPriceByIdNative(Long id, Double newPrice) {
productRepository.updateProductPriceByIdNative(id, newPrice);
}
public void deleteProductById(Long id) {
productRepository.deleteProductById(id);
}
public void deleteProductByName(String name) {
productRepository.deleteProductByName(name);
}
}
总结
- 使用
@Query
注解可以定义自定义的 JPQL 或原生 SQL 查询。 @Modifying
注解用于标记修改数据库的操作,例如更新或删除。- 派生的 delete 方法允许你通过方法签名自动生成删除查询。
如果你需要更详细的示例或有其他问题,请随时告诉我!