spring-boot-dyna-datasource(spring-boot动态数据源)

spring-boot 动态数据源

本示例工程使用maven来构建


pom配置文件


	4.0.0
	com.linewell
	spring-boot-multi-datasource
	0.0.1-SNAPSHOT

	
		10.2.0.5.0
		1.2.24
		1.0.9
		UTF-8
		UTF-8
		1.8
		1.8
		1.8
	

	
		
			
				org.springframework.boot
				spring-boot-dependencies
				1.5.2.RELEASE
				import
				pom
			
		
	



	
		
		
			org.springframework.boot
			spring-boot-starter-web
		
		
			org.springframework.boot
			spring-boot-starter-aop
		
		
		
		
			org.springframework.boot
			spring-boot-starter-test
			test
		

		
		
		
			org.springframework.boot
			spring-boot-starter-jdbc
		
		
			mysql
			mysql-connector-java
		
		
		
			com.oracle
			ojdbc14
			${oracle.version}
		
		
			com.alibaba
			druid
			${druid.version}
		

		
			org.mybatis.spring.boot
			mybatis-spring-boot-starter
			1.3.0
		

		
		
			com.github.pagehelper
			pagehelper
			4.1.0
			
				
					org.mybatis
					mybatis-parent
				
			
		

		
			com.github.miemiedev
			mybatis-paginator
			1.2.17
			
				
					org.mybatis
					mybatis-parent
				
			
		
		
		
			com.alibaba
			fastjson
			${fastjson.version}
		

		

	
	
		
		
			
			
				org.springframework.boot
				spring-boot-maven-plugin
				1.5.2.RELEASE
				
		        	cn.janvi.ds.App
		        	ZIP
		      	
                
                    
                        
                            repackage
                        
                    
                
			
		
	

spring-boot的配置文件(src/main/resources/application.yml)


spring:
  datasource:
    db1:
      url: jdbc:mysql://127.0.0.1/mybatis?characterEncoding=utf-8
      username: root
      password: root
      driver-class-name: com.mysql.jdbc.Driver
    db2:
      url: jdbc:oracle:thin:@127.0.0.1:1521:orcl
      username: scott
      password: tiger
      driver-class-name: oracle.jdbc.driver.OracleDriver

mybatis配置文件(src/main/resources/mybatis/SqlMapConfig1.xml),这个配置文件只用于数据源1的分页测试





	

	
		
			
			
		
	



spring-boot的启动类(cn.janvi.ds.App)


package cn.janvi.ds;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@EnableTransactionManagement //开启事务管理;如果mybatis中service实现类中加入事务注解,需要此处添加该注解
@SpringBootApplication
public class App {
	public static void main(String[] args) {
		SpringApplication.run(App.class, args);
	}
}

数据源1的属性映射类(cn.janvi.ds.config.Db1Properties)


package cn.janvi.ds.config;  
  
import java.io.Serializable;  
  
import org.springframework.boot.context.properties.ConfigurationProperties;  
import org.springframework.stereotype.Component;  
  
@Component  
@ConfigurationProperties(prefix = "spring.datasource.db1")  
public class Db1Properties implements Serializable{  
  
    private static final long serialVersionUID = 283848210567696024L;  
  
    public String url;  
  
    public String username;  
  
    public String password;  
  
    public String driverClassName;  
  
    public Integer maxActive;  
  
    public Integer initialSize;  
  
    public Integer minIdle;  
  
    public Integer maxWait;  
  
    public Integer maxPoolPreparedStatementPerConnectionSize;  
  
    public Integer timeBetweenEvictionRunsMillis;  
  
    public Integer minEvictableIdleTimeMillis;  
  
    public Boolean poolPreparedStatements;  
  
    // 省略Setter 和 Getter 方法......  
      
}  

数据源配置

package cn.janvi.ds.config;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;

/**
 * springboot集成mybatis的基本入口 1)创建数据源(如果采用的是默认的tomcat-jdbc数据源,则不需要)
 * 2)创建SqlSessionFactory 3)配置事务管理器,除非需要使用事务,否则不用配置
 * 
 * 通过读取application.properties文件生成两个数据源(myTestDbDataSource、myTestDb2DataSource)
使用以上生成的两个数据源构造动态数据源dataSource
@Primary:指定在同一个接口有多个实现类可以注入的时候,默认选择哪一个,而不是让@Autowire注解报错(一般用于多数据源的情况下)
@Qualifier:指定名称的注入,当一个接口有多个实现类的时候使用(在本例中,有两个DataSource类型的实例,需要指定名称注入)
@Bean:生成的bean实例的名称是方法名(例如上边的@Qualifier注解中使用的名称是前边两个数据源的方法名,而这两个数据源也是使用@Bean注解进行注入的)
通过动态数据源构造SqlSessionFactory和事务管理器(如果不需要事务,后者可以去掉)
 * 
 * 
 */
