在业务表关系复杂,数据量大的时候,总的说手写sql是比较好的方式。但是当sql语句较为复杂一行代码很难容纳下的时候,在没有多行字符串的java世界就相当蛋疼。mybatis这类可以在xml中管理sql语句的框架是一种比较好的选择。
我也并没有怎么深入用过这些框架,仅吸取xml管理sql的思想为jfinal做一个小小的插件。在设计方面自己也感觉有很多不顺畅的地方,在此抛砖引玉直接上代码。
package com.jfinal.plugin.sqlInXml;
import com.jfinal.plugin.IPlugin;
public class SqlInXmlPlugin implements IPlugin {
@Override
public boolean start() {
try {
SqlManager.parseSqlXml();
} catch (Exception e) {
new RuntimeException(e);
}
return true;
}
@Override
public boolean stop() {
SqlManager.clearSqlMap();
return true;
}
}
package com.jfinal.plugin.sqlInXml;
import java.io.File;
import java.io.FileFilter;
import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
public class SqlManager {
private static Map<String, String> sqlMap = new HashMap<String, String>();
public static String sql(String groupNameAndsqlId) {
return sqlMap.get(groupNameAndsqlId);
}
static void clearSqlMap() {
sqlMap.clear();
}
static void parseSqlXml() {
File file = new File(SqlManager.class.getClassLoader().getResource("").getFile());
File[] files = file.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
if (pathname.getName().endsWith("sql.xml")) {
return true;
}
return false;
}
});
for (File xmlfile : files) {
SqlGroup group = null;
try {
JAXBContext context = JAXBContext.newInstance(SqlGroup.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
group = (SqlGroup) unmarshaller.unmarshal(xmlfile);
} catch (JAXBException e) {
throw new RuntimeException(e);
}
String name = group.name;
if (name == null || name.trim().equals("")) {
name = xmlfile.getName();
}
for (SqlItem sqlItem : group.sqlItems) {
sqlMap.put(name + "." + sqlItem.id, sqlItem.value);
}
}
}
public static void main(String[] args) {
parseSqlXml();
System.out.println(sqlMap);
}
}
package com.jfinal.plugin.sqlInXml;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
class SqlGroup {
@XmlAttribute
String name;
@XmlElement(name="sql")
List<SqlItem> sqlItems = new ArrayList<SqlItem>();
void addSqlgroup(SqlItem sqlGroup) {
sqlItems.add(sqlGroup);
}
}
package com.jfinal.plugin.sqlInXml;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlValue;
@XmlRootElement
class SqlItem {
@XmlAttribute
String id;
@XmlValue
String value;
}
sql.xml
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<sqlGroup name="mobileBind">
<sql id="findByStudentMobile">select * from mobilebind where studentMobile = ?</sql>
<sql id="xx">....</sql>
</sqlGroup>
简单使用:
Model中调用
List<MobileBind> mobileBinds = find(SqlManager.sql("mobileBind.findByStudentMobile"), studentMobile);
一些问题:
SqlManager这里面的功能是否可以移到SqlInXmlPlugIn中?感觉SqlInXmlPlugin.sql()这么调用有点别扭。
另外在sql语句不是很复杂改动不频繁的情况下直接写到java类比xml方便一点。因为虽然sql在xml统一管理,又可以利用xml格式化sql语句,易于维护。 但是在java这一层来读代码又不能直接在看到sql,也是一个很烦的事情。