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

springboot将数据库中的数据导入到xml文件中

有时需要将数据库表中的数据导入到xml文件中。通过代码去数据库中查询数据,将查到的数据写入xml文件,格式<列名>值</列名>,表名作为根标签,列名作为子标签。达到临时保存数据的目的。

后端框架使用的是springboot,数据库使用sqlserver2019。

导入依赖

dom4j包中包含xml文件相关的方法。

其他比如连接数据库、jdbc、mybatis等不一一列举了。

        <!--xml依赖-->
        <dependency>
            <groupId>org.dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>2.1.3</version>
        </dependency>

application.yml

server:
  port: 8125

spring:
  datasource:
    driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
    url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=db_test
    username: sa
    password: rollshop

数据库

t_user表中有10条测试数据

  

Dao层

UserDao.xml

<mapper namespace="com.xml.dao.UserDao">

    <select id="queryAllUser" resultType="com.xml.pojo.User">
        select * from t_user;
    </select>

</mapper>

DataBaseDao.xml

因为需要以数据库列名作为标签,所以需要查询出表的列名。

<mapper namespace="com.xml.dao.DataBaseDao">

    <select id="queryTableColumn" resultType="java.lang.String">
        Select Name FROM SysColumns Where id=Object_Id(${tableName}) order by colorder
    </select>
</mapper>

Service层

在service层中调用方法,将t_user表中的数据导入xml文件

