最近做的一个项目中的一个模块是两个系统间数据进行交换,其中一个系统是在封闭的环境下运行的,所以许多表的数据只能通过XML文件来导入导出进行数据交互,这里我贴出我的代码供希望能给大家提供一个好的思路,并且希望能得到大家的评论,帮助这段代码改进:
- 首先是考虑到实际操作,不需要整个数据库的备份,所以我只是配了几个关键业务表的数据字典,并且在实际调试后我删除了类反射去找到类所在的包例如TASK实体类反射到com.myproject.entity.task这样的方式(可以自己根据业务来选择需不需要这么做),我的方法是把类名和类所在的包配置成了字典,这样做起来少了少许步骤,只需前台配置。贴一下我的字典配置:
- 实际XML导出的数据再导入进去的话根据的是各自表的更新时间,这里因为数据库表设计问题导致字段名称不一致所以我也是配置了一下,另外就是表结构需要有是否有效这个字段用来交互的时候判断这条数据是否是被删除了(这里就相当于一个假删除),因为两个系统间导入导出XML不可能把数据删除,只能新增和修改,下面再贴一下我的导出的格式,里面有row标签下有几个属性,其他均为实体类的属性:
- 代码实现:
主要运用的包是
alibaba的fastjson,
获取桌面路径的FileSystemView,
和Dom4J
/**
* 1.object-TO-xml
* 查找交换的数据并导出
* 拼接sql查询数据库数据,拼接进XML并导出
*/
public Result exportExchangeData(Map map){
try {
Result result=new Result();
SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddHHmmss");
Document doc = DocumentHelper.createDocument();
// 生成根节点
Element root = doc.addElement("ROOT");
String opertableNames="";
// 查找导出记录里面最新记录时间
String hqlForLastExportTime="select max(to_char(creationTime,'yyyyMMddHHmmss')) from ExchangeDataHistory";
Object findOneByHql = super.findOneByHql(hqlForLastExportTime);
//1.根据字典寻找字典值
List<Map<String,String>> entityNamesList=this.getEntityNameList("exchangDataNames");
if(null!=entityNamesList&&entityNamesList.size()>0){
List taskList;
for(Map<String,String> entitymap:entityNamesList){
String tableIntroduction = entitymap.get("tableIntroduction").toString();
String entityPackage = entitymap.get("entityPackage").toString();
Object updateTimeField = entitymap.get("updateTimeField");
Class clz=Class.forName(entityPackage);//反射找到所在的类clz
String hql="from "+clz.getSimpleName();
if(updateTimeField==null){
result.setSuccess(false);
result.setMessage("导出失败,请联系管理员");
return result;
}
if(findOneByHql!=null){
hql+=" where to_char("+updateTimeField.toString()+",'yyyyMMddHHmmss')>='"+findOneByHql.toString()+"'";
}
try {
taskList=this.taskRegService.findAllByHql(hql);
insertElement(taskList,clz,root);
opertableNames+=tableIntroduction+";";
} catch (Exception e) {
e.printStackTrace();
result.setSuccess(false);
result.setMessage("导出失败,请联系管理员,字典配置错误,请检查字典配置!");
return result;
}
}
}
// 获取桌面路径
FileSystemView fsv = FileSystemView.getFileSystemView();
File com = fsv.getHomeDirectory();
String viewPath = com.getPath();
// 写入文件
String xmlName=sdf.format(new Date());
Writer w;
w = new FileWriter(viewPath + "/" + xmlName + ".xml");
OutputFormat opf = OutputFormat.createPrettyPrint();
opf.setEncoding("GBK");
XMLWriter xw = new XMLWriter(w, opf);
xw.write(doc);
// 关闭文件流
xw.close();
w.close();
//作导出插入,更新到导出的历史记录表中
ExchangeDataHistory ex=new ExchangeDataHistory();
ex.setCreator(ManagerFactory.getUserManager().getLoginUser().getEntityName());
ex.setCreationTime(DateUtils.getCurrentTime());
ex.setExchangeType("导出");
ex.setExchangeContent(opertableNames);
this.saveEX(ex);
result.setSuccess(true);
result.setMessage("成功导出到桌面:"+xmlName+".xml");
return result;
} catch (Exception e) {
e.printStackTrace();
Result result=new Result();
result.setSuccess(false);
result.setMessage("导出失败,请联系管理员");
return result;
}
}
/**
* 获取需要字典值(字典值记录需要导出的表结构,用来反射)
*/
public List<Map<String, String>> getEntityNameList(String code) {
List<Map<String, String>> endList = new ArrayList<Map<String, String>>();
//页面的字典配置读取需要导出的实体及实体的属性
List<DictDetail> dictList = this.commonService.getDetailsByDictCode(code);
//需要itemText(表介绍),itemValue1(实体包名),itemValue3(更新时间字段)
if (null != dictList && dictList.size() > 0) {
for (DictDetail d : dictList) {
if (!StringUtils.isEmpty(d.getItemValue1()) && !StringUtils.isEmpty(d.getItemText())) {
Map map = new HashMap<String, String>();
map.put("tableIntroduction", d.getItemText());
map.put("entityPackage", d.getItemValue1());
map.put("updateTimeField", d.getItemValue3());
endList.add(map);
}
}
}
return endList;
}
/**
* 公共方法节点
* 处理数据拼接到xml节点中
* @param prjList
* @param clazz
* @param root
*/
private <T> void insertElement(List<T> prjList, Class<T> clazz, Element root) {
try {
for (int n = 0; n < prjList.size(); n++) {
Object resultObject = clazz.newInstance();//1
Field[] field = clazz.getDeclaredFields();
int fieldNum = field.length;
Object aa = prjList.get(n);//2
Element emp = root
.addElement("ROW");
for (int i = 1; i <= fieldNum; i++) {
Element column = emp.addElement(field[i - 1].getName());
Table annotation = (Table) clazz.getAnnotation(Table.class);
String name = annotation.name();
emp.addAttribute("packageName", clazz.getName());//包名
emp.addAttribute("entityName", clazz.getSimpleName());//实体名称
emp.addAttribute("tableName", name);//数据库表名称
Field field2 = clazz.getDeclaredField(field[i - 1].getName());//3
field2.setAccessible(true);
if (field2.get(aa) != null) {
column.setText(field2.get(aa) + "");
} else {
column.setText("");
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 2.xml-TO-object
* 解析数据文件并更新到数据库中
* 解析XML数据,映射成实体更新到数据库中
*/
public Result importExchangeData(MultipartFile file, Map map) {
try {
Result result = new Result();
//创建临时文件把MultipartFile转换成File类型
File f = null;
if (file.equals("") || file.getSize() <= 0) {
file = null;
} else {
InputStream ins = file.getInputStream();
f = new File(file.getOriginalFilename());
inputStreamToFile(ins, f);
}
XMLWriter writer = null;// 声明写XML的对象
SAXReader reader = new SAXReader();
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("GBK");// 设置XML文件的编码格式
//String filePath = "C:/Users/w4/Desktop/测试导出.xml";
//File file = new File(filePath);
//Document dom = reader.read(file);
Document dom = reader.read(f);
Element root = dom.getRootElement();
String rootXmlText = root.asXML();
Document dom1 = DocumentHelper.parseText(rootXmlText);
Element root1 = dom1.getRootElement();
Iterator iter = root1.elementIterator("ROW");
while (iter.hasNext()) {
Element recordEle = (Element) iter.next();
String packageName = recordEle.attributeValue("packageName");//包名
String entityName = recordEle.attributeValue("entityName");//实体名称
String tableName = recordEle.attributeValue("tableName");//数据库表名称
Class t = Class.forName(packageName);
recordEle.remove(recordEle.attribute("packageName"));
recordEle.remove(recordEle.attribute("entityName"));
recordEle.remove(recordEle.attribute("tableName"));
String text = recordEle.asXML();
org.json.JSONObject xmlJSONObj = XML.toJSONObject(text);
JSONObject j = JSON.parseObject(xmlJSONObj.get("ROW").toString());
Object o = MapUtils.createObject(t, j);
this.taskRegService.saveOrUpdate(o);
}
//删除临时文件
File del = new File(f.toURI());
del.delete();
result.setSuccess(true);
result.setMessage("导入成功");
return result;
} catch (Exception e) {
e.printStackTrace();
Result result = new Result();
result.setSuccess(false);
result.setMessage("导出失败,请联系管理员");
return result;
}
}
/**
* inpuStream转换成可以解析的file类型
* @param ins
* @param file
*/
public static void inputStreamToFile(InputStream ins, File file) {
try {
OutputStream os = new FileOutputStream(file);
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
os.write(buffer, 0, bytesRead);
}
os.close();
ins.close();
} catch (Exception e) {
e.printStackTrace();
}
}