Hibernate+Spring+JDBC+Freemarker

今天看到《银行主数据项目(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版本。
Java代码 复制代码 收藏代码
  1. public class CustomSQL {
  2. private static Logger logger = LoggerFactory.getLogger(CustomSQL.class);
  3. private Map<String, SQLBean> _sqlPool;
  4. private static final String GROUP_BY_CLAUSE = " GROUP BY ";
  5. private static final String ORDER_BY_CLAUSE = " ORDER BY ";
  6. private static final String STRING_SPACE = " ";
  7. private final SAXReader saxReader = new SAXReader();
  8. private Configuration configuration = null;
  9. private StringTemplateLoader stringTemplateLoader = null;
  10. public CustomSQL() throws SQLException {
  11. _sqlPool = new HashMap<String, SQLBean>();
  12. try {
  13. ClassLoader classLoader = getClass().getClassLoader();
  14. configuration = new Configuration();
  15. stringTemplateLoader = new StringTemplateLoader();
  16. configuration.setDefaultEncoding("UTF-8");
  17. String[] configs = getConfigs();
  18. for (String _config : configs) {
  19. read(classLoader, _config);
  20. }
  21. configuration.setTemplateLoader(stringTemplateLoader);
  22. }
  23. catch (Exception e) {
  24. logger.error("", e);
  25. }
  26. }
  27. protected String[] getConfigs() {
  28. return new String[] {"custom-sql/default.xml"};
  29. }
  30. public String appendCriteria(String sql, String criteria) {
  31. if (StringUtils.isBlank(criteria)) {
  32. return sql;
  33. }
  34. if (!criteria.startsWith(STRING_SPACE)) {
  35. criteria = STRING_SPACE.concat(criteria);
  36. }
  37. if (!criteria.endsWith(STRING_SPACE)) {
  38. criteria = criteria.concat(STRING_SPACE);
  39. }
  40. int pos = sql.indexOf(GROUP_BY_CLAUSE);
  41. if (pos != -1) {
  42. return sql.substring(0, pos + 1).concat(criteria).concat(
  43. sql.substring(pos + 1));
  44. }
  45. pos = sql.indexOf(ORDER_BY_CLAUSE);
  46. if (pos != -1) {
  47. return sql.substring(0, pos + 1).concat(criteria).concat(
  48. sql.substring(pos + 1));
  49. }
  50. return sql.concat(criteria);
  51. }
  52. public String get(String id) {
  53. SQLBean bean = _sqlPool.get(id);
  54. if("simple".equals(bean.getTempateType())) {
  55. return _sqlPool.get(id).getContent();
  56. } else
  57. throw new RuntimeException("SQL 模板类型不正确,只可以是simple类型");
  58. }
  59. public String get(String id, Map<String, Object> model) {
  60. try {
  61. Template template = configuration.getTemplate(id);
  62. StringWriter writer = new StringWriter();
  63. template.process(model, writer);
  64. return writer.toString();
  65. } catch (TemplateException e) {
  66. throw new RuntimeException("Parse sql failed", e);
  67. } catch (IOException e) {
  68. throw new RuntimeException("Parse sql failed", e);
  69. }
  70. }
  71. protected void read(ClassLoader classLoader, String source)
  72. throws Exception {
  73. InputStream is = classLoader.getResourceAsStream(source);
  74. if (is == null) {
  75. return;
  76. }
  77. logger.info("Loading " + source);
  78. Document document = saxReader.read(is);
  79. Element rootElement = document.getRootElement();
  80. for (Object sqlObj : rootElement.elements("sql")) {
  81. Element sqlElement = (Element)sqlObj;
  82. String file = sqlElement.attributeValue("file");
  83. if (StringUtils.isNotBlank(file)) {
  84. read(classLoader, file);
  85. } else {
  86. String id = sqlElement.attributeValue("id");
  87. String sqlType = sqlElement.attributeValue("sqlType");
  88. String tempateType = sqlElement.attributeValue("tempateType");
  89. if("simple".equals(tempateType) || "freeMarker".equals(tempateType)) {
  90. String content = transform(sqlElement.getText());
  91. SQLBean bean = new SQLBean();
  92. bean.setTempateType(tempateType);
  93. bean.setSqlType(sqlType);
  94. bean.setContent(content);
  95. if("freeMarker".equals(tempateType))
  96. stringTemplateLoader.putTemplate(id, content);
  97. _sqlPool.put(id, bean);
  98. } else {
  99. logger.warn("{} 对应 tempateType 值 {} 不正确,可选值为:simple和freeMarker", id, sqlType);
  100. }
  101. }
  102. }
  103. }
  104. protected String transform(String sql) {
  105. StringBuilder sb = new StringBuilder();
  106. try {
  107. BufferedReader bufferedReader =
  108. new BufferedReader(new StringReader(sql));
  109. String line = null;
  110. while ((line = bufferedReader.readLine()) != null) {
  111. sb.append(line.trim());
  112. sb.append(STRING_SPACE);
  113. }
  114. bufferedReader.close();
  115. }
  116. catch (IOException ioe) {
  117. return sql;
  118. }
  119. return sb.toString();
  120. }
  121. public static class SQLBean {
  122. /**
  123. * 两种可选类型:simple和freeMarker
  124. */
  125. private String tempateType = "simple";
  126. /**
  127. * 两种可选类型:SQL和HQL
  128. */
  129. private String sqlType = "SQL";
  130. private String content = "";
  131. public String getTempateType() {
  132. return tempateType;
  133. }
  134. public void setTempateType(String tempateType) {
  135. this.tempateType = tempateType;
  136. }
  137. public String getSqlType() {
  138. return sqlType;
  139. }
  140. public void setSqlType(String sqlType) {
  141. this.sqlType = sqlType;
  142. }
  143. public String getContent() {
  144. return content;
  145. }
  146. public void setContent(String content) {
  147. this.content = content;
  148. }
  149. }
  150. }

Java代码 复制代码 收藏代码
  1. public class CustomSQLUtil {
  2. private static Logger logger = LoggerFactory.getLogger(CustomSQLUtil.class);
  3. private static CustomSQLUtil _instance = new CustomSQLUtil();
  4. private CustomSQL _customSQL;
  5. private CustomSQLUtil() {
  6. try {
  7. _customSQL = new CustomSQL();
  8. }
  9. catch (Exception e) {
  10. logger.error("", e);
  11. }
  12. }
  13. public static String appendCriteria(String sql, String criteria) {
  14. return _instance._customSQL.appendCriteria(sql, criteria);
  15. }
  16. public static String get(String id) {
  17. return _instance._customSQL.get(id);
  18. }
  19. public static String get(String id, Map<String, Object> model) {
  20. return _instance._customSQL.get(id, model);
  21. }
  22. }


实例:
Java代码 复制代码 收藏代码
  1. <sql id="com.*.service.home.CvToolMenuService.queryToolMenusByUser" sqlType="SQL" tempateType="freeMarker">
  2. <![CDATA[
  3. select
  4. a.*, (select count(*) from CV_TOOL_MENU d where d.PARENT_MENU_ID = a.RES_ID) COUNT
  5. from
  6. CV_TOOL_MENU a
  7. where
  8. exists (
  9. select b.TOOL_MENU_ID from ST_ROLE_TOOL_MENU b
  10. where a.RES_ID = b.TOOL_MENU_ID and
  11. <#if (paretMenuId??)>
  12. a.PARENT_MENU_ID = ?
  13. <#else>
  14. a.PARENT_MENU_ID is null
  15. </#if>
  16. and b.ROLE_ID in (
  17. <#list roleIds as id>
  18. ?<#if id_has_next>, </#if>
  19. </#list>
  20. ))
  21. ]]>
  22. </sql>



Java代码 复制代码 收藏代码
  1. private static String QUERY_TOOL_MENUS_BY_USER = CvToolMenuService.class.getName()+".queryToolMenusByUser";
  2. String sql = CustomSQLUtil.get(QUERY_TOOL_MENUS_BY_USER, model);
  3. List<Map<String, Object>> maps = null;
  4. if(parentMenuId == null)
  5. maps = toolMenuDao.getJdbcTemplate().queryForList(sql, roleIds.toArray());
  6. else {
  7. roleIds.add(0, parentMenuId);
  8. maps = toolMenuDao.getJdbcTemplate().queryForList (sql, roleIds.toArray());
  9. }

 

 

引用:

你可能感兴趣的:(Hibernate)