今天看到《银行主数据项目(MDM)的数据持久层,你选择hibernate还是ibatis(MyBatis)》跑到首页来了, 把我最近使用方式分享一下。Hiberante+(Spring JDBC + freemarker)两次结合,hibernate对简单的数据操作很方便,可以大量减少SQL语句的维护。对于复杂的sql和性能考虑使用Spring JDBC + freemarker,动态生成SQL。不使用hiberante的二级缓存,在业务层面进行数据缓存。
SQL标签tempateType值;simple和freeMarker, simple直接按照spring jdbc template方式书写。
使用freemarker 可以很好的解决in参数的问题。
StarFlow之前使用了mybatis,最近替换成了spring jdbc.月底会发布0.7版本。
- public class CustomSQL {
- private static Logger logger = LoggerFactory.getLogger(CustomSQL.class);
-
- private Map<String, SQLBean> _sqlPool;
-
- private static final String GROUP_BY_CLAUSE = " GROUP BY ";
- private static final String ORDER_BY_CLAUSE = " ORDER BY ";
- private static final String STRING_SPACE = " ";
-
- private final SAXReader saxReader = new SAXReader();
- private Configuration configuration = null;
- private StringTemplateLoader stringTemplateLoader = null;
-
- public CustomSQL() throws SQLException {
-
- _sqlPool = new HashMap<String, SQLBean>();
-
- try {
- ClassLoader classLoader = getClass().getClassLoader();
- configuration = new Configuration();
- stringTemplateLoader = new StringTemplateLoader();
- configuration.setDefaultEncoding("UTF-8");
-
- String[] configs = getConfigs();
- for (String _config : configs) {
- read(classLoader, _config);
- }
-
- configuration.setTemplateLoader(stringTemplateLoader);
- }
- catch (Exception e) {
- logger.error("", e);
- }
-
- }
-
- protected String[] getConfigs() {
- return new String[] {"custom-sql/default.xml"};
- }
-
- public String appendCriteria(String sql, String criteria) {
- if (StringUtils.isBlank(criteria)) {
- return sql;
- }
-
- if (!criteria.startsWith(STRING_SPACE)) {
- criteria = STRING_SPACE.concat(criteria);
- }
-
- if (!criteria.endsWith(STRING_SPACE)) {
- criteria = criteria.concat(STRING_SPACE);
- }
-
- int pos = sql.indexOf(GROUP_BY_CLAUSE);
-
- if (pos != -1) {
- return sql.substring(0, pos + 1).concat(criteria).concat(
- sql.substring(pos + 1));
- }
-
- pos = sql.indexOf(ORDER_BY_CLAUSE);
-
- if (pos != -1) {
- return sql.substring(0, pos + 1).concat(criteria).concat(
- sql.substring(pos + 1));
- }
-
- return sql.concat(criteria);
- }
-
- public String get(String id) {
- SQLBean bean = _sqlPool.get(id);
- if("simple".equals(bean.getTempateType())) {
- return _sqlPool.get(id).getContent();
- } else
- throw new RuntimeException("SQL 模板类型不正确,只可以是simple类型");
- }
-
- public String get(String id, Map<String, Object> model) {
- try {
- Template template = configuration.getTemplate(id);
- StringWriter writer = new StringWriter();
- template.process(model, writer);
- return writer.toString();
- } catch (TemplateException e) {
- throw new RuntimeException("Parse sql failed", e);
- } catch (IOException e) {
- throw new RuntimeException("Parse sql failed", e);
- }
- }
-
- protected void read(ClassLoader classLoader, String source)
- throws Exception {
-
- InputStream is = classLoader.getResourceAsStream(source);
-
- if (is == null) {
- return;
- }
-
- logger.info("Loading " + source);
-
- Document document = saxReader.read(is);
- Element rootElement = document.getRootElement();
-
- for (Object sqlObj : rootElement.elements("sql")) {
- Element sqlElement = (Element)sqlObj;
- String file = sqlElement.attributeValue("file");
-
- if (StringUtils.isNotBlank(file)) {
- read(classLoader, file);
- } else {
- String id = sqlElement.attributeValue("id");
- String sqlType = sqlElement.attributeValue("sqlType");
- String tempateType = sqlElement.attributeValue("tempateType");
-
- if("simple".equals(tempateType) || "freeMarker".equals(tempateType)) {
- String content = transform(sqlElement.getText());
-
- SQLBean bean = new SQLBean();
- bean.setTempateType(tempateType);
- bean.setSqlType(sqlType);
- bean.setContent(content);
-
- if("freeMarker".equals(tempateType))
- stringTemplateLoader.putTemplate(id, content);
-
- _sqlPool.put(id, bean);
- } else {
- logger.warn("{} 对应 tempateType 值 {} 不正确,可选值为:simple和freeMarker", id, sqlType);
- }
- }
- }
- }
-
- protected String transform(String sql) {
- StringBuilder sb = new StringBuilder();
-
- try {
- BufferedReader bufferedReader =
- new BufferedReader(new StringReader(sql));
-
- String line = null;
- while ((line = bufferedReader.readLine()) != null) {
- sb.append(line.trim());
- sb.append(STRING_SPACE);
- }
-
- bufferedReader.close();
- }
- catch (IOException ioe) {
- return sql;
- }
-
- return sb.toString();
- }
-
- public static class SQLBean {
-
-
-
- private String tempateType = "simple";
-
-
-
- private String sqlType = "SQL";
- private String content = "";
-
- public String getTempateType() {
- return tempateType;
- }
- public void setTempateType(String tempateType) {
- this.tempateType = tempateType;
- }
- public String getSqlType() {
- return sqlType;
- }
- public void setSqlType(String sqlType) {
- this.sqlType = sqlType;
- }
- public String getContent() {
- return content;
- }
- public void setContent(String content) {
- this.content = content;
- }
-
- }
-
- }
public class CustomSQL {
private static Logger logger = LoggerFactory.getLogger(CustomSQL.class);
private Map<String, SQLBean> _sqlPool;
private static final String GROUP_BY_CLAUSE = " GROUP BY ";
private static final String ORDER_BY_CLAUSE = " ORDER BY ";
private static final String STRING_SPACE = " ";
private final SAXReader saxReader = new SAXReader();
private Configuration configuration = null;
private StringTemplateLoader stringTemplateLoader = null;
public CustomSQL() throws SQLException {
_sqlPool = new HashMap<String, SQLBean>();
try {
ClassLoader classLoader = getClass().getClassLoader();
configuration = new Configuration();
stringTemplateLoader = new StringTemplateLoader();
configuration.setDefaultEncoding("UTF-8");
String[] configs = getConfigs();
for (String _config : configs) {
read(classLoader, _config);
}
configuration.setTemplateLoader(stringTemplateLoader);
}
catch (Exception e) {
logger.error("", e);
}
}
protected String[] getConfigs() {
return new String[] {"custom-sql/default.xml"};
}
public String appendCriteria(String sql, String criteria) {
if (StringUtils.isBlank(criteria)) {
return sql;
}
if (!criteria.startsWith(STRING_SPACE)) {
criteria = STRING_SPACE.concat(criteria);
}
if (!criteria.endsWith(STRING_SPACE)) {
criteria = criteria.concat(STRING_SPACE);
}
int pos = sql.indexOf(GROUP_BY_CLAUSE);
if (pos != -1) {
return sql.substring(0, pos + 1).concat(criteria).concat(
sql.substring(pos + 1));
}
pos = sql.indexOf(ORDER_BY_CLAUSE);
if (pos != -1) {
return sql.substring(0, pos + 1).concat(criteria).concat(
sql.substring(pos + 1));
}
return sql.concat(criteria);
}
public String get(String id) {
SQLBean bean = _sqlPool.get(id);
if("simple".equals(bean.getTempateType())) {
return _sqlPool.get(id).getContent();
} else
throw new RuntimeException("SQL 模板类型不正确,只可以是simple类型");
}
public String get(String id, Map<String, Object> model) {
try {
Template template = configuration.getTemplate(id);
StringWriter writer = new StringWriter();
template.process(model, writer);
return writer.toString();
} catch (TemplateException e) {
throw new RuntimeException("Parse sql failed", e);
} catch (IOException e) {
throw new RuntimeException("Parse sql failed", e);
}
}
protected void read(ClassLoader classLoader, String source)
throws Exception {
InputStream is = classLoader.getResourceAsStream(source);
if (is == null) {
return;
}
logger.info("Loading " + source);
Document document = saxReader.read(is);
Element rootElement = document.getRootElement();
for (Object sqlObj : rootElement.elements("sql")) {
Element sqlElement = (Element)sqlObj;
String file = sqlElement.attributeValue("file");
if (StringUtils.isNotBlank(file)) {
read(classLoader, file);
} else {
String id = sqlElement.attributeValue("id");
String sqlType = sqlElement.attributeValue("sqlType");
String tempateType = sqlElement.attributeValue("tempateType");
if("simple".equals(tempateType) || "freeMarker".equals(tempateType)) {
String content = transform(sqlElement.getText());
SQLBean bean = new SQLBean();
bean.setTempateType(tempateType);
bean.setSqlType(sqlType);
bean.setContent(content);
if("freeMarker".equals(tempateType))
stringTemplateLoader.putTemplate(id, content);
_sqlPool.put(id, bean);
} else {
logger.warn("{} 对应 tempateType 值 {} 不正确,可选值为:simple和freeMarker", id, sqlType);
}
}
}
}
protected String transform(String sql) {
StringBuilder sb = new StringBuilder();
try {
BufferedReader bufferedReader =
new BufferedReader(new StringReader(sql));
String line = null;
while ((line = bufferedReader.readLine()) != null) {
sb.append(line.trim());
sb.append(STRING_SPACE);
}
bufferedReader.close();
}
catch (IOException ioe) {
return sql;
}
return sb.toString();
}
public static class SQLBean {
/**
* 两种可选类型:simple和freeMarker
*/
private String tempateType = "simple";
/**
* 两种可选类型:SQL和HQL
*/
private String sqlType = "SQL";
private String content = "";
public String getTempateType() {
return tempateType;
}
public void setTempateType(String tempateType) {
this.tempateType = tempateType;
}
public String getSqlType() {
return sqlType;
}
public void setSqlType(String sqlType) {
this.sqlType = sqlType;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
}
- public class CustomSQLUtil {
- private static Logger logger = LoggerFactory.getLogger(CustomSQLUtil.class);
-
- private static CustomSQLUtil _instance = new CustomSQLUtil();
-
- private CustomSQL _customSQL;
-
- private CustomSQLUtil() {
- try {
- _customSQL = new CustomSQL();
- }
- catch (Exception e) {
- logger.error("", e);
- }
- }
-
- public static String appendCriteria(String sql, String criteria) {
- return _instance._customSQL.appendCriteria(sql, criteria);
- }
-
- public static String get(String id) {
- return _instance._customSQL.get(id);
- }
-
- public static String get(String id, Map<String, Object> model) {
- return _instance._customSQL.get(id, model);
- }
- }
public class CustomSQLUtil {
private static Logger logger = LoggerFactory.getLogger(CustomSQLUtil.class);
private static CustomSQLUtil _instance = new CustomSQLUtil();
private CustomSQL _customSQL;
private CustomSQLUtil() {
try {
_customSQL = new CustomSQL();
}
catch (Exception e) {
logger.error("", e);
}
}
public static String appendCriteria(String sql, String criteria) {
return _instance._customSQL.appendCriteria(sql, criteria);
}
public static String get(String id) {
return _instance._customSQL.get(id);
}
public static String get(String id, Map<String, Object> model) {
return _instance._customSQL.get(id, model);
}
}
实例:
- <sql id="com.*.service.home.CvToolMenuService.queryToolMenusByUser" sqlType="SQL" tempateType="freeMarker">
- <![CDATA[
- select
- a.*, (select count(*) from CV_TOOL_MENU d where d.PARENT_MENU_ID = a.RES_ID) COUNT
- from
- CV_TOOL_MENU a
- where
- exists (
- select b.TOOL_MENU_ID from ST_ROLE_TOOL_MENU b
- where a.RES_ID = b.TOOL_MENU_ID and
- <#if (paretMenuId??)>
- a.PARENT_MENU_ID = ?
- <#else>
- a.PARENT_MENU_ID is null
- </#if>
- and b.ROLE_ID in (
- <#list roleIds as id>
- ?<#if id_has_next>, </#if>
- </#list>
- ))
- ]]>
- </sql>
<sql id="com.*.service.home.CvToolMenuService.queryToolMenusByUser" sqlType="SQL" tempateType="freeMarker">
<![CDATA[
select
a.*, (select count(*) from CV_TOOL_MENU d where d.PARENT_MENU_ID = a.RES_ID) COUNT
from
CV_TOOL_MENU a
where
exists (
select b.TOOL_MENU_ID from ST_ROLE_TOOL_MENU b
where a.RES_ID = b.TOOL_MENU_ID and
<#if (paretMenuId??)>
a.PARENT_MENU_ID = ?
<#else>
a.PARENT_MENU_ID is null
</#if>
and b.ROLE_ID in (
<#list roleIds as id>
?<#if id_has_next>, </#if>
</#list>
))
]]>
</sql>
- private static String QUERY_TOOL_MENUS_BY_USER = CvToolMenuService.class.getName()+".queryToolMenusByUser";
-
- String sql = CustomSQLUtil.get(QUERY_TOOL_MENUS_BY_USER, model);
-
- List<Map<String, Object>> maps = null;
- if(parentMenuId == null)
- maps = toolMenuDao.getJdbcTemplate().queryForList(sql, roleIds.toArray());
- else {
- roleIds.add(0, parentMenuId);
- maps = toolMenuDao.getJdbcTemplate().queryForList (sql, roleIds.toArray());
- }
引用: