简介
ORM框架是对象关系映射框架的简称,是一种可以让程序员使用面向对象的方式来操作数据库的工具,它将数据库中的表和行转换成对象和属性,使得程序员可以通过面向对象的方式来进行数据库操作,这样可以避免了直接使用SQL语言对数据库进行操作时的复杂性和繁琐性。
前端
使用代码编辑器CodeMirror实现跟mybatis一样的语法
后端
使用dom4j对xml字符串进行解析赋值
public class XmlUtils {
public static String sqlAnalysis(String text, Map<String, Object> params, String id) {
try {
text = text.replaceAll("<!--.*?-->", "");
text = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + text;
Document document = DocumentHelper.parseText(text);
Element rootElement = document.getRootElement();
return resolveNode(rootElement, params, id);
} catch (DocumentException e) {
throw new GrammarException("xml语法错误");
}
}
@SuppressWarnings("unchecked")
public static String resolveNode(Element target, Map<String, Object> params, String id) {
StringBuilder sql = new StringBuilder();
List<Node> list = target.content();
for (int i = 0; i < list.size(); i++) {
Node node = list.get(i);
String typeName = node.getNodeTypeName();
if (typeName.equals("Text")) {
String text = replace(node.getText(), params);
sql.append(text);
} else if (typeName.equals("Element")) {
Element element = (Element) node;
String eleName = element.getName();
if (eleName.equals("select") || eleName.equals("insert") || eleName.equals("update")
|| eleName.equals("delete")) {
Attribute attribute = element.attribute("id");
if (attribute != null) {
if (attribute.getValue().equals(id)) {
sql.append(resolveNode(element, params, id));
break;
}
} else {
sql.append(resolveNode(element, params, id));
}
} else if (eleName.equals("where")) {
String text = resolveNode(element, params, id).trim();
if(!StringUtils.isEmpty(text)) {
text = " WHERE " + text;
if(text.startsWith(" WHERE AND ")) {
text = text.replaceAll(" WHERE AND ", " WHERE ");
}
if(text.startsWith(" WHERE and ")) {
text = text.replaceAll(" WHERE and ", " WHERE ");
}
if(text.startsWith(" WHERE OR ")) {
text = text.replaceAll(" WHERE OR ", " WHERE ");
}
if(text.startsWith(" WHERE or ")) {
text = text.replaceAll(" WHERE or ", " WHERE ");
}
sql.append(text);
}
} else if (eleName.equals("if")) {
Attribute attribute = element.attribute("test");
if (attribute != null) {
String attrValue = attribute.getValue();
attrValue = attrValue.replaceAll(" and ", " && ");
attrValue = attrValue.replaceAll(" or ", " || ");
try {
JexlEngine jexl = new JexlBuilder().create();
JexlContext context = new MapContext(params);
JexlExpression expression = jexl.createExpression(attrValue);
if ((boolean) expression.evaluate(context)) {
sql.append(resolveNode(element, params, id));
}
} catch (Exception e) {
// e.printStackTrace();
}
} else {
throw new GrammarException("if语法缺少test属性");
}
} else if (eleName.equals("foreach")) {
Attribute collectionAttribute = element.attribute("collection");
if (collectionAttribute == null) {
throw new GrammarException("foreach语法缺少collection属性");
}
Attribute itemAttribute = element.attribute("item");
if (itemAttribute == null) {
throw new GrammarException("foreach语法缺少item属性");
}
Attribute indexAttribute = element.attribute("index");
Attribute separatorAttribute = element.attribute("separator");
Attribute openAttribute = element.attribute("open");
Attribute closeAttribute = element.attribute("close");
String collection = collectionAttribute.getValue();
if (params.get(collection) == null) {
// 语法错误
throw new GrammarException(collectionAttribute.getValue() + "参数不能为空");
}
String item = itemAttribute.getValue();
String separator = "";
if (separatorAttribute != null) {
separator = separatorAttribute.getValue();
}
String index = "";
if (indexAttribute != null) {
index = indexAttribute.getValue();
}
String open = "";
if (openAttribute != null) {
open = openAttribute.getValue();
}
String close = "";
if (closeAttribute != null) {
close = closeAttribute.getValue();
}
sql.append(open);
if (params.get(collection).getClass().isArray()) {
// array
Object[] collectionArray = (Object[]) params.get(collection);
for (int j = 0; j < collectionArray.length; j++) {
params.put(item, collectionArray[j]);
if (!StringUtils.isEmpty(index)) {
params.put(index, j);
}
sql.append(resolveNode(element, params, id));
if (j != (collectionArray.length - 1)) {
sql.append(separator);
}
}
} else if (params.get(collection) instanceof Collection) {
// list
List<Object> collectionList = (List<Object>) params.get(collection);
for (int j = 0; j < collectionList.size(); j++) {
params.put(item, collectionList.get(j));
if (!StringUtils.isEmpty(index)) {
params.put(index, j);
}
sql.append(resolveNode(element, params, id));
if (j != (collectionList.size() - 1)) {
sql.append(separator);
}
}
} else if (params.get(collection) instanceof Map) {
// map
// Map<String, Object> collectionMap = (Map<String, Object>)
// params.get(collection);
}
sql.append(close);
params.remove(item);
if (!StringUtils.isEmpty(index)) {
params.remove(index);
}
} else if (eleName.equals("set")) {
sql.append(" set ");
sql.append(resolveNode(element, params, id));
}
}
}
String result = sql.toString();
result = result.replaceAll("<", "<");
result = result.replaceAll("<=", "<=");
result = result.replaceAll(">", ">");
result = result.replaceAll(">=", ">=");
return result;
}
@SuppressWarnings("unchecked")
public static String replace(String expression, Map<String, Object> env) {
Pattern pattern = Pattern.compile("(\\#\\{[^}]+\\})");
Matcher matcher = pattern.matcher(expression);
while (matcher.find()) {
String field = matcher.group(1).substring(2, matcher.group(1).length() - 1);
if (env != null) {
if(field.contains(".")) {
String parentField = field.split("\\.")[0];
String subField = field.split("\\.")[1];
Map<String, Object> value = (Map<String, Object>) env.get(parentField);
if (!StringUtils.isEmpty(value.get(subField))) {
if (value.get(subField) instanceof String) {
expression = expression.replaceAll("#\\{" + field + "\\}",
"'" + StringEscapeUtils.escapeSql(value.get(subField).toString()) + "'");
} else {
expression = expression.replaceAll("#\\{" + field + "\\}", value.get(subField).toString());
}
} else {
expression = expression.replaceAll("#\\{" + field + "\\}", "null");
}
} else {
if (!StringUtils.isEmpty(env.get(field))) {
if(field.contains(".")) {
String parentField = field.split("\\.")[0];
String subField = field.split("\\.")[1];
Map<String, Object> value = (Map<String, Object>) env.get(parentField);
if (value.get(subField) instanceof String) {
expression = expression.replaceAll("#\\{" + field + "\\}",
"'" + StringEscapeUtils.escapeSql(value.get(subField).toString()) + "'");
} else {
expression = expression.replaceAll("#\\{" + field + "\\}", value.get(subField).toString());
}
} else {
if (env.get(field) instanceof String) {
expression = expression.replaceAll("#\\{" + field + "\\}",
"'" + StringEscapeUtils.escapeSql(env.get(field).toString()) + "'");
} else {
expression = expression.replaceAll("#\\{" + field + "\\}", env.get(field).toString());
}
}
} else {
expression = expression.replaceAll("#\\{" + field + "\\}", "null");
}
}
} else {
expression = expression.replaceAll("#\\{" + field + "\\}", "null");
}
}
Pattern $pattern = Pattern.compile("(\\$\\{[^}]+\\})");
Matcher $matcher = $pattern.matcher(expression);
while ($matcher.find()) {
String field = $matcher.group(1).substring(2, $matcher.group(1).length() - 1);
if(field.contains(".")) {
String parentField = field.split("\\.")[0];
String subField = field.split("\\.")[1];
Map<String, Object> value = (Map<String, Object>) env.get(parentField);
if (!StringUtils.isEmpty(value.get(subField))) {
expression = expression.replaceAll("\\$\\{" + field + "\\}",
StringEscapeUtils.escapeSql(value.get(subField).toString()));
} else {
expression = expression.replaceAll("\\$\\{" + field + "\\}", "null");
}
} else {
if (!StringUtils.isEmpty(env.get(field))) {
expression = expression.replaceAll("\\$\\{" + field + "\\}",
StringEscapeUtils.escapeSql(env.get(field).toString()));
} else {
expression = expression.replaceAll("\\$\\{" + field + "\\}", "null");
}
}
}
return expression;
}
}