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代码 复制代码 收藏代码spinner.gif
  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. }
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;
		}
		
	}

}

Java代码 复制代码 收藏代码spinner.gif
  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. }
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);
	}
}


实例:
Java代码 复制代码 收藏代码spinner.gif
  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>
<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>



Java代码 复制代码 收藏代码spinner.gif
  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. }

 

 

引用:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值