跨db的动态数据源的transaction- 2.动态数据源
来源:互联网 发布:linux禁用网卡 编辑:程序博客网 时间:2024/06/05 01:50
DynamicDataSource 初始化时会从dynamicDataSourceManager里面将所有数据源读入到dynamicDataSource 的TargetDataSources. 从而取代了在springcontext中配置它的targetDataSources。
@Component("dynamicDataSource")public class DynamicDataSource extends AbstractRoutingDataSource implements InitializingBean{@Autowired@Qualifier("dynamicDataSourceManager")IDynamicDataSourceManager dynamicDataSourceManager;@Overrideprotected Object determineCurrentLookupKey() {return DataSourceContextHolder.getDataSourceType();}public void afterPropertiesSet() {if(dynamicDataSourceManager==null){logger.info("property dynamicDataSourceManager is unset.");return ;}Assert.notNull(dynamicDataSourceManager,"Property 'dynamicDataSourceManager' is Null");Map<Object,Object> targetDS=new HashMap<Object,Object>();for(ShardDataSource ds:dynamicDataSourceManager.getAllDataSources()){targetDS.put(ds.getId(),ds);}this.setTargetDataSources(targetDS);this.setDefaultTargetDataSource(dynamicDataSourceManager.getDefaultDataSource());super.afterPropertiesSet();}}
如果仅是使用动态数据源,将DynamicDataSource配置到sqlSessionFactory的datasource 属性中,然后在DAO里面先用DataSourceContextHolder.setDataSourceType()指定数据源即可。
根据http://www.itblog8.cn/java/20130425101.html,在使用transaction是,需要每个数据源一个独立的SqlSessionFactory。然后通过getSqlSession来实现动态切换。
其中TargetSqlSessionFactorys可以在spring context里面配置。此处是从DynamicSqlSessionFactory里面读取。该类负责为每个datasource创建一个新的SqlSessionFactory.
public class DynamicSqlSessionDaoSupport extends JdbcDaoSupport implements InitializingBean{private static Logger logger=(Logger) LoggerFactory.getLogger(DynamicSqlSessionDaoSupport.class);private Map<String,SqlSessionFactory> targetSqlSessionFactorys;private SqlSessionFactory defaultTargetSqlSessionFactory;private SqlSession sqlSession;private boolean externalSqlSession;@Autowired@Qualifier("nsDefaultSqlSessionFactory")private DynamicSqlSessionFactoryBean dynamicFactoryBean;public final void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory){if(!this.externalSqlSession){this.sqlSession=new SqlSessionTemplate(sqlSessionFactory);}}public final void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate){this.sqlSession=sqlSessionTemplate;this.externalSqlSession=true;} /** * Users should use this method to get a SqlSession to call its statement methods * This is SqlSession is managed by spring. Users should not commit/rollback/close it * because it will be automatically done. * Note:Mybatis use SqlSessionFacory as Lock key @cmei * @return Spring managed thread safe SqlSession */ public final SqlSession getSqlSession() {; if(targetSqlSessionFactorys!=null){ String dataSourceID = DataSourceContextHolder.getDataSourceType(); SqlSessionFactory targetSqlSessionFactory=targetSqlSessionFactorys.get(dataSourceID); if(targetSqlSessionFactory==null){ logger.warn("Default sqlSessionFactory is used!"); setSqlSessionFactory(defaultTargetSqlSessionFactory); }else{ setSqlSessionFactory(targetSqlSessionFactory); } }else{ setSqlSessionFactory(defaultTargetSqlSessionFactory); } return this.sqlSession; }@Overrideprotected void checkDaoConfig() throws IllegalArgumentException {Assert.notNull(this.dynamicFactoryBean, "Property 'dynamicFactoryBean' is required");targetSqlSessionFactorys=this.dynamicFactoryBean.getTargetSqlSessionFactorys();this.defaultTargetSqlSessionFactory=this.dynamicFactoryBean.getDefaultTargetSqlSessionFactory();}public void setTargetSqlSessionFactorys(Map<String,SqlSessionFactory> targetSqlSessionFactorys){this.targetSqlSessionFactorys=targetSqlSessionFactorys;}public void setDefaultTargetSqlSessionFactory(SqlSessionFactory defaultTargetSqlSessionFactory){this.defaultTargetSqlSessionFactory=defaultTargetSqlSessionFactory;}public SqlSessionFactory getDefaultTargetSqlSessionFactory(){return this.defaultTargetSqlSessionFactory;}}</pre><p><br />先参考:<a href="http://www.itblog8.cn/java/20130425101.html" target="_blank">http://www.itblog8.cn/java/20130425101.html</a></p><pre class="java" name="code">public class DataSourceContextHolder {private static final ThreadLocal<String> contextHolder=new ThreadLocal<String>();/** * @param dsIndex */public static void setDataSourceType(int dsIndex,DataSourceGroup dsGroup){contextHolder.set(ShardDataSource.getDataSourceId(dsIndex, dsGroup));}public static String getDataSourceType(){return contextHolder.get();}public static void clearDataSourceType(){contextHolder.remove();}}</pre>
为每个datasource创建自己的SqlSessionFactory:
/** * To sync transaction at dynamic data source, creating separate <code>SqlSessionFactory</code> for each data source is necessary. * This class 's will create SqlSessionFactory dynamically and store them by cloning <code>Configure</code> from defaultSqlSessionFactory. * Note that please set <code>DataSourceContextHolder</code> before using transaction. * @author cmei * */public class DynamicSqlSessionFactoryBean extends SqlSessionFactoryBean implements InitializingBean{private static Logger logger=(Logger) LoggerFactory.getLogger(DynamicSqlSessionFactoryBean.class);private Map<String,SqlSessionFactory> targetSqlSessionFactorys;private SqlSessionFactory defaultTargetSqlSessionFactory;private Resource[] mapperLocations;private String typeAliasesPackage;private IDynamicDataSourceManager dynamicDataSourceManager;public void setDynamicDataSourceManager(IDynamicDataSourceManager dynamicDataSourceManager){this.dynamicDataSourceManager=dynamicDataSourceManager;}public void setMapperLocations(Resource[] mapperLocations){this.mapperLocations=mapperLocations;}public Resource[] getMapperLocations( ) { return this.mapperLocations;}public void setTypeAliasesPackage(String typeAliasesPackage){this.typeAliasesPackage=typeAliasesPackage;}public String getTypeAliasesPackage( ) { return this.typeAliasesPackage;}// Be careful to avoid recursion call.public void afterPropertiesSet() throws Exception{super.setMapperLocations(mapperLocations);super.setTypeAliasesPackage(typeAliasesPackage);super.afterPropertiesSet();this.defaultTargetSqlSessionFactory=super.getObject();buildTargetSqlSessionFactorys(); }private void buildTargetSqlSessionFactorys() throws Exception{if(dynamicDataSourceManager==null){logger.info("property 'dynamicDataSourceManager' is unset.");Assert.notNull(defaultTargetSqlSessionFactory,"Property defaultTargetSqlSessionFactory is Null");return ;}targetSqlSessionFactorys=new HashMap<String,SqlSessionFactory>();for(ShardDataSource ds:dynamicDataSourceManager.getAllDataSources()){SqlSessionFactoryBean fb=new SqlSessionFactoryBean();fb.setMapperLocations(this.getMapperLocations());fb.setTypeAliasesPackage(this.getTypeAliasesPackage());fb.setDataSource(ds);targetSqlSessionFactorys.put(ds.getId(),fb.getObject());}this.defaultTargetSqlSessionFactory=targetSqlSessionFactorys.get(dynamicDataSourceManager.getDefaultDataSource().getId());}public void setDefaultTargetSqlSessionFactory(SqlSessionFactory sqlSessionFactory){this.defaultTargetSqlSessionFactory=sqlSessionFactory;}public SqlSessionFactory getDefaultTargetSqlSessionFactory(){return this.defaultTargetSqlSessionFactory;}public Map<String,SqlSessionFactory> getTargetSqlSessionFactorys(){return this.targetSqlSessionFactorys;}}
最后 class MybatisDAO<T> extends DynamicSqlSessionDaoSupport 。
- 跨db的动态数据源的transaction- 2.动态数据源
- 跨db的动态数据源的transaction- 1动态读取数据源取代配置文件中一一配置
- 跨db的动态数据源的transaction-3.如何使用动态数据源in mybatis
- 动态数据源的绑定
- Spring的AbstractRoutingDataSource 实现 数据源DB的动态切换
- 动态设置数据源的方法
- 开发动态的Inventory数据源
- 动态数据源
- 动态数据源
- wxWidgets:ODBC数据源的动态创建(VC2005)
- 动态注册ODBC数据源的通用方法
- datagridview动态指定数据源的问题
- 如何动态修改DATAWINDOW OBJECT的数据源
- 用脚本实现报表的动态数据源
- 报表工具的动态数据源实现
- Spring mvc 动态数据源的配置
- 动态切换数据库数据源的简单示例
- 报表工具的动态数据源实现
- uva 1203 - Argus
- Oracle的XMLTYPE的处理
- tableview分批显示数据
- TableView中图片的延时加载
- P问题、NP问题、NPC问题、NP难问题的概念
- 跨db的动态数据源的transaction- 2.动态数据源
- NVM_INODE_ATTR_GET_SET
- 如何得到form下的所有的input
- CI框架中,删除记录弹出确认对话框
- 浏览器的js引擎大PK
- grep sed awk 实例
- shell中的各种括号
- 使用ServletRequestListener和ServletRequestAttributeListener
- 查看Oracle中表的统计信息