/**
     * 导出用户的xml数据
     */
    @Override
    public void exportUserDataXml() {
        // 导入的数据
        List<Map> dataList = new ArrayList<>();

        try {
            // 查询user表的数据
            List<User> userList = userDao.queryAllUser();
            if (EiInfoUtils.listIsEmpty(userList)) {
                return;
            }
            // 用户数据封装到导入集合中
            for (User user : userList) {
                // EiInfoUtils.objectToMap()方法,将实体类转为Map键值对类型
                dataList.add(EiInfoUtils.objectToMap(user));
            }
            // 查询t_user表的列
            List<String> tableColumn = dataBaseDao.queryTableColumn("'t_user'");
            // 生成xml文件
            XmlUtil.createXmlFile(dataList,tableColumn,"UserTable","userData","user");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

数据写入xml文件

为了让xml文件中,列名与数据对应,参数格式为键值对,键为实体类属性名,值为实际数据。另外还需要传入数据库列名,因为数据库命名方式与java不同,所以需要通过方法将数据库的命名修改为java的命名,即去掉“_”并且下划线后面的字母大写,从而以该名称为键值去Map中查找数据。为了更加灵活,一级根标签与二级子标签的名称手动输入。

public class XmlUtil {

    /**
     * 生成xml文件
     * @param dataList 数据集合,键值对格式
     * @param columnName 列名集合
     * @param fileName xml文件名
     * @param firstRootName xml根标签名称
     * @param secondRootName xml子标签名称
     */
    public static void createXmlFile(List<Map> dataList,List<String> columnName,String fileName,String firstRootName,String secondRootName){
        XMLWriter writer = null;
        try {
            // 生成一个Document对象
            Document doc = DocumentHelper.createDocument();
            // 添加根元素
            Element root = doc.addElement(firstRootName);
            // 为根元素添加子元素
            for (Map dataMap : dataList) {
                // 二级根元素名称
                Element rootSecond = root.addElement(secondRootName);
                for (String column : columnName) {
                    // 修改column的命名方式 user_id -> userId
                    String newColumn = changeName(column);
                    // 通过列名去键值对中查找值
                    rootSecond.addElement(newColumn).setText(String.valueOf(dataMap.get(newColumn)));
                }
            }

            // 输出xml文件
            OutputFormat format = OutputFormat.createPrettyPrint();
            writer = new XMLWriter(new OutputStreamWriter(new FileOutputStream("D:\\JavaCode\\testmaven25DataExportXml\\xml\\"+fileName+".xml"),"UTF-8"),format);
            writer.write(doc);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            // 关闭资源
            try {
                if (writer != null) {
                    writer.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 修改数据库列名的命名
     * @param str 修改前列名
     * @return 下划线去掉,下划线后面的字母改大写,第一个字母改小写
     */
    private static String changeName(String str) {

        // 字符缓冲区
        StringBuffer sbf = new StringBuffer();
        // 如果列名带有-,也去掉
        str = str.replaceAll("-", "_");
        // 如果字符串包换下划线
        if (str.contains("_")) {
            // 通过下划线将字符串分隔为数组
            String[] split = str.split("_");
            // 循环数组操作其中的字符串
            for (String s : split) {
                if (s.length()>0) {
                    char[] ch = s.toCharArray();
                    if (ch[0] >= 'a' && ch[0] <= 'z') {
                        ch[0] = (char) (ch[0] - 32);
                    }
                    // 添加到字符缓冲
                    sbf.append(ch);
                }
            }
        }else {
            sbf.append(str);
        }
        // 将最后得到的字符串的首字母改成小写
        char[] ch = sbf.toString().toCharArray();
        if (ch[0] >= 'A' && ch[0] <= 'Z') {
            ch[0] = (char) (ch[0] + 32);
        }
        return String.valueOf(ch);
    }
}

运行结果

<?xml version="1.0" encoding="UTF-8"?>

<userData>
  <user>
    <id>1</id>
    <name>hzx01</name>
    <sex>男</sex>
    <age>20</age>
    <phone>123456781</phone>
  </user>
  <user>
    <id>2</id>
    <name>hzx02</name>
    <sex>男</sex>
    <age>21</age>
    <phone>123456782</phone>
  </user>
  <user>
    <id>3</id>
    <name>hzx03</name>
    <sex>男</sex>
    <age>22</age>
    <phone>123456783</phone>
  </user>
  <user>
    <id>4</id>
    <name>hzx04</name>
    <sex>男</sex>
    <age>23</age>
    <phone>123456784</phone>
  </user>
  <user>
    <id>5</id>
    <name>hzx05</name>
    <sex>男</sex>
    <age>24</age>
    <phone>123456785</phone>
  </user>
  <user>
    <id>6</id>
    <name>hzx06</name>
    <sex>男</sex>
    <age>25</age>
    <phone>123456786</phone>
  </user>
  <user>
    <id>7</id>
    <name>hzx07</name>
    <sex>男</sex>
    <age>26</age>
    <phone>123456787</phone>
  </user>
  <user>
    <id>8</id>
    <name>hzx08</name>
    <sex>男</sex>
    <age>27</age>
    <phone>123456788</phone>
  </user>
  <user>
    <id>9</id>
    <name>hzx09</name>
    <sex>男</sex>
    <age>28</age>
    <phone>123465789</phone>
  </user>
  <user>
    <id>10</id>
    <name>hzx10</name>
    <sex>男</sex>
    <age>29</age>
    <phone>123456780</phone>
  </user>
</userData>

完整代码连接

相关文章:

  • Overlay 网络 — VxLAN 应用场景
  • C/C++ | 预处理详解
  • 深入理解pg wal日志
  • 案例1:人生重开模拟器(Python)——直接带你入门~
  • C++ 11 新玩法
  • JavaEE中的JUC的常见的类
  • 【C++入门到实战,看这篇博客总结足够了】
  • 核酸检测多少人为一组混检合适?
  • JavaWeb学习之BS/CS架构及tomcat容器项目部署
  • Python入门必会技巧:pycharm配置Python解释器【2022最新】
  • Zookeeper集群搭建(Linux环境)
  • 今天面试被问到的问题
  • 【JAVAEE框架】SpringMVC 项目起步讲解
  • 【牛客-算法】NC57 反转数字
  • 福昕电子签章服务正式上线:文档签,击穿第三方信息屏障
  • 《Java8实战》-第四章读书笔记(引入流Stream)
  • 30天自制操作系统-2
  • Angular数据绑定机制
  • PAT A1092
  • python docx文档转html页面
  • WebSocket使用
  • 百度贴吧爬虫node+vue baidu_tieba_crawler
  • 聊一聊前端的监控
  • 学习笔记DL002:AI、机器学习、表示学习、深度学习,第一次大衰退
  • 移动互联网+智能运营体系搭建=你家有金矿啊!
  • 译有关态射的一切
  • 新海诚画集[秒速5センチメートル:樱花抄·春]
  • ​LeetCode解法汇总1410. HTML 实体解析器
  • !!java web学习笔记(一到五)
  • #laravel 通过手动安装依赖PHPExcel#
  • #每日一题合集#牛客JZ23-JZ33
  • $.each()与$(selector).each()
  • (2)(2.10) LTM telemetry
  • (定时器/计数器)中断系统(详解与使用)
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (附源码)ssm高校升本考试管理系统 毕业设计 201631
  • (机器学习的矩阵)(向量、矩阵与多元线性回归)
  • (介绍与使用)物联网NodeMCUESP8266(ESP-12F)连接新版onenet mqtt协议实现上传数据(温湿度)和下发指令(控制LED灯)
  • (力扣)循环队列的实现与详解(C语言)
  • (六)库存超卖案例实战——使用mysql分布式锁解决“超卖”问题
  • (四)汇编语言——简单程序
  • (心得)获取一个数二进制序列中所有的偶数位和奇数位, 分别输出二进制序列。
  • .bat批处理(七):PC端从手机内复制文件到本地
  • .dwp和.webpart的区别
  • .halo勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .net core 3.0 linux,.NET Core 3.0 的新增功能
  • .NET Core 项目指定SDK版本
  • .NET8.0 AOT 经验分享 FreeSql/FreeRedis/FreeScheduler 均已通过测试
  • .考试倒计时43天!来提分啦!
  • [ SNOI 2013 ] Quare
  • [1181]linux两台服务器之间传输文件和文件夹
  • [20190401]关于semtimedop函数调用.txt
  • [dfs] 图案计数
  • [ESP32 IDF]web server
  • [FxCop.设计规则]8. 也许参数类型应该是基类型