@Configuration
@MapperScan(basePackages = "cn.janvi.ds.mapper")
public class MyBatisConfig {

  

    @Autowired
    private Db1Properties db1Properties;
	
    /**
     * 数据源1,使用阿里巴巴的数据源com.alibaba.druid.pool.DruidDataSource
     * @return
     */
    @Bean
    public DataSource ds1() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(db1Properties.url);
        dataSource.setUsername(db1Properties.username);
        dataSource.setPassword(db1Properties.password);
        dataSource.setDriverClassName(db1Properties.driverClassName);
        return dataSource;
    }

    /**
     * 数据源2,使用默认的数据源org.apache.tomcat.jdbc.pool.DataSource
     * @return
     */
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.db2") // application.yml中对应属性的前缀
    public DataSource ds2() {
        return DataSourceBuilder.create().build();
    }

    /**
     * @Primary 该注解表示在同一个接口有多个实现类可以注入的时候,默认选择哪一个,而不是让@autowire注解报错
     * @Qualifier 根据名称进行注入,通常是在具有相同的多个类型的实例的一个注入(例如有多个DataSource类型的实例)
     */
    @Bean
    @Primary
    public DynamicDataSource dataSource(@Qualifier("ds1") DataSource ds1,
    		@Qualifier("ds2") DataSource ds2) {
        Map targetDataSources = new HashMap<>();
        targetDataSources.put("ds1", ds1);
        targetDataSources.put("ds2", ds2);

        DynamicDataSource dataSource = new DynamicDataSource();
        dataSource.setTargetDataSources(targetDataSources);	// 该方法是AbstractRoutingDataSource的方法
        dataSource.setDefaultTargetDataSource(ds1);		// 默认的datasource设置为ds1

        return dataSource;
    }

   /**
    * 根据数据源创建SqlSessionFactory
    * @param ds1
    * @param ds2
    * @return
    * @throws Exception
    */
    @Bean
    public SqlSessionFactory sqlSessionFactory(@Qualifier("ds1") DataSource ds1,
            @Qualifier("ds2") DataSource ds2) throws Exception{
		SqlSessionFactoryBean fb = new SqlSessionFactoryBean();
		fb.setDataSource(this.dataSource(ds1, ds2));
	// 下边两句仅仅用于*.xml文件,如果整个持久层操作不需要使用到xml文件的话(只用注解就可以搞定),则不加
        //fb.setTypeAliasesPackage(env.getProperty("mybatis.typeAliasesPackage"));// 指定基包
        //fb.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(env.getProperty("mybatis.mapperLocations")));
	fb.setConfigLocation(new ClassPathResource("mybatis/SqlMapConfig1.xml"));	// 引入mybatis的配置文件,分页插件
	return fb.getObject();
    }
    
    /**
     * 配置事务管理器
     */
    @Bean
    public DataSourceTransactionManager transactionManager(DynamicDataSource dataSource) throws Exception {
        return new DataSourceTransactionManager(dataSource);
    }

}


线程本地化用于保存当前线程使用的数据源名

package cn.janvi.ds.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 
 * 定义一个ContextHolder, 用于保存当前线程使用的数据源名
 * Company:www.linewell.com
 * @author panjianwei
 * @date 2017年8月29日上午7:12:12
 */
public class DataSourceContextHolder {
	public static final Logger log = LoggerFactory.getLogger(DataSourceContextHolder.class);

	/**
	 * 默认数据源
	 */
	public static final String DEFAULT_DS = "ds1";

	private static final ThreadLocal contextHolder = new ThreadLocal<>();

	// 设置数据源名
	public static void setDB(String dbType) {
		log.debug("切换到{}数据源", dbType);
		contextHolder.set(dbType);
	}

	// 获取数据源名
	public static String getDB() {
		return (contextHolder.get());
	}

	// 清除数据源名
	public static void clearDB() {
		contextHolder.remove();
	}
}

动态数据源

package cn.janvi.ds.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

/**
 * 自定义一个javax.sql.DataSource接口的实现,这里只需要继承Spring为我们预先实现好的父类AbstractRoutingDataSource即可
 * Company:www.linewell.com
 * @author panjianwei
 * @date 2017年8月29日上午7:13:27
 */
public class DynamicDataSource extends AbstractRoutingDataSource {
	private static final Logger log = LoggerFactory.getLogger(DynamicDataSource.class);

	@Override
	protected Object determineCurrentLookupKey() {
		log.debug("数据源为{}", DataSourceContextHolder.getDB());

		return DataSourceContextHolder.getDB();
	}

}

自定义注解用于切换数据源(cn.janvi.ds.config.Ds)

package cn.janvi.ds.config;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 
 * 自定义注释@DS用于在编码时指定方法使用哪个数据源
 * Company:www.linewell.com
 * @author panjianwei
 * @date 2017年8月29日上午7:20:04
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD })
public @interface Ds {
	String value() default "ds1";
}

使用AOP进行拦截切换数据源(cn.janvi.ds.config.DynamicDataSourceAspect)

package cn.janvi.ds.config;

import java.lang.reflect.Method;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

/**
 * 
 * 编写AOP切面,实现切换逻辑:
 * Company:www.linewell.com
 * @author panjianwei
 * @date 2017年8月29日上午7:24:09
 */
@Aspect
@Component
public class DynamicDataSourceAspect {

	@SuppressWarnings("rawtypes")
	@Before("@annotation(Ds)")
	public void beforeSwitchDS(JoinPoint point) {

		// 获得当前访问的class
		Class className = point.getTarget().getClass();

		// 获得访问的方法名
		String methodName = point.getSignature().getName();
		
		// 得到方法的参数的类型
		Class[] argClass = ((MethodSignature) point.getSignature()).getParameterTypes();
		
		// 设置默认数据源
		String dataSource = DataSourceContextHolder.DEFAULT_DS;
		try {
			// 得到访问的方法对象
			Method method = className.getMethod(methodName, argClass);

			// 判断是否存在@DS注解
			if (method.isAnnotationPresent(Ds.class)) {
				Ds annotation = method.getAnnotation(Ds.class);
				// 取出注解中的数据源名
				dataSource = annotation.value();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		// 切换数据源
		DataSourceContextHolder.setDB(dataSource);

	}

	@After("@annotation(Ds)")
	public void afterSwitchDS(JoinPoint point) {

		DataSourceContextHolder.clearDB();
	}
}

Mybatis 的那一套开发结构 Bean、Mapper、Service

Bean(使用mybatis的逆向工程 )

package cn.janvi.ds.bean;

import java.math.BigDecimal;
import java.util.Date;

public class Emp {
    private Short empno;

    private String ename;

    private String job;

    private Short mgr;

    private Date hiredate;

    private BigDecimal sal;

    private BigDecimal comm;

    private Short deptno;

    // 省略... SETTER AND GETTER
}


package cn.janvi.ds.bean;

import java.util.Date;

public class Items {
    private Integer id;

    private String name;

    private Float price;

    private String pic;

    private Date createtime;

    private String detail;
   // 省略... SETTER AND GETTER
}
 
   
 
  

Mapper(使用mybatis的逆向工程生成)

package cn.janvi.ds.mapper;

import java.util.List;

import org.apache.ibatis.annotations.Param;

import cn.janvi.ds.bean.Emp;
import cn.janvi.ds.bean.EmpExample;

public interface EmpMapper {
    int countByExample(EmpExample example);

    int deleteByExample(EmpExample example);

    int deleteByPrimaryKey(Short empno);

    int insert(Emp record);

    int insertSelective(Emp record);

    List selectByExample(EmpExample example);

    Emp selectByPrimaryKey(Short empno);

    int updateByExampleSelective(@Param("record") Emp record, @Param("example") EmpExample example);

    int updateByExample(@Param("record") Emp record, @Param("example") EmpExample example);

    int updateByPrimaryKeySelective(Emp record);

    int updateByPrimaryKey(Emp record);
}
package cn.janvi.ds.mapper;

import java.util.List;

import org.apache.ibatis.annotations.Param;

import cn.janvi.ds.bean.Items;
import cn.janvi.ds.bean.ItemsExample;

public interface ItemsMapper {
    int countByExample(ItemsExample example);

    int deleteByExample(ItemsExample example);

    int deleteByPrimaryKey(Integer id);

    int insert(Items record);

    int insertSelective(Items record);

    List selectByExampleWithBLOBs(ItemsExample example);

    List selectByExample(ItemsExample example);

    Items selectByPrimaryKey(Integer id);

    int updateByExampleSelective(@Param("record") Items record, @Param("example") ItemsExample example);

    int updateByExampleWithBLOBs(@Param("record") Items record, @Param("example") ItemsExample example);

    int updateByExample(@Param("record") Items record, @Param("example") ItemsExample example);

    int updateByPrimaryKeySelective(Items record);

    int updateByPrimaryKeyWithBLOBs(Items record);

    int updateByPrimaryKey(Items record);
}

Mapper对应的.xml文件

EmpMapper.xml




  
    
    
    
    
    
    
    
    
  
  
    
      
        
          
            
              
                
                  and ${criterion.condition}
                
                
                  and ${criterion.condition} #{criterion.value}
                
                
                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
                
                
                  and ${criterion.condition}
                  
                    #{listItem}
                  
                
              
            
          
        
      
    
  
  
    
      
        
          
            
              
                
                  and ${criterion.condition}
                
                
                  and ${criterion.condition} #{criterion.value}
                
                
                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
                
                
                  and ${criterion.condition}
                  
                    #{listItem}
                  
                
              
            
          
        
      
    
  
  
    EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO
  
  
  
  
    delete from EMP
    where EMPNO = #{empno,jdbcType=DECIMAL}
  
  
    delete from EMP
    
      
    
  
  
    insert into EMP (EMPNO, ENAME, JOB, 
      MGR, HIREDATE, SAL, COMM, 
      DEPTNO)
    values (#{empno,jdbcType=DECIMAL}, #{ename,jdbcType=VARCHAR}, #{job,jdbcType=VARCHAR}, 
      #{mgr,jdbcType=DECIMAL}, #{hiredate,jdbcType=DATE}, #{sal,jdbcType=DECIMAL}, #{comm,jdbcType=DECIMAL}, 
      #{deptno,jdbcType=DECIMAL})
  
  
    insert into EMP
    
      
        EMPNO,
      
      
        ENAME,
      
      
        JOB,
      
      
        MGR,
      
      
        HIREDATE,
      
      
        SAL,
      
      
        COMM,
      
      
        DEPTNO,
      
    
    
      
        #{empno,jdbcType=DECIMAL},
      
      
        #{ename,jdbcType=VARCHAR},
      
      
        #{job,jdbcType=VARCHAR},
      
      
        #{mgr,jdbcType=DECIMAL},
      
      
        #{hiredate,jdbcType=DATE},
      
      
        #{sal,jdbcType=DECIMAL},
      
      
        #{comm,jdbcType=DECIMAL},
      
      
        #{deptno,jdbcType=DECIMAL},
      
    
  
  
  
    update EMP
    
      
        EMPNO = #{record.empno,jdbcType=DECIMAL},
      
      
        ENAME = #{record.ename,jdbcType=VARCHAR},
      
      
        JOB = #{record.job,jdbcType=VARCHAR},
      
      
        MGR = #{record.mgr,jdbcType=DECIMAL},
      
      
        HIREDATE = #{record.hiredate,jdbcType=DATE},
      
      
        SAL = #{record.sal,jdbcType=DECIMAL},
      
      
        COMM = #{record.comm,jdbcType=DECIMAL},
      
      
        DEPTNO = #{record.deptno,jdbcType=DECIMAL},
      
    
    
      
    
  
  
    update EMP
    set EMPNO = #{record.empno,jdbcType=DECIMAL},
      ENAME = #{record.ename,jdbcType=VARCHAR},
      JOB = #{record.job,jdbcType=VARCHAR},
      MGR = #{record.mgr,jdbcType=DECIMAL},
      HIREDATE = #{record.hiredate,jdbcType=DATE},
      SAL = #{record.sal,jdbcType=DECIMAL},
      COMM = #{record.comm,jdbcType=DECIMAL},
      DEPTNO = #{record.deptno,jdbcType=DECIMAL}
    
      
    
  
  
    update EMP
    
      
        ENAME = #{ename,jdbcType=VARCHAR},
      
      
        JOB = #{job,jdbcType=VARCHAR},
      
      
        MGR = #{mgr,jdbcType=DECIMAL},
      
      
        HIREDATE = #{hiredate,jdbcType=DATE},
      
      
        SAL = #{sal,jdbcType=DECIMAL},
      
      
        COMM = #{comm,jdbcType=DECIMAL},
      
      
        DEPTNO = #{deptno,jdbcType=DECIMAL},
      
    
    where EMPNO = #{empno,jdbcType=DECIMAL}
  
  
    update EMP
    set ENAME = #{ename,jdbcType=VARCHAR},
      JOB = #{job,jdbcType=VARCHAR},
      MGR = #{mgr,jdbcType=DECIMAL},
      HIREDATE = #{hiredate,jdbcType=DATE},
      SAL = #{sal,jdbcType=DECIMAL},
      COMM = #{comm,jdbcType=DECIMAL},
      DEPTNO = #{deptno,jdbcType=DECIMAL}
    where EMPNO = #{empno,jdbcType=DECIMAL}
  

ItemsMapper.xml




  
    
    
    
    
    
  
  
    
  
  
    
      
        
          
            
              
                
                  and ${criterion.condition}
                
                
                  and ${criterion.condition} #{criterion.value}
                
                
                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
                
                
                  and ${criterion.condition}
                  
                    #{listItem}
                  
                
              
            
          
        
      
    
  
  
    
      
        
          
            
              
                
                  and ${criterion.condition}
                
                
                  and ${criterion.condition} #{criterion.value}
                
                
                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
                
                
                  and ${criterion.condition}
                  
                    #{listItem}
                  
                
              
            
          
        
      
    
  
  
    id, name, price, pic, createtime
  
  
    detail
  
  
  
  
  
    delete from items
    where id = #{id,jdbcType=INTEGER}
  
  
    delete from items
    
      
    
  
  
    insert into items (id, name, price, 
      pic, createtime, detail
      )
    values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR}, #{price,jdbcType=REAL}, 
      #{pic,jdbcType=VARCHAR}, #{createtime,jdbcType=TIMESTAMP}, #{detail,jdbcType=LONGVARCHAR}
      )
  
  
    insert into items
    
      
        id,
      
      
        name,
      
      
        price,
      
      
        pic,
      
      
        createtime,
      
      
        detail,
      
    
    
      
        #{id,jdbcType=INTEGER},
      
      
        #{name,jdbcType=VARCHAR},
      
      
        #{price,jdbcType=REAL},
      
      
        #{pic,jdbcType=VARCHAR},
      
      
        #{createtime,jdbcType=TIMESTAMP},
      
      
        #{detail,jdbcType=LONGVARCHAR},
      
    
  
  
  
