初衷
本人去git找源码时,发现部分代码,不提供sql文件。实在令人气愤。如果xml很多,一个一个去mysql 工具创建数据库,那也太可怕了。
思路
- 将mybatis创建的XML文件解析出来,只用到 resultMap 里面的数据。
- 根据mysql 创建数据表语句,将解析得到数据进行拼接。
- 将拼接好的数据,保存在一个.sql文件中
实践
使用 dom4j-2.1.3.jar 解析xml文件,fastjson-1.2.68.jar 格式化存放解析出来数据。
1、创建 ConvertTool 工具类,用于解析XML文件,数据拼接mysql语句。
public class ConvertTool {
public static List<JSONObject> start(String path) throws DocumentException {
// 创建saxReader对象
SAXReader reader = new SAXReader();
// 通过read方法读取一个文件 转换成Document对象
Document document = reader.read(new File(path));
//获取根节点元素对象
Element node = document.getRootElement();
List<JSONObject> jsonObject = new ArrayList<>();
//读取dom4j.xml文件中所有元素
listNodes(node,jsonObject);
System.out.println(jsonObject.toString());
return jsonObject;
}
//节点内容
public static void listNodes(Element node, List<JSONObject> jsonObject) {
String nodeName = node.getName();
if ("result".equals(nodeName) || "id".equals(nodeName)
|| "resultMap".equals(nodeName) || "mapper".equals(nodeName)) {
System.out.println("当前节点的名称::" + node.getName());
// 获取当前节点的所有属性节点
List<Attribute> list = node.attributes();
JSONObject item = new JSONObject();
// 遍历属性节点
for (Attribute attr : list) {
System.out.println(attr.getText()
+ "---" + attr.getName()
+ "---" + attr.getValue());
item.put(attr.getName(), attr.getValue());
}
if (item.get("namespace") == null) {
jsonObject.add(item);
}
//如果文本内容不是空,则打印
if (!(node.getTextTrim().equals(""))) {
System.out.println("文本内容::::" + node.getText());
}
// 当前节点下面子节点迭代器
Iterator<Element> it = node.elementIterator();
// 遍历
while (it.hasNext()) {
// 获取某个子节点对象
Element e = it.next();
// 对子节点进行遍历
listNodes(e,jsonObject);
}
} else {
return;
}
}
// 将xml解析出来的数据转换成String
public static String handleXMLToText( List<List<JSONObject>> jsonData){
StringBuffer stringBuffer = new StringBuffer();
String tableName = null; // 数据表名
String typeVal = null;
String column = null; // 列名
String jdbcType = null; // 数据类型
for(int i = 0; i < jsonData.size(); i++){
List<JSONObject> items = jsonData.get(i);
stringBuffer.append("CREATE TABLE ");
for (int j = 0; j < items.size(); j++){
JSONObject item = items.get(j);
if (item.get("column") == null) {
typeVal = (String) item.get("type");
String[] typeValS = typeVal.split("\\.");
tableName = typeValS[typeValS.length - 1];
System.out.println("数据表 名::::" + tableName);
stringBuffer.append(tableName + "( ");
} else {
column = (String) item.get("column");
jdbcType = (String) item.get("jdbcType");
stringBuffer.append(column + " " + jdbcType
+ (("VARCHAR".equals(jdbcType))? "(255)" : "")
+ (j == items.size() - 1 ? " " : "," + "\r\n"));
}
}
stringBuffer.append("\r\n )\r\n");
}
System.out.println("数据sql::::" + stringBuffer.toString());
return stringBuffer.toString();
}
}
2、创建 FileTool工具类,用于读写数据。
public class FileTool {
public static void wirte(String path,String content){
// 构建指定文件
File file = new File(path);
System.out.println("数据sql 路径::::" + path);
// 根据文件创建文件的输出流
try (OutputStream os = new FileOutputStream(file)) {
// 把内容转换成字节数组
byte[] data = content.getBytes();
// 向文件写入内容
os.write(data);
} catch (Exception e) {
e.printStackTrace();
}
}
public static List<String> getXMLFiles(String path) {
File file = new File(path);//File类型可以是文件也可以是文件夹
File[] fileList = file.listFiles();//将该目录下的所有文件放置在一个File类型的数组中
List<String> wjList = new ArrayList<String>();//新建一个文件集合
for (int i = 0; i < fileList.length; i++) {
if (fileList[i].isFile() && fileList[i].getName().endsWith(".xml") ) {//判断是否为XML文件
wjList.add(fileList[i].getAbsolutePath());
}
}
return wjList;
}
}
3、创建 JFrameMain SWING 可视化窗口类,用于操作以及一些逻辑判断
public class JFrameMain extends JFrame implements ActionListener{
JButton open = null;
Label pathLabel = null;
TextField pathText = null;
JButton openTarger = null;
Label targerLabel = null;
TextField targerText = null;
JButton handleStart = null;
public static void main(String[] args) {
new JFrameMain();
}
public JFrameMain(){
FlowLayout layout = new FlowLayout(FlowLayout.LEFT, 30, 20);
Panel pannel = new Panel(layout);
pathLabel = new Label();
pathLabel.setText("选择XML文件目录:");
pannel.add(pathLabel);
open=new JButton("选择");
open.setSize(80, 40);
pannel.add(open);
pathText = new TextField();
pathText.setColumns(50);
pathText.setEnabled(false);
pannel.add(pathText);
open.setActionCommand("path");
open.addActionListener(this);
targerLabel = new Label();
targerLabel.setText("选择存放目录:");
pannel.add(targerLabel);
openTarger=new JButton("选择");
openTarger.setSize(80, 40);
pannel.add(openTarger);
targerText = new TextField();
targerText.setColumns(50);
targerText.setEnabled(false);
pannel.add(targerText);
openTarger.setActionCommand("target");
openTarger.addActionListener(this);
handleStart = new JButton("开始");
handleStart.setSize(750, 40);
pannel.add(handleStart);
handleStart.setActionCommand("start");
handleStart.addActionListener(this);
this.setBounds(400, 200, 700, 200);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.add(pannel);
}
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("actionPerformed:"+ e.getActionCommand());
// TODO Auto-generated method stub
if ("path".equals(e.getActionCommand()) || "target".equals(e.getActionCommand())) {
JFileChooser jfc=new JFileChooser();
jfc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES );
jfc.showDialog(new JLabel(), "选择");
File file=jfc.getSelectedFile();
if(file.isDirectory()){
System.out.println("文件夹:"+file.getAbsolutePath());
if ("path".equals(e.getActionCommand())) {
pathText.setText(file.getAbsolutePath().toString());
} else if ("target".equals(e.getActionCommand())){
targerText.setText(file.getAbsolutePath().toString());
}
}else{
JOptionPane.showMessageDialog(null, "请选择文件夹");
if ("path".equals(e.getActionCommand())) {
pathText.setText("");
} else if ("target".equals(e.getActionCommand())){
pathText.setText("");
}
System.out.println("文件:"+file.getAbsolutePath());
}
System.out.println(jfc.getSelectedFile().getName());
} else if ("start".equals(e.getActionCommand())) {
String path = pathText.getText();
String targetPath = targerText.getText();
if ( ( path == null || "".equals(path))
|| ( targetPath == null || "".equals(targetPath))
) {
JOptionPane.showMessageDialog(null, "请选择文件夹");
return;
}
Long startTime = new Date().getTime();
System.out.println("开始转换"+ startTime);
handleStart.setEnabled(false);
handleFile();
System.out.println("结束转换"+ new Date().getTime());
System.out.println("转换消耗"+ (new Date().getTime() - startTime ));
handleStart.setEnabled(true);
JOptionPane.showMessageDialog(null, "转换成功转换消耗(ms)" + (new Date().getTime() - startTime ) );
}
}
private void handleFile(){
String path = pathText.getText();
List<String> datas = FileTool.getXMLFiles(path);
System.out.println("xmls文件:"+ datas.toString());
List<List<JSONObject>> jsonData = new ArrayList<>();
for (int i = 0; i < datas.size(); i++){
try {
List<JSONObject> item = ConvertTool.start(datas.get(i));
jsonData.add(item);
} catch (DocumentException e) {
e.printStackTrace();
}
}
System.out.println("xmls文件解析:"+ jsonData.toString());
String result = ConvertTool.handleXMLToText(jsonData);
String targetPath = targerText.getText();
targetPath += "\\"+ new Date().getTime()+ ".sql";
FileTool.wirte(targetPath, result);
}
}
运行 JFrameMain 即可。
页面:
源码