Spring Batch之读数据—读XML文件(三十二)

一、XML格式文件解析

XML是一种通用的数据交换格式,它的平台无关性、语言无关性、系统无关性,给数据集成与交换带来了极大的方便。XML在Java领域的解析方式有两种,一种叫SAX,另一种叫DOM。SAX是基于事件流的解析,DOM是基于XML文档树结构的解析。但是这两种都不适用于批处理的XML中的解析,因为两种处理方式都没有支持Stream。而StAX是一种支持Stream方式的XML解析方式。

StAX(The Streaming API for XML),是一种利用拉姆式解析(pull-parsing)XML文档的API。

二、Spring OXM

OXM是Object-to-XML-Mapping的缩写,它是一个O/X-mapper,负责将Java对象映射为XML数据,或者将XML数据映射为java对象。

Spring framework在3.0版本中引入了该特性,Spring O/X Mapper仅定义由流行的第三方框架实现的统一切面。要使用Spring的O/X Mapper功能,需提供一个能在Java对象和XML之间转换的组件。通常这样的组件有Castor、XMLBeans、Java Architecture for XML Binding(JAXB)、JiBX和XStream等。

Spring OXM框架如下:

OXM框架通过Unmarshaller接口将XML文本反序列化为Object对象,通过接口Marshaller将Object对象反序列化为XML文本。同时Spring OXM框架提供了内置的序列化和反序列化组件,包括CastorMarshaller、JibxMarshaller、XmlBeansMarshaller、XStreamMarshaller、Jaxb2Marshaller等。

三、StaxEventItemReader

StaxEventItemReader实现ItemReader接口,核心作用是将XML文件中的记录转换为Java对象。StaxEventItemReader通过引用OXM组件完成对XML的读操作,负责将XML文件转换为Java对象,并交给处理或者写阶段。

下图展示了XML文件读取的逻辑框架图,XMLEventReader负责将文件按照StaX的模式读取指定的节点数据,然后交给反序列化组件Unmarshaller完成Java对象的生成。

StaxEventItemReader关键属性

StaxEventItemReader属性 类型 说明
fragmentRootElementName String 需要转换为Java对象的根节点的名字
fragmentRootElementNameSpace String 需要转换为Java对象的根节点的命名空间
resource Resource 需要读取的资源文件
maxItemCount String 能读取的最大条目数 默认值:Integer.MAX_VALUE
strick Boolean 定义读取文件不存在时候的策略,如果为true则抛出异常,如果为false表示不抛出异常。 默认值为:true
unmarshaller Int Spring OXM实现类,负责将XML内容转换为Java对象

在实际配置StaxEventItemReader时,只需要配置Unmarshaller、Resource两个属性即可。

四、项目实例

1.项目框架

2.代码实现

BatchMain.java:

java 复制代码
package com.xj.demo24;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @Author : xjfu
 * @Date : 2021/10/26 20:01
 * @Description : demo24读XML文件
 */