    update items
    
      
        id = #{record.id,jdbcType=INTEGER},
      
      
        name = #{record.name,jdbcType=VARCHAR},
      
      
        price = #{record.price,jdbcType=REAL},
      
      
        pic = #{record.pic,jdbcType=VARCHAR},
      
      
        createtime = #{record.createtime,jdbcType=TIMESTAMP},
      
      
        detail = #{record.detail,jdbcType=LONGVARCHAR},
      
    
    
      
    
  
  
    update items
    set id = #{record.id,jdbcType=INTEGER},
      name = #{record.name,jdbcType=VARCHAR},
      price = #{record.price,jdbcType=REAL},
      pic = #{record.pic,jdbcType=VARCHAR},
      createtime = #{record.createtime,jdbcType=TIMESTAMP},
      detail = #{record.detail,jdbcType=LONGVARCHAR}
    
      
    
  
  
    update items
    set id = #{record.id,jdbcType=INTEGER},
      name = #{record.name,jdbcType=VARCHAR},
      price = #{record.price,jdbcType=REAL},
      pic = #{record.pic,jdbcType=VARCHAR},
      createtime = #{record.createtime,jdbcType=TIMESTAMP}
    
      
    
  
  
    update items
    
      
        name = #{name,jdbcType=VARCHAR},
      
      
        price = #{price,jdbcType=REAL},
      
      
        pic = #{pic,jdbcType=VARCHAR},
      
      
        createtime = #{createtime,jdbcType=TIMESTAMP},
      
      
        detail = #{detail,jdbcType=LONGVARCHAR},
      
    
    where id = #{id,jdbcType=INTEGER}
  
  
    update items
    set name = #{name,jdbcType=VARCHAR},
      price = #{price,jdbcType=REAL},
      pic = #{pic,jdbcType=VARCHAR},
      createtime = #{createtime,jdbcType=TIMESTAMP},
      detail = #{detail,jdbcType=LONGVARCHAR}
    where id = #{id,jdbcType=INTEGER}
  
  
    update items
    set name = #{name,jdbcType=VARCHAR},
      price = #{price,jdbcType=REAL},
      pic = #{pic,jdbcType=VARCHAR},
      createtime = #{createtime,jdbcType=TIMESTAMP}
    where id = #{id,jdbcType=INTEGER}
  

service 接口

package cn.janvi.ds.service;

import java.util.List;

import cn.janvi.ds.bean.Emp;

public interface EmpService {

