Spring Data JPA 实战 - 注解式方法查询之@Query、@Modifying与派生delete

在 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 方法允许你通过方法签名自动生成删除查询。

如果你需要更详细的示例或有其他问题,请随时告诉我!

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值