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

spring batch 中JpaNamedQueryProvider、JpaNativeQueryProvider两种查询方式对比

完整代码示例:对比两种查询方式

// Employee.java 实体类(包含命名查询)
@Entity
@NamedQuery(name = "Employee.findAllNamedQuery", 
            query = "SELECT e FROM Employee e ORDER BY e.id") // 定义命名查询
public class Employee {
    @Id
    private Long id;
    private String name;
    private Double salary;
    // getters/setters
}

// JobConfig.java 配置类
@Configuration
@EnableBatchProcessing
public class JobConfig {

    @Autowired
    private JobBuilderFactory jobBuilderFactory;
    @Autowired
    private StepBuilderFactory stepBuilderFactory;
    @Autowired
    private EntityManagerFactory entityManagerFactory;

    @Bean
    public Job employeeJob() {
        return jobBuilderFactory.get("employeeJob")
                .start(employeeStep1()) // 使用命名查询的步骤
                .next(employeeStep2())  // 使用原生查询的步骤
                .build();
    }

    // 使用JpaNamedQueryProvider的步骤
    @Bean
    public Step employeeStep1(JpaPagingItemReader<Employee> namedQueryReader) {
        return stepBuilderFactory.get("step1")
                .<Employee, Employee>chunk(10)
                .reader(namedQueryReader)
                .writer(items -> items.forEach(System.out::println))
                .build();
    }

    // 使用JpaNativeQueryProvider的步骤
    @Bean
    public Step employeeStep2(JpaPagingItemReader<Employee> nativeQueryReader) {
        return stepBuilderFactory.get("step2")
                .<Employee, Employee>chunk(10)
                .reader(nativeQueryReader)
                .writer(items -> items.forEach(System.out::println))
                .build();
    }

    // 命名查询配置
    @Bean
    public JpaPagingItemReader<Employee> namedQueryReader() {
        return new JpaPagingItemReaderBuilder<Employee>()
            .name("namedQueryReader")
            .entityManagerFactory(entityManagerFactory)
            .pageSize(50)
            .queryProvider(new JpaNamedQueryProvider("Employee.findAllNamedQuery"))
            .build();
    }

    // 原生查询配置
    @Bean
    public JpaPagingItemReader<Employee> nativeQueryReader() {
        return new JpaPagingItemReaderBuilder<Employee>()
            .name("nativeQueryReader")
            .entityManagerFactory(entityManagerFactory)
            .pageSize(50)
            .queryProvider(new JpaNativeQueryProvider<>(
                "SELECT e.id, e.name, e.salary FROM EMPLOYEE e ORDER BY e.id", // 原生SQL
                Employee.class, // 映射实体
                new String[]{"id", "name", "salary"} // 列名到属性的映射
            ))
            .build();
    }
}

// SpringBatchApplication.java 启动类
@SpringBootApplication
@EnableBatchProcessing
public class SpringBatchApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringBatchApplication.class, args);
    }
}

关键代码说明:

  1. JpaNamedQueryProvider

    • 通过实体类上的@NamedQuery定义查询名称和JPQL语句
    • 配置时直接传入命名查询名称
    • 优势:符合JPA规范,编译时检查查询语法
  2. JpaNativeQueryProvider

    • 处理原生SQL查询,需手动指定:
      • SQL语句(注意表名与数据库实际表名一致)
      • 目标实体类型
      • 列名与实体属性的映射关系
    • 适用场景:需要复杂SQL优化或使用数据库特定语法
  3. JpaPagingItemReader

    • 核心分页读取器,自动处理分页逻辑:
      • 使用entityManagerFactory连接数据库
      • 通过pageSize控制每批数据量
      • 支持事务管理(由Spring Batch自动处理)
  4. JpaPagingItemReaderBuilder

    • 通过链式调用简化配置:

      new JpaPagingItemReaderBuilder<>()
          .name("readerName") 
          .entityManagerFactory(...) 
          .pageSize(50) 
          .queryProvider(...) 
          .build();
      
    • 必须配置:entityManagerFactoryqueryProviderpageSize


功能对比表格

类名称功能描述使用场景关键配置参数注意事项
JpaNamedQueryProvider基于实体类的命名查询管理需要复用JPQL查询查询名称(String)需与实体类的@NamedQuery一致
JpaNativeQueryProvider管理原生SQL查询,支持列名到实体属性的映射需要执行原生SQL查询SQL语句、实体类型、属性列名映射数组需确保列名与实体属性严格对应
JpaPagingItemReader分页读取数据的核心组件,支持数据库连接和分页逻辑所有需要分页读取数据的场景entityManagerFactory、pageSize、查询提供者需配合Spring Batch事务管理
JpaPagingItemReaderBuilder构建JpaPagingItemReader的辅助类,提供链式配置方式需要简化配置流程name、entityManagerFactory、pageSize、查询提供者所有参数必须显式配置

使用要点总结:

  1. 命名查询:需在实体类上通过@NamedQuery定义,保证查询名称一致性
  2. 原生查询
    • 表名需与数据库实际表名一致(区分大小写)
    • 列名必须与实体属性严格对应(如:id对应Employee.id
  3. 分页性能
    • pageSize需根据数据库性能调整,建议50-1000之间
    • 分页使用OFFSET时需注意数据库性能(如MySQL InnoDB的优化)
  4. 事务管理:Spring Batch会自动管理事务,但需确保EntityManagerFactory配置正确
  5. 数据映射:原生查询需手动指定列名映射,命名查询自动通过实体属性映射

相关文章:

  • Graphpad Prism for Mac医学绘图
  • Svelte 深度理解
  • 31天Python入门——第15天:日志记录
  • 深度学习入门1 基于Python的理论与实现
  • Photoshop 2025安装包下载及Photoshop 2025详细图文安装教程
  • 【LeetCode 题解】算法:8.字符串转换整数(atoi)
  • 自动化测试selenium(Java版)
  • CentOS 8 安装 Redis 全流程指南:从基础部署到远程安全配置
  • 音视频 三 看书的笔记 MediaPlayer的C/S架构
  • 数据库设计-笔记4
  • DeepSeek深度解析:AI在体育比分网中的应用场景与技术实践
  • Kali Linux 下安装 Sublime Text 详细教程
  • 各类神经网络学习:(五)LSTM 长短期记忆(上集),结构详解
  • 01 设计模式和设计原则
  • AI 在测试中的应用:从自动化到智能化的未来
  • Ubuntu下UEFI安全启动安装Nvdia驱动
  • JavaScript Fetch API
  • el-table + el-pagination 前端实现分页操作
  • secp256k1的模数P是如何选择的?
  • Java反射机制详解:原理、应用与最佳实践
  • “ChatGPT严选”横空出世了,“DeepSeek严选”还要等多久?
  • 东风着陆场做好各项搜救准备,迎接神舟十九号航天员天外归来
  • 2025上海体育消费节启动,多形式联动打造体育消费盛宴
  • 幸福航空五一前三天航班取消:客服称目前是锁舱状态,无法确认何时恢复
  • 最高法专门规范涉企案件审执工作:从源头防止趋利性执法司法
  • 持续更新丨伊朗官员:港口爆炸已致5人死亡超700人受伤