	List findAll();
}

package cn.janvi.ds.service;

import java.util.List;

import com.github.pagehelper.PageInfo;

import cn.janvi.ds.bean.Items;

public interface ItemsService {

	List findAll();
	
	PageInfo findByPage(int page,int rows);
	
	int add(Items items);
}

sevice接口实现类

package cn.janvi.ds.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.janvi.ds.bean.Emp;
import cn.janvi.ds.config.Ds;
import cn.janvi.ds.mapper.EmpMapper;
import cn.janvi.ds.service.EmpService;

@Service
public class EmpServiceImpl implements EmpService {

	@Autowired
	private EmpMapper empMapper;
	
	/**
	 * 使用@Ds注解,指定使用的数据源2
	 */
	@Ds("ds2")
	@Override
	public List findAll() {
		return this.empMapper.selectByExample(null);
	}

}
package cn.janvi.ds.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import cn.janvi.ds.bean.Items;
import cn.janvi.ds.mapper.ItemsMapper;
import cn.janvi.ds.service.ItemsService;

@Service
public class ItemsServiceImpl implements ItemsService {

	@Autowired
	private ItemsMapper itemsMapper;
	
	@Override
	public List findAll() {
		return this.itemsMapper.selectByExample(null);
	}
        // 没有使用注解则说明此方法使用的是默认数据源1
	@Override
	public PageInfo findByPage(int page, int rows) {
		PageHelper.startPage(page,rows);
		List selectByExample = this.itemsMapper.selectByExample(null);
		PageInfo pageInfo = new PageInfo(selectByExample);
		return pageInfo;
	}

