使用Spring+Ibatis的项目,关于如何使用事务、如何提升性能的几点总结
转自:http://blog.csdn.net/a9529lty/archive/2010/05/24/5619520.aspx
1. 按需取数据,减少网络开销。
A 表:有 100 多个字段,存储在数据库 A 上
Id | Property1 | Property2 | … | Property120 |
|
|
|
|
|
|
|
|
|
|
B 表:只有 10 个字段,存储在数据库 B 上
Id | Property1 | Property2 | … | Property10 |
|
|
|
|
|
|
|
|
|
|
要从 A 表中查询一些数据在插入到 B 表中。
懒的做法:把所有数据全读出来,当获取 2000 条数据时,网络耗时约 15 秒。在项目过程中,有开发人员偷懒,就写了如下的 sql ,导致调用远程服务取数据时,设定服务超时时间为 3 秒,结果总是超时。
1. select * from A where … 2. 把从 A 表获得的数据转换成符合 B 表格式的数据 3. Insert into B(id,property1,…,property10) valuses(1,’test’,…,’2009-11-9’) |
好的做法:只取 B 表需要的数据,耗时从 15 秒减少至 2 秒。
select id,property1,…,property10 from A where … |
2. 在 DAO 层 ,Spring+Ibatis 批量插入数据 , 减少获取数据库连接池的次数,提高性能 .
SqlMapClientTemplate sqlMapClientTemplate = getSqlDaoBaseSupport() .getSqlMapTemplate(SubDBRoute.getCRMRoute ()); sqlMapClientTemplate.execute( new SqlMapClientCallback() {
public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException { executor.startBatch(); for ( int i = 0; i < resultList.size(); i++) { executor.insert( "IbatisTestDAO.insertTest" , resultList.get(i)); } executor.executeBatch(); return null ; } }); |
3. 使用 Spring 的事务,保证数据的一致性 .
public boolean atomicInsert () throws RegRuleServiceException { Object object = crmTransactionTemplate .execute ( new TransactionCallback() { public Object doInTransaction(TransactionStatus status) { Boolean ret = Boolean. FALSE ; try { doSomething(); ret = Boolean. TRUE ; } catch (DAOException e) { logger .error( "atomicInsert" , e); status.setRollbackOnly(); } return ret; } }); return (Boolean) object; } |
4. 插入数据时 Spring template 的 update 和 insert 的区别。在项目过程中,开发人员在写代码时,忽视了这两个方法的区别,导致需要自动生成主键的插入不成功,花费了很长时间才找出原因。下次引以为戒。
< insert id = "IbatisTestDAO.insertTest" parameterClass = "TestDO" > < selectKey resultClass = "long" keyProperty = "id" > select SEQ_TEST_ID.nextval as id from dual </ selectKey > insert into test(id,name) values(#id#,#name#) </ insert > |
调用 Spring template 的 update 方法,也可以成功插入一条数据,返回的是被更新的记录数。这个时候 selectKey 的自动生成主键不起作用。
// 调用 Spring template Int updateRows = sqlMapClientTemplate.update(statementName, parameterObject); |
调用 Spring template 的 insert 方法,成功插入一条数据,并且返回新增加记录的主键。
// 调用 Spring template Object back = sqlMapClientTemplate.insert(statementName, parameterObject);
|