`
ping12132200
  • 浏览: 829 次
  • 性别: Icon_minigender_2
社区版块
存档分类
最新评论

spring+mybatis多数据源配置

 
阅读更多

应开发需求需要,根据项目业务,不同业务下的数据存入不同的数据库中,且须读写分离。目前常用的有两种方式:

    第一种:定义多个个数据库连接,分别是AReadDataSource,AWriteDataSource,BReadDataSource,BWriteDataSource,CReadDataSource, CWriteDataSource来实现;

   第二种:动态数据源切换,就是在程序运行时,把数据源动态织入到程序中,从而选择读取对应的数据库。主要使用的技术是:annotation,Spring AOP ,反射。具体实现方式如下:

 

    先定义一个annotation的注解类:

 

@Retention(RetentionPolicy.RUNTIME)  
@Target(ElementType.METHOD)  
@Documented 
public @interface DataSourceNote {
	String dbSource() default ""; 
}

 

 

    添加一个dataSource.xml,文件内容如下:

    

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd  
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context-4.0.xsd">
     
    <!-- testA读库写库  start   -->                   
    <bean id="testAReadDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    	<!-- 读库个性化配置   -->
        <property name="driverClassName" value="${jdbc.testA_read.driver}"/>
        <property name="url" value="${jdbc.testA_read.url}"/>
        <property name="username" value="${jdbc.testA_read.username}"/>
        <property name="password" value="${jdbc.testA_read.password}"/>
    </bean>
    <bean id="testAWriteDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    	<!-- 写库个性化配置   -->
        <property name="driverClassName" value="${jdbc.testA_write.driver}"/>
        <property name="url" value="${jdbc.testA_write.url}"/>
        <property name="username" value="${jdbc.testA_write.username}"/>
        <property name="password" value="${jdbc.testA_write.password}"/>
    </bean>
     <!-- testA读库写库   end   -->  
    
    <!-- testB读库写库     start -->                   
    <bean id="testBReadDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    	<!-- 读库个性化配置   -->
        <property name="driverClassName" value="${jdbc.testB_read.driver}"/>
        <property name="url" value="${jdbc.testB_read.url}"/>
        <property name="username" value="${jdbc.testB_read.username}"/>
        <property name="password" value="${jdbc.testB_read.password}"/>
    </bean>
    <bean id="testBWriteDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    	<!-- 写库个性化配置   -->
        <property name="driverClassName" value="${jdbc.testB_write.driver}"/>
        <property name="url" value="${jdbc.testB_write.url}"/>
        <property name="username" value="${jdbc.testB_write.username}"/>
        <property name="password" value="${jdbc.testB_write.password}"/>
    </bean>
    <!-- testB读库写库     end --> 
    
    
    <!-- testC读库 写库 	start	-->                   
    <bean id="testCReadDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    	<!-- 读库个性化配置   -->
        <property name="driverClassName" value="${jdbc.testC_read.driver}"/>
        <property name="url" value="${jdbc.testC_read.url}"/>
        <property name="username" value="${jdbc.testC_read.username}"/>
        <property name="password" value="${jdbc.testC_read.password}"/>
    </bean>
    <bean id="testCWriteDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    	<!-- 写库个性化配置   -->
        <property name="driverClassName" value="${jdbc.testC_write.driver}"/>
        <property name="url" value="${jdbc.testC_write.url}"/>
        <property name="username" value="${jdbc.testC_write.username}"/>
        <property name="password" value="${jdbc.testC_write.password}"/>
    </bean>
    <!-- testC读库 写库 	end	--> 
    
     
	<bean id="dataSource" class="com.test.dao.aspect.ChooseDataSource" lazy-init="true">
		<description>数据源</description>
		<property name="targetDataSources">
			<map key-type="java.lang.String" value-type="javax.sql.DataSource">
				<!-- write -->
				<entry key="testAWrite" value-ref="testAWriteDataSource" />
				<entry key="testBWrite" value-ref="testBWriteDataSource" />
				<entry key="testCWrite" value-ref="testCWriteDataSource" />
				<!-- read -->
				<entry key="testARead" value-ref="testAReadDataSource" />
				<entry key="testBRead" value-ref="testBReadDataSource" />
				<entry key="testCRead" value-ref="testCReadDataSource" />
			</map>
		</property>
		<property name="methodType">
			<map key-type="java.lang.String">
				<!-- read -->
				<entry key="testARead" value=",get,select,count,list,query," />
				<entry key="testBRead" value=",get,select,count,list,query," />
				<entry key="testCRead" value=",get,select,count,list,query," />
				<!-- write -->
				<entry key="testAWrite" value=",add,insert,create,update,delete,remove," />
				<entry key="testBWrite" value=",add,insert,create,update,delete,remove," />
				<entry key="testCWrite" value=",add,insert,create,update,delete,remove," />
			</map>
		</property>
	</bean>
	<!-- 切面   -->
	<bean class="com.test.dao.aspect.DataSourceAspect" />
	<!-- jdbc模板  -->
	<bean class="org.springframework.jdbc.core.JdbcTemplate">
		<constructor-arg ref="dataSource" />
	</bean>
</beans>

 

 

    然后将dataSource.xml配置到spring-config.xml里面去,具体参考如下文件:    

 

<import resource="classpath*:spring/dataSource.xml"/>

   

 

    mybatis.xml配置如下:

     

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:cache="http://www.springframework.org/schema/cache"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd  
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context-4.0.xsd
                        http://www.springframework.org/schema/tx
                        http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
                        http://www.springframework.org/schema/cache
                        http://www.springframework.org/schema/cache/spring-cache-4.0.xsd">
     <!-- 开启注解配置 -->
	<context:annotation-config />
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="configLocation" value="classpath:mybatis/mybatis-config.xml" />
		<!-- 自动扫描mapping.xml文件 -->
		<property name="mapperLocations" value="classpath:sqlmaps/**/*.xml" />
	</bean>
	<!-- 事务管理   -->
    <bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
</beans>

 

 

    现在再来看看,dataSource.xml里面相关的两个类的代码,第一个DataSourceAspect,用于动态切换数据库源:

 

@Aspect
@EnableAspectJAutoProxy(proxyTargetClass = true)
@Log4j2
public class DataSourceAspect {

	@Pointcut("execution(* com.test.dao.*..*Impl.*(..))")
	public void aspect() {
	}

	/**
	 * 配置前置通知,使用在方法aspect()上注册的切入点
	 */
	@Before("aspect()")
	public void before(JoinPoint point) {
		String method = point.getSignature().getName();
		Log4j2Util.printLog4j2(log,this, method, Level.INFO, "(" + StringUtils.join(point.getArgs(), ",") + ")");
		//获取到对象的类
		Object obj = point.getTarget();
		Method methods[] = obj.getClass().getMethods();
		for (int  i = 0;  i< methods.length; i++) {
			 if(method.equals(methods[i].getName())){
				 DataSourceNote note = methods[i].getAnnotation(DataSourceNote.class);
				 String dbSource = note.dbSource();
				 if(StringUtils.isNotEmpty(dbSource)){
					 Log4j2Util.printLog4j2(log,this, "before", Level.DEBUG, "---------数据库类型:"+dbSource);
					 HandleDataSource.putDataSource(dbSource);
				 }else{
					 Log4j2Util.printLog4j2(log,this, "before", Level.ERROR, "---------数据库类型:"+dbSource);
				 }
			 }
		}
	}

	@After("aspect()")
	public void after(JoinPoint point) {
		HandleDataSource.clear();
	}
}

   

   下面再来看看ChooseDataSource类的处理,获取对应的dataSource里面的数据源:

 

public class ChooseDataSource extends AbstractRoutingDataSource {
	public static Map<String, List<String>> METHODTYPE = new HashMap<String, List<String>>();

	// 获取数据源名称
	protected Object determineCurrentLookupKey() {
		return HandleDataSource.getDataSource();
	}

	// 设置方法名前缀对应的数据源
	public void setMethodType(Map<String, String> map) {
		for (String key : map.keySet()) {
			List<String> v = new ArrayList<String>();
			String[] types = map.get(key).split(",");
			for (String type : types) {
				if (StringUtils.isNotBlank(type)) {
					v.add(type);
				}
			}
			METHODTYPE.put(key, v);
		}
	}
}

 

 代码实际使用示例如下:

public class TestDataDaoImpl extends BaseDao implements TestDataDao{
	
	private static final String NAME_SPACE = "com.test.dao.TestDataDao.";

	@Override
	@DataSourceNote(dbSource = "testAWrite")
	public boolean addTestAUserMsg(List<UserDO> list)
			throws DaoException {
		
		Integer count = this.insert(NAME_SPACE + "addTestAUserMsg", list);
		
		return (count == null || count == 0) ? false : true;
	}

	@Override
	@DataSourceNote(dbSource = "testBWrite")
	public boolean addTestBUserMsgLog(List<UserMsgLogDO> list)
			throws DaoException {
		
		Integer count = this.insert(NAME_SPACE + "addTestBUserMsgLog", list);
		
		return (count == null || count == 0) ? false : true;
	}

	@Override
	@DataSourceNote(dbSource = "testCRead")
	public UserDetail queryTestCUserDetail(Map<String, String> param)
			throws DaoException {
		
		UserDetail temp = (UserDetail ) this.queryForObject(NAME_SPACE + "queryTestCUserDetail", param);
		return temp;
	}

}

 

 按步骤依顺配置下来即可,不是很明白的地方可以去看看org.apache.commons.dbcp.BasicDataSource里的createConnectionFactory方法。及其他相关方法

 

  

 

 

 

 

 

 

分享到:
评论

相关推荐

    Spring+Mybatis 多数据源配置

    当我们面临多数据源的配置需求时,即在一个应用程序中需要同时操作多个数据库,Spring和Mybatis的集成就显得尤为重要。这篇博客“Spring+Mybatis 多数据源配置”将深入探讨如何在项目中实现这一功能。 首先,我们...

    Spring+MyBatis多数据源配置实现

    总之,Spring+MyBatis多数据源配置是大型项目中常见的需求,它通过`AbstractRoutingDataSource`实现了动态数据源选择,结合MyBatis的Mapper接口和注解,可以方便地在多个数据库之间切换,从而满足复杂的数据库访问...

    SSM(Spring+SpringMVC+MyBatis)多数据源配置框架

    在多数据源配置中,Spring能够帮助管理不同的数据源,通过配置bean来切换和控制数据源的使用。 **SpringMVC** 是Spring框架的一部分,专为Web开发设计。它简化了模型-视图-控制器(Model-View-Controller,MVC)的...

    Springboot+Mybatis+Druid多数据源配置

    在多数据源场景下,我们可以通过Spring Boot的@ConfigurationProperties特性来配置不同的数据源。每个数据源都需要定义一套包括URL、用户名、密码和驱动类名等属性。例如: ```java @Configuration @...

    Springboot+mybatis+druid多数据源配置(oracle+mybatis)

    总结,Spring Boot结合Mybatis和Druid实现多数据源配置的过程包括:配置数据源、配置Mybatis、创建数据源切换器、以及针对不同数据库的测试。这一过程涉及了Spring Boot的自动配置、依赖注入、配置属性绑定等多个...

    springmvc + spring + mybatis + maven整合配置文件

    然后配置Spring的applicationContext.xml,包括Bean定义、AOP配置、数据源、事务管理器等。接着配置Spring MVC的servlet-context.xml,设置DispatcherServlet、视图解析器、拦截器等。最后,配置MyBatis的mybatis-...

    SpringMvc+Spring+Mybatis+Maven+注解方式=整合

    - MyBatis的配置文件(mybatis-config.xml)中,设置数据源和SqlSessionFactory,以便MyBatis与数据库交互。 通过以上步骤,我们可以构建一个松耦合、可测试的系统,每个组件都发挥着它应有的作用,而注解方式的...

    《spring+mybatis 企业应用实战》源码、类库全资料

    1. **配置文件**:包括Spring的bean配置文件(如`applicationContext.xml`)和MyBatis的配置文件(如`mybatis-config.xml`),它们定义了数据源、事务管理器、SqlSessionFactory以及Mapper接口的扫描路径。...

    struts2+spring+mybatis框架

    3. **配置MyBatis**:编写MyBatis的配置文件,包括数据源、SqlSessionFactory,并为每个Mapper接口定义XML映射文件。 4. **整合Spring和Struts2**:使用Spring的Struts2插件,使Spring管理的Bean可以直接在Struts2 ...

    Spring+SpringMVC+Mybatis多数据源

    总结来说,"Spring+SpringMVC+Mybatis多数据源"的整合涉及了Spring的数据源管理、SpringMVC的请求路由、Mybatis的数据源配置以及事务管理。具体实现时,可以根据项目需求选择合适的方式进行数据源切换,以达到优化...

    spring+hibernate和spring+myBatis实现连接多个数据库,同时操作的项目

    在多数据源环境中,MyBatis的配置文件需要包含多个数据源的信息,每次操作数据库时,可以通过SqlSessionFactoryBuilder创建指定数据源的SqlSessionFactory,然后通过SqlSession来执行SQL。 项目的...

    springboot+druid+mybatis多数据源动态切换案例

    5. **MyBatis配置**:在多数据源环境下,MyBatis的配置需要针对每个数据源分别设置SqlSessionFactory,并在Mapper接口上通过@MapperScan注解指定对应的SqlSessionFactory。 6. **事务管理**:在多数据源情况下,...

    SpringBoot+gradle+mybatis多数据源动态配置

    本项目结合了SpringBoot、Gradle和MyBatis,旨在实现多数据源的动态配置,这对于处理多个数据库或者分库分表的场景尤其有用。以下是对这个项目的详细解析: **SpringBoot** SpringBoot是由Pivotal团队提供的全新...

    springboot+mybatis双数据源配置及事务处理

    Spring Boot通过`@EnableAutoConfiguration`注解自动配置了大量常见服务,包括数据源和MyBatis的配置。然而,当涉及到多个数据源时,我们需要手动进行一些配置。 1. **配置双数据源** - 首先,为每个数据源创建一...

    spring+spring mvc+mybatis框架整合实现超市货物管理系统

    对于MyBatis,我们需要创建`mybatis-config.xml`配置文件,配置数据源、事务管理器以及映射文件的位置。 数据库方面,本系统使用了MySQL,通过MyBatis的SqlSessionFactory和SqlSession对象,我们可以执行SQL语句。`...

    struts+spring+mybatis源代码例子

    标题中的"struts+spring+mybatis源代码例子"意味着这是一个实际的项目示例,包含了这三个框架的集成使用,可以帮助开发者理解和学习如何在实际项目中整合这些技术。通过分析和研究这个源代码,开发者可以深入理解...

    spring+springmvc+mybatis

    在实际项目中,开发者通常会创建一个配置文件(如:`springmvc_mybatis1208`可能包含的`spring-config.xml`),在其中配置Spring和MyBatis的相关设置,包括数据源、事务管理器、SqlSessionFactory等。同时,还需要...

    SpringMVC+Spring+MyBatis jar包和配置文件

    4. 配置MyBatis:编写mybatis-config.xml,包含数据源、事务管理器、环境等信息。 5. 配置Mapper:创建Mapper接口和对应的XML文件,定义SQL语句。 6. 配置Spring与MyBatis的集成:使用MyBatis-Spring的...

    Spring+Mybatis+Mysql项目框架

    - **src/main/resources**:存放配置文件,如Spring的bean配置、Mybatis的Mapper XML文件、数据库连接配置等。 - **webapp**:Web应用目录,其中`WEB-INF`下存放web.xml,定义了Servlet和Filter等Web组件;`jsp`...

Global site tag (gtag.js) - Google Analytics