Spring Batch分析(一)

在前两篇文章中,我们对spring batch这个批处理框架进行了初步的学习和了解。你可以从中了解到spring batch的基本概念、应用场景、如何编写一个spring batch的demo,以及其架构设计和核心组件的简介。

今天我们将深入分析Spring Batch中一个常用的类:JdbcPagingItemReader。通过对其源码的分析,你将对Spring Batch有更深入的理解,从而更好地进行技术选型和场景化方案的落地。

1、JdbcPagingItemReader类的继承层次:

Spring Batch分析(一)可以看到,该类继承自ItemReader和ItemStream接口。

2、JdbcPagingItemReader的作用是什么?

JdbcPagingItemReader用于通过JDBC以分页方式从数据库中读取记录。它通过PagingQueryProvider构建的SQL来检索数据,并使用setPageSize(int)方法指定分页大小。通过调用read()方法请求其他页面,并返回与当前位置相对应的对象。在重新启动时,它会使用最后一个排序键值来定位要读取的第一页。排序键必须具有唯一的键约束,以确保在两次执行之间不会丢失任何数据。分页性能依赖于数据库的特定功能来限制返回的行数。设置较大的页面大小并使用与页面大小匹配的提交间隔可以提高性能。在两次调用open(ExecutionContext)之间,该实现是线程安全的,但在多线程环境中使用时,需要设置saveState=false(无重启功能)。

3、JdbcPagingItemReader的属性有哪些?

private static final String START_AFTER_VALUE = "start.after";public static final int VALUE_NOT_SET = -1;private DataSource dataSource;private PagingQueryProvider queryProvider;private Map parameterValues;private NamedParameterJdbcTemplate namedParameterJdbcTemplate;private RowMapper rowMapper;private String firstPageSql;private String remainingPagesSql;private Map startAfterValues;private Map previousStartAfterValues;private int fetchSize = VALUE_NOT_SET;

关于PagingQueryProvider接口,需要说明的是,Spring Batch根据不同的数据库类型封装了相应的实现类,如MySqlPagingQueryProvider、OraclePagingQueryProvider等,如下图所示:

Spring Batch分析(一)如果你熟悉阿里巴巴开源的DataX,那么你会发现其设计思想与Spring Batch有一定的相似性,都是通过Reader读取数据源,Writer写入数据源。DataX提供了更细粒度的控制和可插拔性,只需对需要的部分进行组装即可使用,而Spring Batch则提供了常用数据源的封装。

4、JdbcPagingItemReader也实现了InitializingBean接口的afterPropertiesSet方法:

public void afterPropertiesSet() throws Exception {    super.afterPropertiesSet();    Assert.notNull(dataSource, "DataSource may not be null");    JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);    if (fetchSize != VALUE_NOT_SET) {        jdbcTemplate.setFetchSize(fetchSize);    }    jdbcTemplate.setMaxRows(getPageSize());    namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate);    Assert.notNull(queryProvider, "QueryProvider may not be null");    queryProvider.init(dataSource);    this.firstPageSql = queryProvider.generateFirstPageQuery(getPageSize());    this.remainingPagesSql = queryProvider.generateRemainingPagesQuery(getPageSize());}

从这里可以看出,Spring Batch实际上是使用JdbcTemplate进行SQL查询的,默认的pageSize为10,然后queryProvider调用init方法,将DataSource作为参数传入。

析稿Ai写作 析稿Ai写作

科研人的高效工具:AI论文自动生成,十分钟万字,无限大纲规划写作思路。

析稿Ai写作 97 查看详情 析稿Ai写作

DataSource作为init参数传入后的代码逻辑如下:

public void init(DataSource dataSource) throws Exception {    Assert.notNull(dataSource, "A DataSource is required");    Assert.hasLength(selectClause, "selectClause must be specified");    Assert.hasLength(fromClause, "fromClause must be specified");    Assert.notEmpty(sortKeys, "sortKey must be specified");    StringBuilder sql = new StringBuilder(64);    sql.append("SELECT ").append(selectClause);    sql.append(" FROM ").append(fromClause);    if (whereClause != null) {        sql.append(" WHERE ").append(whereClause);    }    if(groupClause != null) {        sql.append(" GROUP BY ").append(groupClause);    }    List namedParameters = new ArrayList();    parameterCount = JdbcParameterUtils.countParameterPlaceholders(sql.toString(), namedParameters);    if (namedParameters.size() > 0) {        if (parameterCount != namedParameters.size()) {            throw new InvalidDataAccessApiUsageException(                "You can't use both named parameters and classic "?" placeholders: " + sql);        }        usingNamedParameters = true;    }}

从这段代码可以看出几点:

DataSource必须指定,否则会抛出异常。select查询列必须明确,不能使用select *。fromClause必须有,否则不知道从哪个表查询数据,如果不传会抛出异常。sortKey是必须的,Spring Batch要求传一个sortKey,且该sortKey必须能确定数据的唯一性,否则在批处理时会遗漏数据(需要注意的是,分页查询必须指定sortKey,这对查询性能有一定影响。如果不想指定sortKey,直接会抛出异常;如果指定了唯一key作为sortKey,但select中没有sortKey,会报列名无效的异常,且该异常不会明确指出是哪个列无效,只能通过异常堆栈判断)。

此外,Spring Batch的PagingQueryProvider只支持单表查询,不支持join类型的查询。

5、SortedKey的结构是怎样的?

public void setSortKeys(Map sortKeys) {    this.sortKeys = sortKeys;}

可以看出,SortedKey是一个Map对象,其中key是数据库表的唯一key字段名称,value是一个Order对象。Order对象只有两个属性:升序或降序,Order是一个枚举类型:

public enum Order {    ASCENDING, DESCENDING}

今天主要分享了Spring Batch中从数据库数据源读取数据的方式PagingQueryProvider。对于开源工具,我们不评价其好坏,而是吸收其设计思想,发现其不足之处。如果有余力,可以自行研发。

如果你有数据库、消息类、文件类等数据源,可以选择Spring Batch。建议每个reader读取单表数据,然后在processor中处理多个结果集,最后将数据插入目标数据源。对于database类型,希望你在使用Spring Batch的Reader读取数据时能提高性能,如使用索引,避免全表扫描等。

当然,对于数据的抽取、清洗和转换,你也可以考虑其他技术方案,如kettle、DataX(商业版是DataWorks),以及大数据类型的解决方案。同时,你还需要考虑资源问题,如时间、人力等。

以上就是Spring Batch分析(一)的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/433515.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月7日 15:09:18
下一篇 2025年11月7日 15:13:55

