Spring ibatis struts review

本文介绍Spring框架与iBatis的集成应用,包括配置示例、事务处理及分库分表策略。展示了如何利用Spring管理iBatis的SqlMapClient,并通过具体代码实现了账户操作的事务控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring:
1)Ioc
2)AOP
3)BeanFactory, DI
4)DispatcherServlet: handlerMapping,return ModelAndView,viewResolver

Struts:
1)ActionServlet
2)Struts-config.xml: FormBean,ActionMapping
3)Action.execute(),return ActionForward.


ibatis:
[img]http://www.ibm.com/developerworks/cn/java/j-lo-ibatis-principle/image008.gif[/img]

<beans>
<bean id="sqlMapTransactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="sqlMapTransactionTemplate"
class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="sqlMapTransactionManager"/>
</bean>
<!--sql map -->
<bean id="sqlMapClient"
class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation" value="com/mydomain/data/SqlMapConfig.xml"/>
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="dataSource" name="dataSource"
class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@10.1.5.11:1521:XE"/>
<property name="username" value="junshan"/>
<property name="password" value="junshan"/>
<property name="maxActive" value="20"/>
</bean>
<bean id="accountDAO" class="com.mydomain.AccountDAO">
<property name="sqlMapClient" ref="sqlMapClient"/>
<property name="sqlMapTransactionTemplate" ref="sqlMapTransactionTemplate"/>
</bean>
</beans>


public class SimpleTest {
public static void main(String[] args) {
ApplicationContext factory =
new ClassPathXmlApplicationContext("/com/mydomain/data/applicationContext.xml");
final AccountDAO accountDAO = (AccountDAO) factory.getBean("accountDAO");
final Account account = new Account();
account.setId(1);
account.setFirstName("tao");
account.setLastName("bao");
account.setEmailAddress("junshan@taobao.com");
account.setDate(new Date());
try {
accountDAO.getSqlMapTransactionTemplate().execute(new TransactionCallback(){
public Object doInTransaction(TransactionStatus status){
try{
accountDAO.deleteAccount(account.getId());
accountDAO.insertAccount(account);
//account.setLastName("bobo");
//accountDAO.updateAccount(account);
Account result = accountDAO.selectAccount(account);
System.out.println(result);
return null;
} catch (Exception e) {
status.setRollbackOnly();
return false;
}
}
});
//accountDAO.getSqlMapClient().commitTransaction();
} catch (Exception e) {
e.printStackTrace();
}
}
}


关于spring+ibatis sharding方案的实现:
1)根据ID和路由规则确定TargetDataSource
因为一般DaoImpl会下面这样实现,因此可以写一个类ShardSqlMapClientDaoSupport继承SqlMapClientDaoSupport,然后根据ID和路由规则确定TargetDataSource,调用setDataSource(TargetDataSource)方法。这样数据源的路由问题(就是分库)就解决了。

2)接下来看怎么实现sql中的分表。
a 首先根据id和路由规则确定表名table
b 因为如下面代码所示SqlMapClientTemplate的insert和queryForObject等方法都是通过callback来做的,这里只传一个statementName过去,具体的跟statement替换变量相关的代码都在ibatis包里,所以这里替换表名的工作还不是很好做。
c 那怎么办呢?通过搜索看到ibatis从3.0开始提供了Plugin接口,可以对执行的sql进行拦截,这样就可以把表名根据规则替换上去了。但是由于我们使用的是ibatis早期版本,升级的代价比较大,因此最后只在某些新项目使用了这个分表逻辑。
关于Plugin怎么使用看我的收藏夹最新文章。

3)如果查询条件中不含id,比如根据name查或动态条件查,特别是可能还需要分页,排序,group by,count等会比较麻烦,这种情况只能把sql发送到各个dataSource然后在应用端进行Merge。 没办法,Sharding是有代价的。



package com.lanp.dao;

import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;

import com.lanp.beans.Student;

public class StudentDaoImpl extends SqlMapClientDaoSupport implements StudentDao {

@Override
public Student getStudent(String name) {
try{
return (Student)getSqlMapClientTemplate().queryForObject("queryStudentById", name);
} catch(Exception e) {
e.printStackTrace();
}
return null;
}

}




public Object queryForObject(final String statementName, final Object parameterObject)
throws DataAccessException {

return execute(new SqlMapClientCallback() {
public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
return executor.queryForObject(statementName, parameterObject);
}
});
}


public Object insert(final String statementName, final Object parameterObject)
throws DataAccessException {

return execute(new SqlMapClientCallback() {
public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
return executor.insert(statementName, parameterObject);
}
});
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值