Spring ibatis struts review

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:


<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("[email protected]");
        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);
			}
		});
	}

猜你喜欢

转载自jd2bs.iteye.com/blog/1868128
今日推荐