当前位置: 首页 > news >正文

Spring Data 2026 高级查询:数据访问的新境界

Spring Data 2026 高级查询:数据访问的新境界

别叫我大神,叫我 Alex 就好。今天我们来聊聊 Spring Data 2026 的高级查询功能,这是数据访问的新境界。

一、Spring Data 2026 概述

Spring Data 2026 是 Spring 生态系统中数据访问的最新版本,它带来了一系列强大的新特性和改进,旨在简化数据访问,提高查询效率。

核心优势

  • 简化数据访问:减少样板代码,提高开发效率
  • 强大的查询能力:支持复杂的查询场景
  • 多数据源支持:无缝集成各种数据源
  • 性能优化:内置查询优化机制
  • 与现代 Java 特性集成:支持虚拟线程、模式匹配等

二、高级查询特性

1. 复杂条件查询

Spring Data 2026 提供了更强大的条件查询能力:

@Repository public interface UserRepository extends JpaRepository<User, Long> { // 基本条件查询 List<User> findByAgeGreaterThanAndActive(int age, boolean active); // 模糊查询 List<User> findByUsernameLike(String username); // 排序查询 List<User> findByActiveTrueOrderByCreatedAtDesc(); // 分页查询 Page<User> findByActiveTrue(Pageable pageable); } // 使用示例 @Service public class UserService { private final UserRepository userRepository; public UserService(UserRepository userRepository) { this.userRepository = userRepository; } public List<User> getActiveUsers(int minAge) { return userRepository.findByAgeGreaterThanAndActive(minAge, true); } public Page<User> getActiveUsersPage(int page, int size) { Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdAt")); return userRepository.findByActiveTrue(pageable); } }

2. JPQL 查询

使用 JPQL 进行复杂查询:

@Repository public interface OrderRepository extends JpaRepository<Order, Long> { @Query("SELECT o FROM Order o WHERE o.user.id = :userId AND o.status = :status") List<Order> findByUserIdAndStatus(@Param("userId") Long userId, @Param("status") OrderStatus status); @Query("SELECT o FROM Order o JOIN o.items i WHERE i.productId = :productId") List<Order> findByProductId(@Param("productId") Long productId); @Query("SELECT o FROM Order o WHERE o.totalPrice > :minPrice ORDER BY o.createdAt DESC") Page<Order> findByTotalPriceGreaterThan(@Param("minPrice") BigDecimal minPrice, Pageable pageable); }

3. 原生 SQL 查询

对于复杂场景,使用原生 SQL:

@Repository public interface ProductRepository extends JpaRepository<Product, Long> { @Query(value = "SELECT * FROM products WHERE price > :minPrice AND category = :category", nativeQuery = true) List<Product> findByPriceAndCategory(@Param("minPrice") BigDecimal minPrice, @Param("category") String category); @Query(value = "SELECT p.id, p.name, p.price, COUNT(o.id) as orderCount " + "FROM products p LEFT JOIN order_items oi ON p.id = oi.product_id " + "LEFT JOIN orders o ON oi.order_id = o.id " + "WHERE o.created_at BETWEEN :startDate AND :endDate " + "GROUP BY p.id, p.name, p.price " + "ORDER BY orderCount DESC", nativeQuery = true) List<Object[]> findTopSellingProducts(@Param("startDate") LocalDate startDate, @Param("endDate") LocalDate endDate); }

三、查询方法进阶

1. 动态查询

使用 Specification 进行动态查询:

@Repository public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> { } @Service public class UserService { private final UserRepository userRepository; public UserService(UserRepository userRepository) { this.userRepository = userRepository; } public List<User> searchUsers(UserSearchCriteria criteria) { Specification<User> spec = Specification.where(null); if (criteria.getMinAge() != null) { spec = spec.and((root, query, cb) -> cb.greaterThan(root.get("age"), criteria.getMinAge())); } if (criteria.getMaxAge() != null) { spec = spec.and((root, query, cb) -> cb.lessThan(root.get("age"), criteria.getMaxAge())); } if (criteria.getActive() != null) { spec = spec.and((root, query, cb) -> cb.equal(root.get("active"), criteria.getActive())); } if (criteria.getUsername() != null) { spec = spec.and((root, query, cb) -> cb.like(root.get("username"), "%" + criteria.getUsername() + "%")); } return userRepository.findAll(spec); } @Data public static class UserSearchCriteria { private Integer minAge; private Integer maxAge; private Boolean active; private String username; } }

2. 投影查询

使用投影减少数据传输:

// 接口投影 interface UserProjection { String getUsername(); String getEmail(); int getAge(); } @Repository public interface UserRepository extends JpaRepository<User, Long> { List<UserProjection> findByActiveTrue(); @Query("SELECT u.username as username, u.email as email, u.age as age FROM User u WHERE u.active = true") List<UserProjection> findActiveUsersWithProjection(); } // 类投影 @Data class UserDTO { private String username; private String email; public UserDTO(String username, String email) { this.username = username; this.email = email; } } @Repository public interface UserRepository extends JpaRepository<User, Long> { List<UserDTO> findByActiveTrue(); }

3. 批量操作

提高批量操作性能:

@Repository public interface ProductRepository extends JpaRepository<Product, Long> { @Modifying @Query("UPDATE Product p SET p.price = p.price * :multiplier WHERE p.category = :category") int updatePricesByCategory(@Param("category") String category, @Param("multiplier") double multiplier); @Modifying @Query("DELETE FROM Product p WHERE p.stock < :minStock") int deleteByStockLessThan(@Param("minStock") int minStock); } @Service @Transactional public class ProductService { private final ProductRepository productRepository; public ProductService(ProductRepository productRepository) { this.productRepository = productRepository; } public void updatePrices(String category, double multiplier) { productRepository.updatePricesByCategory(category, multiplier); } public void cleanupLowStockProducts(int minStock) { productRepository.deleteByStockLessThan(minStock); } }

四、性能优化

1. 缓存策略

集成 Spring Cache 提高查询性能:

@Configuration @EnableCaching public class CacheConfig { @Bean public CacheManager cacheManager() { SimpleCacheManager cacheManager = new SimpleCacheManager(); cacheManager.setCaches(Arrays.asList( new ConcurrentMapCache("users"), new ConcurrentMapCache("products"), new ConcurrentMapCache("orders") )); return cacheManager; } } @Service public class UserService { private final UserRepository userRepository; public UserService(UserRepository userRepository) { this.userRepository = userRepository; } @Cacheable(value = "users", key = "#id") public User getUserById(Long id) { return userRepository.findById(id) .orElseThrow(() -> new UserNotFoundException(id)); } @CachePut(value = "users", key = "#user.id") public User updateUser(User user) { return userRepository.save(user); } @CacheEvict(value = "users", key = "#id") public void deleteUser(Long id) { userRepository.deleteById(id); } }

2. 查询优化

优化查询执行计划:

@Repository public interface OrderRepository extends JpaRepository<Order, Long> { // 使用 JOIN FETCH 避免 N+1 问题 @Query("SELECT o FROM Order o JOIN FETCH o.items WHERE o.id = :id") Optional<Order> findByIdWithItems(@Param("id") Long id); // 使用索引提示 @Query(value = "SELECT * FROM orders o USE INDEX (idx_orders_user_id) WHERE o.user_id = :userId", nativeQuery = true) List<Order> findByUserIdWithIndex(@Param("userId") Long userId); } @Service public class OrderService { private final OrderRepository orderRepository; public OrderService(OrderRepository orderRepository) { this.orderRepository = orderRepository; } public Order getOrderWithItems(Long id) { return orderRepository.findByIdWithItems(id) .orElseThrow(() -> new OrderNotFoundException(id)); } }

3. 异步查询

使用虚拟线程进行异步查询:

@Service public class ProductService { private final ProductRepository productRepository; public ProductService(ProductRepository productRepository) { this.productRepository = productRepository; } @Async public CompletableFuture<List<Product>> getProductsByCategoryAsync(String category) { return CompletableFuture.supplyAsync(() -> productRepository.findByCategory(category) ); } public CompletableFuture<Page<Product>> getProductsPageAsync(int page, int size) { Pageable pageable = PageRequest.of(page, size); return CompletableFuture.supplyAsync(() -> productRepository.findAll(pageable) ); } }

五、多数据源支持

1. 多数据源配置

@Configuration public class DataSourceConfig { @Bean @Primary @ConfigurationProperties(prefix = "spring.datasource.primary") public DataSource primaryDataSource() { return DataSourceBuilder.create().build(); } @Bean @ConfigurationProperties(prefix = "spring.datasource.secondary") public DataSource secondaryDataSource() { return DataSourceBuilder.create().build(); } @Bean @Primary public LocalContainerEntityManagerFactoryBean primaryEntityManagerFactory( EntityManagerFactoryBuilder builder, @Qualifier("primaryDataSource") DataSource dataSource) { return builder .dataSource(dataSource) .packages("com.example.domain.primary") .persistenceUnit("primary") .build(); } @Bean public LocalContainerEntityManagerFactoryBean secondaryEntityManagerFactory( EntityManagerFactoryBuilder builder, @Qualifier("secondaryDataSource") DataSource dataSource) { return builder .dataSource(dataSource) .packages("com.example.domain.secondary") .persistenceUnit("secondary") .build(); } @Bean @Primary public JpaTransactionManager primaryTransactionManager( @Qualifier("primaryEntityManagerFactory") EntityManagerFactory entityManagerFactory) { return new JpaTransactionManager(entityManagerFactory); } @Bean public JpaTransactionManager secondaryTransactionManager( @Qualifier("secondaryEntityManagerFactory") EntityManagerFactory entityManagerFactory) { return new JpaTransactionManager(entityManagerFactory); } } @Repository @Transactional(transactionManager = "primaryTransactionManager") public interface UserRepository extends JpaRepository<User, Long> { } @Repository @Transactional(transactionManager = "secondaryTransactionManager") public interface ProductRepository extends JpaRepository<Product, Long> { }

2. 跨数据源事务

@Service public class OrderService { private final UserRepository userRepository; private final ProductRepository productRepository; private final OrderRepository orderRepository; public OrderService(UserRepository userRepository, ProductRepository productRepository, OrderRepository orderRepository) { this.userRepository = userRepository; this.productRepository = productRepository; this.orderRepository = orderRepository; } @Transactional(transactionManager = "primaryTransactionManager") public Order createOrder(OrderRequest request) { // 检查用户 User user = userRepository.findById(request.getUserId()) .orElseThrow(() -> new UserNotFoundException(request.getUserId())); // 检查产品(跨数据源) Product product = checkProductStock(request.getProductId(), request.getQuantity()); // 创建订单 Order order = new Order(); order.setUserId(user.getId()); order.setProductId(product.getId()); order.setQuantity(request.getQuantity()); order.setTotalPrice(product.getPrice().multiply(BigDecimal.valueOf(request.getQuantity()))); order.setStatus(OrderStatus.CREATED); return orderRepository.save(order); } @Transactional(transactionManager = "secondaryTransactionManager") public Product checkProductStock(Long productId, int quantity) { Product product = productRepository.findById(productId) .orElseThrow(() -> new ProductNotFoundException(productId)); if (product.getStock() < quantity) { throw new InsufficientStockException(productId, quantity); } // 扣减库存 product.setStock(product.getStock() - quantity); productRepository.save(product); return product; } }

六、实践案例:电商平台数据访问

场景描述

构建一个电商平台的数据访问层,支持用户、产品、订单等实体的复杂查询。

实现方案

// 用户仓库 @Repository public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> { Optional<User> findByUsername(String username); List<User> findByActiveTrue(); @Query("SELECT u FROM User u JOIN u.orders o WHERE o.status = :status GROUP BY u.id") List<User> findUsersWithOrdersByStatus(@Param("status") OrderStatus status); } // 产品仓库 @Repository public interface ProductRepository extends JpaRepository<Product, Long> { List<Product> findByCategory(String category); List<Product> findByPriceBetween(BigDecimal minPrice, BigDecimal maxPrice); @Query("SELECT p FROM Product p WHERE p.stock > 0 ORDER BY p.createdAt DESC") Page<Product> findAvailableProducts(Pageable pageable); @Query(value = "SELECT p.* FROM products p WHERE p.id IN (SELECT oi.product_id FROM order_items oi GROUP BY oi.product_id ORDER BY COUNT(*) DESC LIMIT :limit)", nativeQuery = true) List<Product> findTopSellingProducts(@Param("limit") int limit); } // 订单仓库 @Repository public interface OrderRepository extends JpaRepository<Order, Long> { List<Order> findByUserId(Long userId); List<Order> findByStatus(OrderStatus status); @Query("SELECT o FROM Order o JOIN FETCH o.items WHERE o.id = :id") Optional<Order> findByIdWithItems(@Param("id") Long id); @Query("SELECT o FROM Order o WHERE o.createdAt BETWEEN :startDate AND :endDate") List<Order> findByDateRange(@Param("startDate") LocalDateTime startDate, @Param("endDate") LocalDateTime endDate); } // 订单服务 @Service public class OrderService { private final OrderRepository orderRepository; private final UserRepository userRepository; private final ProductRepository productRepository; public OrderService(OrderRepository orderRepository, UserRepository userRepository, ProductRepository productRepository) { this.orderRepository = orderRepository; this.userRepository = userRepository; this.productRepository = productRepository; } public Order createOrder(OrderRequest request) { // 验证用户 User user = userRepository.findById(request.getUserId()) .orElseThrow(() -> new UserNotFoundException(request.getUserId())); // 验证产品和库存 Product product = productRepository.findById(request.getProductId()) .orElseThrow(() -> new ProductNotFoundException(request.getProductId())); if (product.getStock() < request.getQuantity()) { throw new InsufficientStockException(request.getProductId(), request.getQuantity()); } // 创建订单 Order order = new Order(); order.setUserId(user.getId()); order.setStatus(OrderStatus.CREATED); order.setTotalPrice(product.getPrice().multiply(BigDecimal.valueOf(request.getQuantity()))); // 创建订单项 OrderItem item = new OrderItem(); item.setProductId(product.getId()); item.setQuantity(request.getQuantity()); item.setPrice(product.getPrice()); order.addItem(item); // 保存订单 order = orderRepository.save(order); // 扣减库存 product.setStock(product.getStock() - request.getQuantity()); productRepository.save(product); return order; } public Order getOrderWithItems(Long orderId) { return orderRepository.findByIdWithItems(orderId) .orElseThrow(() -> new OrderNotFoundException(orderId)); } public List<Order> getOrdersByDateRange(LocalDateTime startDate, LocalDateTime endDate) { return orderRepository.findByDateRange(startDate, endDate); } }

七、总结与建议

Spring Data 2026 为我们提供了强大的高级查询能力,使数据访问变得更加简单和高效。以下是一些关键建议:

