📄 cast.java
字号:
current = (Element) simple.item(i);// 遍历该链表
currenttype = (Element) current.getElementsByTagName("restriction")
.item(0);// 取约束条件
simpleType.put(current.getAttribute("name"), currenttype
.getAttribute("base"));// 取数据类型信息,保存在hash表中
}
simpleType.put("string", "string");// 添加上基本的数据类型,目前只支持这几种,这样文件中所有的数据类型都应该映射为这几种基本的类型
simpleType.put("date", "date");
simpleType.put("integer", "integer");
simpleType.put("float", "float");
return simple;
}
private void castToSql() {
Iterator<String> output = complexType.keySet().iterator();
while (output.hasNext()) {
String tablename = output.next();// 取出表名
String tabletype = complexType.get(tablename);// 取出表类型名
/*
* Iterator<String> tempi = tableType.keySet().iterator();
* while(tempi.hasNext()) { System.out.println(tempi.next()); }
*/
if (!tableType.containsKey(tabletype))
continue;
HashMap<String, String> content = tableType.get(tabletype);// 取出表项内容
if (tablename.startsWith("#")) {
content.remove("ParentID");
tablename = tablename.substring(1);
}
sql += "if exists \r\n (select 1 \r\n from sysobjects \r\n where id = object_id('"
+ tablename
+ "') and type = 'U') \r\n drop table "
+ tablename
+ "\r\ngo \r\n\r\n"
+ "create table "
+ tablename + " (\r\n";// 如果该表以及存在,首先要删除同名的表,在创建该表
Iterator<String> attricontent = content.keySet().iterator();
ArrayList<String> keyname = key.get(tabletype);
ArrayList<String[]> rest = restriction.get(tabletype);
while (attricontent.hasNext()) {
String name = attricontent.next();
String type = content.get(name);
if (type.equalsIgnoreCase("integer"))
type = "int";
else if (type.equalsIgnoreCase("date"))
type = "datetime";
else if (type.equalsIgnoreCase("string"))
type = "varchar(30)";// 字符串统一成长度为30的可变长字符串类型存储
sql += " " + name + " " + type;
if (name.equals("ID"))
sql += " IDENTITY(1,1)";
if (name.equals("ID") || keyname != null
&& keyname.contains(name))
sql += " not null,\r\n";
else
sql += " null,\r\n";
}
sql += " constraint PK_" + tablename.toUpperCase()
+ " primary key (ID)";
if (rest != null)// 以下为生成约束条件的建表语句
for (int i = 0; i < rest.size(); i++) {
String[] currentrest = rest.get(i);
String temp = "";
if (!currentrest[1].equals("-1"))
temp += currentrest[0] + " >= " + currentrest[1]
+ " and ";
if (!currentrest[2].equals("-1"))
temp += currentrest[0] + " <= " + currentrest[2]
+ " and ";
if (!currentrest[3].equals("-1"))
temp += currentrest[0] + " in " + currentrest[3]
+ " and ";
if (!currentrest[4].equals("-1"))
temp += currentrest[0] + " like " + "'"
+ currentrest[4] + "'" + " and ";
if (temp.equals(""))
continue;
sql += ",\r\n constraint CK_"
+ currentrest[0].toUpperCase() + " check("+temp.substring(0, temp.length() - 5) + ")";
}
sql += "\r\n) \r\ngo \r\n\r\n";// \r\n作为换行,可实现回车换行
}
}
public void generate() throws Exception {
castToSql();
FileWriter myFile = new FileWriter(schemafile.substring(0, schemafile
.length() - 4)
+ ".sql");
myFile.write(sql);// 写入文件
myFile.close();// 关闭文件
// System.out.println(sql);
}
public void store(String xmlfile) throws Exception {// 指定xmlfile文件,该xml文件应该是符合实例化该实例的xml
// shema文件规定的合式的xml文件,该方法应该生成一个sql文件,其中包含了存储该xml文件内数据的insert语句
Element rootElement = getRoot(xmlfile);
String sql = "";
sql += generateInsertSql(rootElement, null, 1);
if (!sql.equals("")) {
FileWriter myFile = new FileWriter(xmlfile.substring(0, xmlfile
.length() - 4)
+ ".sql");
myFile.write(sql);// 写入文件
myFile.close();// 关闭文件
// System.out.println(sql);
}
}
private String generateInsertSql(Element root, String ParentTable,
int sequence) throws ParserConfigurationException {// 递归生成存储xml文件中数据的插入语句的函数,root是xml中的某级结点,ParentTable是其父亲节点的表名称,sequence是有序属性的顺序值
String rootname = root.getNodeName();
String insertsql = "";
String pre = "";
String varname = "@" + root.hashCode() + sequence;// 以节点的哈希值加节点顺值作为存储其父亲节点ID值的sql变量名
if (tableType.containsKey(complexType.get(rootname))
|| tableType.containsKey(complexType.get("#" + rootname))) {// 如果元素名对应的表存在
if (tableType.containsKey(complexType.get("#" + rootname)))
rootname = "#" + rootname;
// 遍历对应的属性集合
HashMap<String, String> attriset = tableType.get(complexType
.get(rootname));
Iterator<String> output = attriset.keySet().iterator();
while (output.hasNext()) {
String attriname = output.next();// 取出属性名
if (attriname.equals("ID"))
continue;// ID是自增字段,不用处理
if (attriname.equals("sequence")) {// 如果是顺序值,从参数知
insertsql += " " + sequence + ", ";
continue;
}
if (attriname.equals("ParentID")) {// 如果是父亲节点ID值,加上sql变量名
if (rootname.startsWith("#"))
continue;
if (ParentTable != null) {// 如果父亲节点存在,首先需要写入计算父亲节点ID值的sql语句,以备作为其ParentID的值
pre += "DECLARE " + varname + " INT \r\nselect "
+ varname + " = count(*) from " + ParentTable
+ "\r\n";
}
insertsql += " " + varname + ", ";
continue;
}
String attritype = attriset.get(attriname);// 取出属性的数据类型
if (!root.getAttribute(attriname).equals("")) {// 如果为节点的属性
if (attritype.equals("string") || attritype.equals("date"))
insertsql += " '" + root.getAttribute(attriname)
+ "', ";
else
insertsql += " " + root.getAttribute(attriname) + ", ";
} else {// 否则,应该是子节点中的内容
String con = root.getElementsByTagName(attriname).item(0)
.getFirstChild().getNodeValue();
if (attritype.equals("string") || attritype.equals("date"))
insertsql += " '" + con + "', ";
else
insertsql += " " + con + ", ";
}
}
// 遍历完成之后,应该所有的属性均转化成为了插入值
if (rootname.startsWith("#"))
rootname = rootname.substring(1);
insertsql = "insert into " + rootname + " values ("
+ insertsql.substring(0, insertsql.length() - 2) + ")\r\n";
if (!pre.equals(""))
insertsql = pre + insertsql;
// 接着处理外键信息
NodeList childnode = root.getChildNodes();
ArrayList<String> keyrefattri = new ArrayList<String>();
String tableName = null;
for (int i = 1; i < childnode.getLength(); i += 2) {
String attriname = childnode.item(i).getNodeName();// 取出属性名
if (keyrefToTableName.containsKey(attriname)) {// 如果是一个外键
tableName = keyrefToTableName.get(attriname);// 取出表名
if (attriset.containsKey(attriname)
&& tableName.equals(rootname))
break;// 需要跳出自己的递归
if (!keyrefattri.contains(attriname))
keyrefattri.add(attriname);
}
}
if (keyrefattri.size() != 0) {
NodeList[] keyreflist = new NodeList[keyrefattri.size()];
for (int i = 0; i < keyrefattri.size(); i++) {
keyreflist[i] = root.getElementsByTagName(keyrefattri
.get(i));
}
for (int i = 0; i < keyreflist[0].getLength(); i++) {
HashMap<String,Node> a = new HashMap<String,Node>();
for (int j = 0; j < keyreflist.length; j++)
a.put(keyrefattri.get(j),keyreflist[j].item(i));
insertsql += insertRef(a, tableName, rootname, i);
}
}
}
//处理非属性的子节点,递归调用该函数
NodeList child = root.getChildNodes();
if (insertsql.equals(""))
for (int i = 1; i < child.getLength(); i += 2)
insertsql += generateInsertSql((Element) child.item(i),
ParentTable, (i-1)/2+1);
else
for (int i = 1; i < child.getLength(); i += 2)
insertsql += generateInsertSql((Element) child.item(i),
rootname, (i-1)/2+1);
return insertsql;
}
private String insertRef(HashMap<String,Node> a, String tableName,
String ParentTable, int sequence) {//处理外键关系表的数据的插入sql语句的生成函数
String insertsql = "";
String pre = "";
String varname = "@" + a.hashCode() + sequence;
HashMap<String, String> attriset = tableType.get(complexType
.get(tableName));
Iterator<String> output = attriset.keySet().iterator();
while (output.hasNext()) {
String attriname = output.next();// 取出属性名
if (attriname.equals("ID"))
continue;// ID是自增字段,不用处理
if (attriname.equals("sequence")) {// 如果是顺序值,从参数知
insertsql += " " + sequence + ", ";
continue;
}
if (attriname.equals("ParentID")) {// 如果是父亲节点ID值,加上sql变量名
pre += "DECLARE " + varname + " INT \r\nselect " + varname
+ " = count(*) from " + ParentTable + "\r\n";
insertsql += " " + varname + ", ";
continue;
}
String attritype = attriset.get(attriname);// 取出属性的数据类型
String con = a.get(attriname).getFirstChild().getNodeValue();
if (attritype.equals("string") || attritype.equals("date"))
insertsql += " '" + con + "', ";
else
insertsql += " " + con + ", ";
}
insertsql = "insert into " + tableName + " values ("
+ insertsql.substring(0, insertsql.length() - 2) + ")\r\n";
if (!pre.equals(""))
insertsql = pre + insertsql;
return insertsql;
}
public static void main(String[] args) {
try {
new Cast("testschema.xml").generate();
new Cast("testschema.xml").store("test.xml");
} catch (Exception e) {
e.printStackTrace();
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -