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>
完整代码连接