  1. 合理使用查询方法:根据场景选择合适的查询方式
  2. 优化查询性能:使用缓存、索引、JOIN FETCH 等技术
  3. 简化数据传输:使用投影减少不必要的数据加载
  4. 处理复杂场景:使用 Specification、JPQL 或原生 SQL
  5. 多数据源管理:合理配置和使用多数据源

这其实可以更优雅一点,通过合理使用 Spring Data 2026 的高级查询特性,我们可以构建出更高效、更可维护的数据访问层。

别叫我大神,叫我 Alex 就好。希望这篇文章能帮助你更好地理解和使用 Spring Data 2026 的高级查询功能。欢迎在评论区分享你的使用经验!

http://www.cnnetsun.cn/news/1827785.html

相关文章:

  • 喔去,litellm 竟然被投毒了,赶紧检查你的机器中招了没有垢
  • OpenCore配置可视化:OCAuxiliaryTools的技术实现与架构解析
  • 如何用Sunshine搭建专属游戏串流服务器?3个步骤让电脑变云主机
  • AlienFX Tools实战指南:3步解决Alienware灯光控制失效问题
  • 微信小程序订阅消息避坑指南:为什么你的订阅弹窗总被拒绝?
  • Diff Checker终极指南:如何在3分钟内掌握文本差异分析的核心技巧
  • #55_NE595脉冲电路
  • Open UI5 源代码解析之947:MatrixLayout.js
  • Claude Managed Agents横空出世,AI Agent开发的革命,多少项目要被淘汰?
  • Burpsuite插件Galaxy实战:5分钟搞定FastAPI接口的DES-CBC加解密调试
  • 如何快速上手PointNet_Pointnet2_pytorch:从零开始的完整教程
  • cv_unet_image-colorization模型蒸馏实践:训练更轻量、更快的小模型
  • MPC-BE多媒体播放器架构设计与性能优化深度解析
  • 突破NVIDIA垄断:AMD GPU+ROCm环境下的AI大模型本地化部署与性能调优全攻略
  • Word参考文献自动编号与引用格式优化全攻略
  • 北航毕业论文LaTeX模板:5步搞定专业排版,告别格式烦恼
  • DeepRL部署实践:从理论到工业应用的完整解决方案
  • Gemma-3-270m在AI技术中的前沿应用探索
  • 最强 AI Coding Agent 架构深度解构
  • 支付集成的优雅革命:Yansongda Pay 如何让多平台接入变得如此简单
  • WebSocket连接状态检测的实战技巧与常见问题解析
  • C#上位机对接MES系统,除了HTTP API,这几种工业协议(MQTT/OPC UA)怎么选?
  • 金山办公软件WPS:Word批量裁剪图片形状( 超实用【F4】键)
  • ROLL多任务RL训练指南:数学、编程、通用推理全流程实战
  • 手把手教你用扣子工作流实现AI批量生成古诗分镜(附完整代码)
  • Amlogic-s9xxx-openwrt性能优化:让你的盒子运行更流畅
  • 如何实现《塞尔达传说:旷野之息》存档跨平台迁移?BotW存档管理器完整指南
  • 终极Mac文件预览效率革命:QuickLook插件完全指南
  • 如何用Audit.NET轻松实现Entity Framework数据库操作审计
  • MVVM-Kotlin-Android-Architecture项目代码审查与重构建议