Spring Boot Data JDBC如何为所有数据库查询统一过滤指定记录
方案1:使用@Where注解(推荐,Spring Data JDBC 3.0及以上版本支持)
这是最简便的实现方式,仅需给实体类添加@Where注解指定全局过滤条件,所有针对该实体的查询(包括CrudRepository自带方法、自定义派生查询)都会自动拼接该过滤条件:
import org.springframework.data.annotation.Id; import org.springframework.data.relational.core.mapping.Table; import org.springframework.data.relational.core.mapping.Where; @Table("Customers") @Where("isDisabled = 0") record Customer(@Id Long id, String name) {}
你的Repository代码不需要做任何修改,调用findAll()、findById()、findByName()等所有查询方法时,会自动过滤isDisabled=1的记录。
方案2:使用@SoftDelete注解(适合逻辑删除场景,Spring Data JDBC 2.4及以上版本支持)
如果你的isDisabled是逻辑删除标记位,后续需要支持软删除操作(调用delete方法时仅标记为禁用,不物理删除数据),可以直接用@SoftDelete注解:
- 先在实体中补充
isDisabled字段并加注解:
import org.springframework.data.annotation.Id; import org.springframework.data.relational.core.mapping.Table; import org.springframework.data.relational.core.mapping.SoftDelete; @Table("Customers") record Customer( @Id Long id, String name, // value指定被标记为删除的值,defaultTo指定正常状态的值 @SoftDelete(value = "1", defaultTo = "0") boolean isDisabled ) {}
- 无需修改Repository代码,除了自动过滤禁用记录外,调用
repository.deleteById(id)时会自动将对应记录的isDisabled设为1,不会物理删除数据。
方案3:自定义基础Repository实现(低版本兼容方案)
如果你用的Spring Data JDBC版本不支持上述注解,可以自定义公共的基础Repository接口统一重写查询逻辑:
- 定义基础Repository接口,加
@NoRepositoryBean注解避免Spring实例化:
import org.springframework.data.repository.NoRepositoryBean; import org.springframework.data.repository.CrudRepository; import org.springframework.data.jdbc.repository.query.Query; import java.util.List; import java.util.Optional; @NoRepositoryBean public interface FilterDisabledRepository<T, ID> extends CrudRepository<T, ID> { @Override @Query("SELECT * FROM #{#entityName} WHERE id = :id AND isDisabled = 0") Optional<T> findById(ID id); @Override @Query("SELECT * FROM #{#entityName} WHERE isDisabled = 0") List<T> findAll(); // 其他需要过滤的Crud方法也可以在这里统一重写 }
- 你的业务Repository继承该基础接口即可:
public interface CustomerRepository extends FilterDisabledRepository<Customer, Long> { // 自定义查询方法按照正常规则编写即可,也可以手动加isDisabled过滤条件 }
以上三种方案都可以实现你要求的效果,针对你给出的示例数据:
- 调用
findAll()返回的结果会自动排除id为2的Brittany记录 - 调用
findById(2)会返回空的Optional
内容的提问来源于stack exchange,提问作者MC Emperor
相关产品推荐
相关产品推荐