	/**
	 * 增删改需要事务
	 */
	@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor=Exception.class)
	@Override
	public int add(Items items) {
		// 模拟出错
		int a = 1/0;
		return this.itemsMapper.insert(items);
	}

}

编写测试类

package cn.janvi.test;

import java.sql.SQLException;
import java.util.Date;
import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageInfo;

import cn.janvi.ds.App;
import cn.janvi.ds.bean.Emp;
import cn.janvi.ds.bean.Items;
import cn.janvi.ds.service.EmpService;
import cn.janvi.ds.service.ItemsService;

@RunWith(SpringRunner.class)
@SpringBootTest(classes={App.class})
public class TT {


	@Autowired
	private ItemsService itemsService;

	/**
	 * 测试数据源1 - 查询所有Items
	 * @throws SQLException
	 */
	@Test
	public void testDynamicDs1() throws SQLException {
		List findAll = this.itemsService.findAll();
		
		System.out.println(JSON.toJSONString(findAll));
	}
	
	/**
	 * 测试数据源1 - 分页查询Items
	 * @throws SQLException
	 */
	@Test
	public void testDynamicDs1Page() throws SQLException {
		PageInfo findByPage = this.itemsService.findByPage(1, 2);
		
		System.out.println(JSON.toJSONString(findByPage.getList()));
	}
	
	
	@Test
	public void testDynamicDs1Add() {
		Items items = new Items();
		items.setId(4001);
		items.setName("联想小新");
		items.setCreatetime(new Date());
		items.setDetail("LENOVO - XiaoXin 700-15ISK");
		items.setPic("http://image.janvi/xx.png");
		items.setPrice(4799.0F);
		int result = this.itemsService.add(items);
		System.out.println(result);
	}
	
	
	@Autowired
	private EmpService empService;
	
	
	/**
	 * 测试数据源2 - 查询所有Emp
	 * @throws SQLException
	 */
	@Test
	public void testDynamicDs2(){
		List findAll = this.empService.findAll();
		
		System.out.println(JSON.toJSONString(findAll));
	}
	
}

数据源1使用mysql数据库,创建脚本:

CREATE TABLE `items` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(32) NOT NULL COMMENT '商品名称',
  `price` float(10,1) NOT NULL COMMENT '商品定价',
  `detail` text COMMENT '商品描述',
  `pic` varchar(64) default NULL COMMENT '商品图片',
  `createtime` datetime NOT NULL COMMENT '生产日期',
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8


数据源2使用oracle默认提供的scott账户


源码下载地址(百度云)链接:http://pan.baidu.com/s/1hs9YQva 密码:93rz


你可能感兴趣的:(spring-boot,spring,datasource,spring-boot,java,ee,mybatis)