[Java]spring中的数据处理

写在前面

如果直接用JDBC来访问数据库,会有大量重复相似的代码,而且这样的工程逻辑也不清晰,难以维护,spring中对数据访问做了优化。

JDBC

用JDBC访问数据库的流程大致如下:
try{
	Connection connection = getDataSource().getConnection();
	Statement statement = connection.createStatement();

	// ...

	statement.executeUpdate("....");
	statement.close();
} finally {
	statement.close();
	connection.close();
}

JdbcTemplate

既然有这么多相似的代码,那么最直接的优化的方法就是将访问的过程进行封装,从而让业务代码专心地去做业务:
public class JdbcTemplate {
	public Object execute(StatementCallback action) throws DataAccessException {
		
		// 将连接数据库等操作抽取出来
	
	}
}
然后直接用它来执行对应的sql就可以了:
jdbcTemplate.execute(new StatementCallback(){
	public Object doInStatement(Statement stmt) throws SQLException {
		stmt.execute("your sql"); return ret;
	}
}
但是这样赤裸裸地把SQL和Java代码混在一起也不怎么好,还是有点乱。

iBatis

ORM是的对数据库的操作更加炉火纯青,甚至不需要写sql,不过这里要介绍的是iBatis(原因是用这个比较多)。iBatis实际上应该算是半个ORM吧,因为我们还得去编写sql。基本用法如下:
Map parameters = new HashMap();
parameters.put("param1", value);
// ..

Object ret = sqlMapClient.queryForObject("sql_id", parameters);
还有:
protected void batchInsert(final List beans) {
	sqlMapClientTemplate.execute(new SqlMapClientCallback() {
		public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
			executor.startBatch();
			Interator iter = beans.iterator();
			while(iter.hasNext()) {
				Bean bean = (Bean) iter.next();
				executor.insert("insert_name", bean);
			} 
			executor.executeBatch();
			return null;
		}
	});
}
当然在编写sqlMap的时候也是支持动态条件的,关于配置看这里

事务

当然,直接用JDBC也可以做事务,在失败的时候直接调用就可以了:
void rollback() throws SQLException;
但是就像上面讲的,这样太不方便了,下面来看TransactionTemplate的方式:
Boolean executeResult = (Boolean) transactionTemplate.execute(new TransactionCallback() {
	@Override
	public Object doInTransaction(TransactionStatus status) {
		try {
			// 操作数据库

			return true;
		} catch (Exception e) {
			status.setRollbackOnly();
			return false;
		}
	}
}
用template的方式比较灵活了,重复的代码也比较少了。但是代码调整起来还是有点大,比如将原来不是事务的东西变成是一个事务就有点麻烦了。下面来看用配置的方式:
<bean id="plantDao" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
	<property name="transactionManager">
		<ref bean="transactionManager" />
	</property>     
	<property name="target">
		<ref bean="plantDaoTarget" />
	</property> 
	<property name="proxyInterfaces">
		<value>com.*.spring.dao.PlantDao</value>
	</property>
</bean>
其他配置的方式(没有实践过,备用):
  • ProxyFactory + TransactionInterceptor
  • BeanNameAutoProxyCreator
  • Spring 2.x申明事务配置方式
在整个上面的实现中,为了实现的方便必须将connection相关的操作“丢掉”,而要丢掉比较好的办法是用ThreadLocal,这样就可以随用随取。

---------- ---------- ---------- ---------- ---------- 分割线 ---------- ---------- ---------- ---------- ----------

接下来收集一些大家可能遇到的问题。有时候需要用iBatis来执行一个SQL,可以用如下配置:
<sqlMap namespace="SQL">  
	<statement id="sqlExecute"  parameterClass="java.util.Map">  
		$sql$  
	</statement>  
</sqlMap>
用$sql$的原因是##会默认添加"",同时需要设置remapResults=true(默认为false),这样iBatis会根据每次的查询结果设置元数据,保证返回正确结果,但是会造成一定的性能损失,在这里有具体讨论。








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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值