public class BatchMain {
    public static void main(String[] args) {

        ApplicationContext context = new ClassPathXmlApplicationContext("demo24/job/demo24-job.xml");
        //Spring Batch的作业启动器,
        JobLauncher launcher = (JobLauncher) context.getBean("jobLauncher");
        //在batch.xml中配置的一个作业
        Job job  = (Job)context.getBean("billJob");

        try{
            //开始执行这个作业,获得处理结果(要运行的job,job参数对象)
            JobExecution result = launcher.run(job, new JobParameters());
            System.out.println(result.toString());
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

CreditBill.java:

java 复制代码
package com.xj.demo24;

/**
 * @Author : xjfu
 * @Date : 2021/10/26 19:27
 * @Description :
 */
public class CreditBill {
    //银行卡账户ID
    private String accountID = "";
    //持卡人姓名
    private String name = "";
    //消费金额
    private double amount = 0;
    //消费日期
    private String date = "";
    //消费场所
    private String address = "";

    public String getAccountID() {
        return accountID;
    }

    public void setAccountID(String accountID) {
        this.accountID = accountID;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getAmount() {
        return amount;
    }

    public void setAmount(double amount) {
        this.amount = amount;
    }

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return this.accountID + "," + this.name + "," + this.amount + "," + this.date + "," + this.address;
    }
}

demo24-job.xml:

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:batch="http://www.springframework.org/schema/batch"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd">

    <!--导入文件-->
    <import resource="classpath:demo24/job/demo24-jobContext.xml"/>

    <!--定义名字为billJob的作业-->
    <batch:job id="billJob">
        <!--定义名字为billStep的作业步-->
        <batch:step id="billStep">
            <batch:tasklet transaction-manager="transactionManager">
                <!--定义读、处理、写操作,规定每处理两条数据,进行一次写入操作,这样可以提高写的效率-->
                <batch:chunk reader="xmlReader" writer="xmlWriter" commit-interval="2">
                </batch:chunk>
            </batch:tasklet>
        </batch:step>
    </batch:job>
</beans>

demo24-jobContext.xml:

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

    <!--定义作业仓库 Job执行期间的元数据存储在内存中-->
    <bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
    </bean>

    <!--定义作业调度器,用来启动job-->
    <bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
        <!--注入jobRepository-->
        <property name="jobRepository" ref="jobRepository"/>
    </bean>

    <!--定义事务管理器,用于Spring Batch框架中对数据操作提供事务能力-->
    <bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager"/>

    <!-- XML文件读取 -->
    <bean id="xmlReader" scope="step" class="org.springframework.batch.item.xml.StaxEventItemReader">
        <!--需要转换为Java对象的根节点的名字为credit-->
        <property name="fragmentRootElementName" value="credit"/>
        <!--负责将XML内容转换为Java对象-->
        <property name="unmarshaller" ref="creditMarshaller"/>
        <!--需要读取的资源文件-->
        <property name="resource" value="classpath:demo24/data/demo24-inputXmlFile.xml"/>
    </bean>

    <!--Spring OXM实现类,负责将XML内容转换为Java对象-->
    <bean id="creditMarshaller" class="org.springframework.oxm.xstream.XStreamMarshaller">
        <property name="aliases">
            <util:map id="aliases">
                <entry key="credit" value="com.xj.demo24.CreditBill"/>
            </util:map>
        </property>
    </bean>

    <!--注入实体类-->
    <bean id="creditBill" class="com.xj.demo24.CreditBill" scope="prototype"/>

    <!-- XML文件写入 -->
    <bean id="xmlWriter" class="org.springframework.batch.item.xml.StaxEventItemWriter" scope="step">
        <property name="rootTagName" value="juxtapose"/>
        <property name="marshaller" ref="creditMarshaller"/>
        <property name="resource" value="file:src/main/resources/demo24/data/demo24-outputXmlFile.xml"/>
    </bean>

</beans>

demo24-inputXmlFile.xml:

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<credits>
    <credit>
        <accountID>4047390012345678</accountID>
        <name>tom</name>
        <amount>100.00</amount>
        <date>2013-2-2 12:00:08</date>
        <address>Lu Jia Zui road</address>
    </credit>
    <credit>
        <accountID>4047390012345678</accountID>
        <name>tom</name>
        <amount>320.00</amount>
        <date>2013-2-3 10:35:21</date>
        <address>Lu Jia Zui road</address>
    </credit>
    <credit>
        <accountID>4047390012345678</accountID>
        <name>tom</name>
        <amount>674.70</amount>
        <date>2013-2-6 16:26:49</date>
        <address>South Linyi road</address>
    </credit>
</credits>
    

3.运行结果

demo24-outputXmlFile.xml:

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?><juxtapose><credit><accountID>4047390012345678</accountID><name>tom</name><amount>100.0</amount><date>2013-2-2 12:00:08</date><address>Lu Jia Zui road</address></credit><credit><accountID>4047390012345678</accountID><name>tom</name><amount>320.0</amount><date>2013-2-3 10:35:21</date><address>Lu Jia Zui road</address></credit><credit><accountID>4047390012345678</accountID><name>tom</name><amount>674.7</amount><date>2013-2-6 16:26:49</date><address>South Linyi road</address></credit></juxtapose>
相关推荐
爱吃山竹的大肚肚15 分钟前
优化SQL:如何使用 EXPLAIN
java·数据库·spring boot·sql·spring
向上的车轮22 分钟前
Apache Camel 与 Spring Integration的区别是什么?
java·spring·apache
URBBRGROUN46732 分钟前
Spring AI Alibaba入门
java·人工智能·spring
码界奇点2 小时前
基于Spring Boot和Vue.js的视频点播管理系统设计与实现
java·vue.js·spring boot·后端·spring·毕业设计·源代码管理
爱吃山竹的大肚肚2 小时前
MySQL 支持的各类索引
java·数据库·sql·mysql·spring·spring cloud
高老庄小呆子2 小时前
SpringBoot3.5.4 引入Knife4j的官方start包
spring
廋到被风吹走2 小时前
【Spring】Spring Boot详细介绍
java·spring boot·spring
梵得儿SHI2 小时前
SpringCloud 核心组件精讲:Spring Cloud Gateway 网关实战-路由配置 + 过滤器开发 + 限流鉴权(附场景配置模板)
java·spring·spring cloud·gateway·搭建基础网关·现静态/动态路由配置·全局/局部过滤器
阿拉斯攀登3 小时前
设计模式:Spring MVC 中命令模式的核心映射与设计逻辑
spring·设计模式·mvc·命令模式
BD_Marathon3 小时前
Spring是什么
java·后端·spring