相关推荐

  • Python中如何调试代码?

    在python中调试代码可以使用print语句、pdb和ide。1. 使用print语句查看变量值和执行流程。2. 使用pdb设置断点和逐行执行代码。3. 使用ide如pycharm进行图形化调试,设置断点和查看变量。结合这些方法可以提高调试效率。 在Python中调试代码是每个开发者的必备技能。无…

    2025年12月14日
    000
  • 如何在Python中实现线程池?

    在python中实现线程池使用concurrent.futures模块中的threadpoolexecutor类。1) 使用该类创建线程池并提交任务。2) 选择合适的线程池大小,通过实验和监控动态调整。3) 处理任务提交和结果,使用as_completed或wait函数。4) 处理任务异常和超时,使…

    2025年12月14日
    000
  • Python中如何定义异步上下文管理器类?

    在python中定义异步上下文管理器类需要实现__aenter__和__aexit__两个方法。1.__aenter__方法在进入上下文时被调用,用于异步操作的初始化。2.__aexit__方法在退出上下文时被调用,用于资源释放和异常处理。使用异步上下文管理器可以确保资源在异步环境下被正确管理和释放…

    2025年12月14日
    000
  • 如何在Python中编写for循环?

    在python中编写for循环使用for关键字和可迭代对象,如列表、字符串或范围。1)基本用法:for item in [1, 2, 3, 4, 5]: print(item)。2)高级用法:结合enumerate和zip函数。3)注意陷阱:避免修改正在遍历的列表,使用列表副本。4)性能优化:使用列…

    2025年12月14日
    000
  • Python中如何定义数据类(@dataclass)?

    在python中,使用@dataclass装饰器定义数据类。1) 导入dataclass模块并使用@dataclass装饰类。2) 定义字段及其类型,支持默认值。3) 数据类自动生成__init__、__repr__、__eq__等方法,提高代码简洁性和可读性。 在Python中,如何定义数据类(@…

    2025年12月14日
    000
  • Python中如何操作PDF文件?

    在Python中操作PDF文件是一项非常实用的技能,无论你是需要提取PDF中的文本、合并多个PDF文件,还是添加水印和注释,都有相应的库和方法可以帮助你实现这些功能。今天我们就来深入探讨一下如何在Python中高效地操作PDF文件。 Python中操作PDF文件主要依赖于几个强大的库,比如PyPDF…

    2025年12月14日
    000
  • python怎么进入编程界面 编程界面进入步骤

    进入python编程界面的步骤包括:1. 在计算机上安装python,记得勾选“add python to path”选项;2. 打开命令行或终端,输入“python”或“python3”进入交互式解释器界面。这是一个直观且适合初学者的环境,但对于大型项目可能不够方便。 进入Python编程界面的步…

    2025年12月14日
    000
  • 怎样在Python中创建列表?

    在python中创建列表的方法包括:1) 使用方括号包围元素,如my_list = [1, 2, 3, 4, 5];2) 创建空列表,如empty_list = [];3) 使用列表推导式填充默认值,如filled_list = [0 for _ in range(10)];4) 使用list()函…

    2025年12月14日
    000
  • Python中如何使用聚合函数?

    在python中使用聚合函数可以通过内置函数、numpy和pandas实现:1)使用内置函数如sum()、max()、min()处理简单数据;2)numpy提供高效的向量化操作,如np.sum()、np.mean()等;3)pandas适合复杂数据处理,使用groupby()和mean()等函数。选…

    2025年12月14日
    000
  • Python中怎样创建setup.py?

    在python中创建setup.py文件的步骤如下:1.安装setuptools库:pip install setuptools。2.创建setup.py文件,定义项目元数据和依赖,如名称、版本、作者信息、描述、依赖包等。3.使用find_packages()自动发现项目包,确保项目结构标准。4.可…

    2025年12月14日
    000
  • Python中如何使用map和filter函数?

    在python中,map和filter函数的使用方法如下:1. map函数用于对可迭代对象的每个元素应用函数,例如将数字列表平方。2. filter函数用于根据条件筛选元素,如筛选偶数。3. 结合使用时,可以先筛选再转换数据,如提取并大写长度大于3的字符串。注意在处理大型数据时,列表推导式可能更高效…

    2025年12月14日
    000
  • Python中如何使用matplotlib绘图?

    matplotlib是python中强大的数据可视化工具。1.安装简单,使用pip install matplotlib。2.基本使用包括导入库、创建数据、绘制图形和添加标题与标签。3.高级定制可通过改变线条颜色、样式,添加图例和注解实现。4.常见问题如图形比例失调可通过查阅文档和社区资源解决。5.…

    2025年12月14日
    000
  • Python中怎样使用@property装饰器?

    @property装饰器在python中用于实现属性的getter、setter和deleter方法,使方法看起来像属性,提高代码可读性和控制访问。1)它允许在不改变接口的情况下添加控制逻辑,如数据验证。2)使用时需考虑性能影响、封装和接口稳定性、以及继承中的多态问题。合理使用@property能显…

    2025年12月14日
    000
  • Python中怎样实现with语句支持?

    在python中,实现with语句支持需要通过上下文管理器实现__enter__和__exit__方法。1) 创建一个类,如filehandler,包含__init__方法初始化文件名和模式。2) 在__enter__方法中打开文件并返回文件对象。3) 在__exit__方法中关闭文件,并处理可能的…

    2025年12月14日
    000
  • Python中如何识别语音?

    在python中实现语音识别可以使用speechrecognition库或云服务。1. 使用speechrecognition库,通过麦克风捕获音频并利用google speech recognition识别。2. 调整环境噪音以提高准确率。3. 支持多语言识别。4. 云服务如google clou…

    2025年12月14日
    000
  • Python中怎样实现动态属性?

    在python中,可以通过重写__getattr__、__setattr__和__delattr__方法实现动态属性。1. 重写__getattr__方法来获取属性。2. 重写__setattr__方法来设置属性。3. 重写__delattr__方法来删除属性。这种方法提供了完全控制属性的灵活性,但…

    2025年12月14日
    000
  • 如何确保Python代码的安全性?

    确保python代码的安全性需要从多个方面入手:1) 在代码层面,进行严格的输入验证,如使用正则表达式清理用户输入;2) 通过虚拟环境管理依赖,避免全局安装带来的安全风险;3) 在数据处理方面,使用hashlib等库安全处理密码,并结合盐值增强安全性;4) 定期更新python环境和依赖,修补已知漏…

    2025年12月14日
    000
  • python安装好了怎么运行 python运行方法介绍

    python安装好后可以通过命令行运行。1. 在命令行输入“python 文件名.py”即可运行脚本。2. 使用ide如pycharm或vs code,通过点击“运行”按钮或设置快捷键运行。3. 在线平台如jupyter notebook适合交互式编程和数据分析。 在你成功安装了Python之后,如…

    2025年12月14日
    000
  • Python中怎样使用Jinja2模板引擎?

    在python中使用jinja2模板引擎可以通过以下步骤实现:1. 安装jinja2,使用命令pip install jinja2。2. 创建模板文件,使用jinja2语法插入动态内容,如{{ title }}和{% for item in items %}。3. 编写python代码加载并渲染模板…

    2025年12月14日
    000
  • Python中如何实现数据归一化?

    在python中,数据归一化可以通过min-max归一化和z-score归一化实现:1.min-max归一化使用公式x_norm = (x – x_min) / (x_max – x_min),适用于无异常值的数据;2.z-score归一化使用公式x_norm = (x &#…

    2025年12月14日
    000

发表回复

登录后才能评论
关注微信