`

给spring jdbctemplate加上一层“华丽外衣”-动态SQL&&SQL语句以文件存放

 
阅读更多

用hibernate用得多了,忽然怀念起自己直接写sql 的轻巧类库了。

    开源的类库中,需要写sql常用的有spring jdbc ,apache的dbutil , MyBatis。看过MyBatis文档,写过demo, 相对于hibernate这个强大的ORM工具,MyBatis可控性更好,然而今天它不主角,今天的主角是spring jdbc.

   

    spring jdbc 当我一接触到的时候,从此深深爱上了这个小巧的家伙:简单而优雅的API,配上spring本身的声名式事务!这就是一把小巧的神器!    

    然而随着我深入的了解,让我不爽的是SQL语句写在JAVA代码中,想要动态SQL自己拼字符串吧!

    但是这又有什么的?我把SQL语句放在外部文件,然后把它读出来就行了。

   有这想法第一步想到的是:

   利用Spring注入功能,把SQL注入到bean中去,但是想想又不合适,不喜欢用xml方式配置spring bean ,如果每个   bean都注入几条SQL,不是所有要用SQL的bean都要写在xml文件吗?

   这个办法不是一个优雅的解决办法,那创建一个类,利用spring注入功能,将相关的值注入到map属性中,尝试了一下,所有的sql都丢到一个文件多不优雅!还是自己动手来读吧,dom4j读xml很简单,上代码:

 

public class SQLBuilder {

	private static Logger logger = LoggerFactory.getLogger(SQLBuilder.class);

	private Map<String, String> sqlContainer = null;

	private String sqlFilePath = "systemSql.xml";

	public SQLBuilder() {

		initSqlContainer();
	}

	public SQLBuilder(String sqlFilePath) {

		this.sqlFilePath = sqlFilePath;
		initSqlContainer();
	}

	public String getSql(String key) {
		String sql = sqlContainer.get(key);
		if (sql == null || "".equals(sql))
			logger.warn("不存在该SQL语句");
		if (logger.isDebugEnabled()) {
			logger.debug("SQL:" + sql);
		}
		return sql;
	}

	public String getDynamicalSql(String key, Map<String, ?> param) {
		String sql = sqlContainer.get(key);

		return VelocityUtils.render(sql, param);
	}


	@SuppressWarnings("unchecked")
	private void initSqlContainer() {
		sqlContainer = new ConcurrentHashMap<String, String>();
		if (sqlFilePath == null || "".equals(sqlFilePath)) {
            throw new NullPointerException("sql语句文件不能为空!");
		}
		String[] files = sqlFilePath.split(";");
		for (String file : files) {
			readSQLFromFile(file);
		}
	}

	private void readSQLFromFile(String fileName) {
		InputStream ips = Thread.currentThread().getContextClassLoader()
				.getResourceAsStream(fileName);
		Document document = null;
		SAXReader saxReader = new SAXReader();
		try {
			document = saxReader.read(ips);
		} catch (DocumentException e) {
			logger.error("读取系统中用到的SQL 语句XML出错");
			throw new RuntimeException("读取sql语句XML文件出错:" + e.getMessage());
		}
		Element root = document.getRootElement();
		List<Element> sqlElements = root.selectNodes("//sqlElement");
		String key;
		for (Element sql : sqlElements) {
			key=sql.attribute("key").getValue();
			if(sqlContainer.containsKey(key)){
				logger.warn("key值:"+key+"重复");
			}
			sqlContainer.put(key, sql.getText());

		}

		if (ips != null) {
			try {
				ips.close();
			} catch (IOException e) {
				logger.error("关闭输入流出错:" + e.getMessage());
			}
		}
	}

	public void setSqlFilePath(String sqlFilePath) {
		this.sqlFilePath = sqlFilePath;
	}

	@Override
	protected void finalize() throws Throwable {
		super.finalize();
		if (sqlContainer != null) {
			sqlContainer.clear();
			sqlContainer = null;
		}

	}

}

 

模板技术用过freemarker ,velocity 我喜欢velocity多点,直接拿springside 里面工具类生成动态SQL

/**
 * 使用Velocity生成内容的工具类.
 * 
 * @author calvin
 */
public class VelocityUtils {

	static {
		try {
			Velocity.init();
		} catch (Exception e) {
			throw new RuntimeException("Exception occurs while initialize the velociy.", e);
		}
	}

	/**
	 * 渲染内容.
	 * 
	 * @param template 模板内容.
	 * @param model 变量Map.
	 */
	public static String render(String template, Map<String, ?> model) {
		try {
			VelocityContext velocityContext = new VelocityContext(model);
			StringWriter result = new StringWriter();
			Velocity.evaluate(velocityContext, result, "", template);
			return result.toString();
		} catch (Exception e) {
			throw new RuntimeException("Parse template failed.", e);
		}
	}
}

 

<?xml version="1.0" encoding="UTF-8"?>
<sqls>
	<sqlElement key="queryUser">
		<![CDATA[
		
		select *  from t_userInfo
		
		]]>
	</sqlElement>

	<sqlElement key="insertUser">
		<![CDATA[
		
		insert into t_userInfo(sex,age,userName,address,contactNumber,mobilePhone)
		 values(:sex,:age,:userName,:address,:contactNumber,:mobilePhone)
		
		]]>
	</sqlElement>
	<sqlElement key="updateUser">
		<![CDATA[
		
		update t_userInfo set userName=:userName where userID=:userID
		
		]]>
	</sqlElement>

	<sqlElement key="deleteUser">
	<![CDATA[
	
	delete from  t_userInfo   where userID=:userID
	
	]]>

	</sqlElement>
	
	
    <sqlElement key="search">
	
	<![CDATA[
	
	select * from t_userinfo
	
	#if( $user.userName !="")
	 where userName like :userName
	#end
	
	]]>
     
	</sqlElement>

</sqls>

 

调用:可以自己创建对象,或者将SQLBuilder 放到spring容器中,让spring 管理bean

   SQLBuilder是线程安全的建议仅创建一个实例,减少读取SQL语句文件 的IO消耗!

public class JdbcTest {

	@Resource
	DataSource dataSource;

	@Resource
	SQLBuilder sqlBuilder;

	private NamedParameterJdbcOperations jdbcTemplate;

	public JdbcTest() {
		// jdbcTemplate = getJdbcTemplate();
	}

	public NamedParameterJdbcOperations getJdbcTemplate() {
		return jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);

	}

	

	@Transactional
	public void deleteUser(Map<String, Integer> param) {
		getJdbcTemplate().update(sqlBuilder.getSql("deleteUser"), param);
	}

}

 

分享到:
评论

相关推荐

    打印JdbcTemplate执行sql

    这篇博客文章的标题"打印JdbcTemplate执行sql"主要涉及如何在使用`JdbcTemplate`时,追踪并打印出执行的SQL语句,这对于调试和性能分析非常有帮助。接下来,我们将深入探讨`JdbcTemplate`的工作原理以及如何实现SQL...

    spring-jdbcTemplate实例工程

    1. **JdbcTemplate对象**:这是Spring JdbcTemplate的核心,它包含了执行SQL语句的所有方法,如update()用于更新,query()用于查询,insert()用于插入等。 2. **参数绑定**:JdbcTemplate支持多种方式的参数绑定,...

    SpringJdbcTemplate封装工具类

    SpringJdbcTemplate是一个模板类,它提供了大量的方法来执行SQL查询、更新、存储过程等操作。这些方法会自动处理JDBC相关的资源关闭、异常转换等细节,使得代码更加整洁和健壮。 2. **数据库自适应** Spring...

    基于注解的Spring JdbcTemplate

    在Spring配置文件中,我们需要定义一个`JdbcTemplate` bean,如下所示: ```xml &lt;bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"&gt; ``` 其中,`dataSource`是指向数据库连接池的...

    day4-Spring JdbcTemplate & 声明式事务.md

    数据源负责连接数据库,而JdbcTemplate则用于执行SQL语句。 ```xml &lt;!-- 在Spring配置文件中定义数据源 --&gt; &lt;bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"&gt; ...

    Spring JDBCTemplate连接池jar包

    总之,Spring JDBCTemplate结合连接池提供了一个高效且易于使用的数据库访问层,它降低了数据库操作的复杂性,同时也提升了系统的性能。正确配置和使用这些库,可以极大地优化我们的数据库应用程序。

    Spring JdbcTemplate

    **Spring JdbcTemplate**是Spring框架中的一个核心组件,主要用于简化Java数据库访问。它提供了一种模板化的方式来执行SQL语句,使得开发人员可以避免编写大量的重复代码,专注于业务逻辑,而不是底层的数据库交互...

    strut2+spring+springjdbctemplate做的简易登录系统

    Spring JDBC Template被用来简化数据库操作,它提供了一种模板方法模式,将SQL执行、结果集处理等细节进行了封装,使得开发者只需要关注SQL语句和处理结果即可。例如,登录验证可能涉及查询用户表,查找与输入用户名...

    Spring JdbcTemplate 常用方法整理

    Spring的JdbcTemplate是Spring框架中用于简化数据库操作的工具类,它是基于JDBC但又抽象出了一层,避免了直接与数据库驱动API交互,从而提高了代码的可读性和可维护性。本文将深入探讨Spring JdbcTemplate的常用方法...

    Spring-JdbcTemplate

    - **JdbcTemplate**:作为 Spring 对 JDBC 的包装,它提供了一系列的模板方法和回调接口,用于执行 SQL 语句,并对异常进行了统一处理。 ### 2. JdbcTemplate 的主要功能 - **查询**:支持简单的 SQL 查询,预编译...

    struts+spring +jdbctemplate demo

    - Spring配置文件:如applicationContext.xml,定义了bean的声明和依赖关系,包括Action类和使用JdbcTemplate的数据访问层bean。 - 数据库连接配置:可能在Spring配置文件中或者单独的properties文件中,定义了...

    SSH笔记-Spring JdbcTemplate

    SSH笔记-Spring JdbcTemplate是关于如何在Spring框架中利用JdbcTemplate进行数据库操作的教程。Spring是一个广泛应用的Java企业级应用框架,它提供了多种数据访问工具,而JdbcTemplate就是其中之一,用于简化JDBC...

    spring的jdbcTemplate小案例

    JdbcTemplate是Spring提供的一种数据库操作工具,它简化了数据库访问,使开发者能够编写出更健壮、更易于维护的代码,避免了手动处理JDBC连接、预编译SQL语句等繁琐任务。 首先,我们来理解一下JdbcTemplate的基本...

    Spring JdbcTemplate例子

    Spring JdbcTemplate是Spring框架中的一个核心组件,主要用来简化数据库操作。它提供了一种模板方法设计模式,将SQL语句的执行与结果处理进行了抽象,使得开发者可以更加专注于业务逻辑,而无需关心底层数据访问的...

    spring-springMvc-jdbctemplate.rar

    JdbcTemplate支持SQL语句的动态构造,可以方便地执行查询、更新、插入和删除等操作。 数据库方面,本项目选择了Oracle,这是一个流行的商业关系型数据库管理系统(RDBMS)。Oracle提供了高性能、高可用性和安全性,...

    Spring JdbcTemplate api

    根据给定的文件信息,以下是对“Spring JdbcTemplate API”的详细知识点解析: ### Spring JdbcTemplate API:数据库操作的模板模式 #### 概述 在Spring框架中,`JdbcTemplate`是一个用于简化JDBC编程的工具类,...

    Spring 中jdbcTemplate 实现执行多条sql语句示例

    总结来说,Spring的JdbcTemplate提供了一种方便、安全的方式来执行多条SQL语句,尤其是在需要确保数据一致性的情况下。通过批处理和事务管理,我们可以有效地处理复杂的数据库操作,避免因单个操作失败而导致的数据...

    Spring--JdbcTemplate.pdf

    JdbcTemplate是Spring中常用的持久层技术之一,它支持Spring的声明式事务管理,能够与Spring的其他框架组件无缝整合。 描述中提到的"一图详解(脑图)"意味着文档中可能包含了一个清晰的图示,这个图示将详细展示...

    使用Spring JDBCTemplate进行增删改查curd操作

    在Spring框架中,JdbcTemplate是用于简化数据库操作的重要工具,它是Spring JDBC模块的一部分。通过使用JdbcTemplate,开发者可以避免编写大量的重复代码,如手动管理连接、处理结果集等,从而专注于业务逻辑。本文...

    一个简单的spring-jdbctemplate扩展

    Spring的JdbcTemplate是Spring框架中的一个核心组件,用于简化数据库操作。它提供了一种模板方法模式,抽象出常见的JDBC代码,使得开发者可以避免编写大量的重复性代码,从而更加专注于业务逻辑。本项目是对Spring ...

Global site tag (gtag.js) - Google Analytics