Spring Boot 动态数据源(Spring 注解数据源)

<div class="content-detail markdown-body"> <p>本文实现案例场景:<br>某系统除了需要从自己的主要数据库上读取和管理数据外,还有一部分业务涉及到其他多个数据库,要求可以在任何方法上可以灵活指定具体要操作的数据库。</p> <p>为了在开发中以最简单的方法使用,本文基于注解和AOP的方法实现,在spring boot框架的项目中,添加本文实现的代码类后,只需要配置好数据源就可以直接通过注解使用,简单方便。</p> <p><strong>一配置二使用</strong><br><strong>1. 启动类注册动态数据源</strong><br><strong>2. 配置文件中配置多个数据源</strong><br><strong>3. 在需要的方法上使用注解指定数据源</strong></p> <p>1、在启动类添加 @Import({DynamicDataSourceRegister.class, MProxyTransactionManagementConfiguration.class})</p> <pre><code class="hljs less"><span class="hljs-variable">@SpringBootApplication</span> <span class="hljs-variable">@Import</span>({DynamicDataSourceRegister.class}) <span class="hljs-comment">// 注册动态多数据源</span> public class SpringBootSampleApplication {
<span class="hljs-comment">// 省略其他代码</span>

}</code></pre>

<p>2、配置文件配置内容为:<br>(不包括项目中的其他配置,这里只是数据源相关的)</p> <pre><code class="hljs nix"><span class="hljs-comment"># 主数据源,默认的</span></br> spring.datasource.<span class="hljs-attr">driver-class-name=com.mysql.jdbc.Driver</span></br> spring.datasource.<span class="hljs-attr">url=jdbc:mysql://localhost:3306/test</span></br> spring.datasource.<span class="hljs-attr">username=root</span></br> spring.datasource.<span class="hljs-attr">password=123456</span></br>

<span class="hljs-comment"># 更多数据源</span> custom.datasource.<span class="hljs-attr">names=ds1,ds2</span></br> custom.datasource.ds1.<span class="hljs-attr">driver-class-name=com.mysql.jdbc.Driver</span></br> custom.datasource.ds1.<span class="hljs-attr">url=jdbc:mysql://localhost:3306/test1</span></br> custom.datasource.ds1.<span class="hljs-attr">username=root</span></br> custom.datasource.ds1.<span class="hljs-attr">password=123456</span></br>

custom.datasource.ds2.<span class="hljs-attr">driver-class-name=com.mysql.jdbc.Driver</span></br> custom.datasource.ds2.<span class="hljs-attr">url=jdbc:mysql://localhost:3306/test2</span></br> custom.datasource.ds2.<span class="hljs-attr">username=root</span></br> custom.datasource.ds2.<span class="hljs-attr">password=123456</span></code></pre>

<p>3、使用方法</p> <pre><code class="hljs java"><span class="hljs-keyword">package</span> org.springboot.sample.service;</br>

<span class="hljs-keyword">import</span> java.sql.ResultSet;</br> <span class="hljs-keyword">import</span> java.sql.SQLException;</br> <span class="hljs-keyword">import</span> java.util.List;</br>

<span class="hljs-keyword">import</span> org.springboot.sample.datasource.TargetDataSource;</br> <span class="hljs-keyword">import</span> org.springboot.sample.entity.Student;</br> <span class="hljs-keyword">import</span> org.springboot.sample.mapper.StudentMapper;</br> <span class="hljs-keyword">import</span> org.springframework.beans.factory.annotation.Autowired;</br> <span class="hljs-keyword">import</span> org.springframework.jdbc.core.JdbcTemplate;</br> <span class="hljs-keyword">import</span> org.springframework.jdbc.core.RowMapper;</br> <span class="hljs-keyword">import</span> org.springframework.stereotype.Service;</br>

<span class="hljs-comment">/**</br>

  • Student Service</br>

  • <span class="hljs-doctag">@author</span> 单红宇(365384722)</br>

  • <span class="hljs-doctag">@myblog</span> http://blog.csdn.net/catoop/</br>

  • <span class="hljs-doctag">@create</span> 2016年1月12日</br> */</span></br> <span class="hljs-meta">@Service</span></br> <span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">StudentService</span> </span>{</br>

    <span class="hljs-meta">@Autowired</span></br> <span class="hljs-keyword">private</span> JdbcTemplate jdbcTemplate;</br>

    <span class="hljs-comment">// MyBatis的Mapper方法定义接口</span></br> <span class="hljs-meta">@Autowired</span></br> <span class="hljs-keyword">private</span> StudentMapper studentMapper;</br>

    <span class="hljs-meta">@TargetDataSource</span>(name=<span class="hljs-string">"ds2"</span>)</br> <span class="hljs-function"><span class="hljs-keyword">public</span> List<Student> <span class="hljs-title">likeName</span><span class="hljs-params">(String name)</span></span>{</br> <span class="hljs-keyword">return</span> studentMapper.likeName(name);</br> }

    <span class="hljs-function"><span class="hljs-keyword">public</span> List<Student> <span class="hljs-title">likeNameByDefaultDataSource</span><span class="hljs-params">(String name)</span></span>{</br> <span class="hljs-keyword">return</span> studentMapper.likeName(name);</br> }

    <span class="hljs-comment"></br>/**

    • 不指定数据源使用默认数据源</br>

    • <span class="hljs-doctag">@return</span></br>

    • <span class="hljs-doctag">@author</span> SHANHY</br>

    • <span class="hljs-doctag">@create</span> 2016年1月24日</br> */</span></br> <span class="hljs-function"><span class="hljs-keyword">public</span> List<Student> <span class="hljs-title">getList</span><span class="hljs-params">()</span></span>{</br> String sql = <span class="hljs-string">"SELECT ID,NAME,SCORE_SUM,SCORE_AVG, AGE FROM STUDENT"</span>;</br> <span class="hljs-keyword">return</span> (List<Student>) jdbcTemplate.query(sql, <span class="hljs-keyword">new</span> RowMapper<Student>(){</br>

      1 <span class="hljs-meta">@Override</span></br> 2 <span class="hljs-function"><span class="hljs-keyword">public</span> Student <span class="hljs-title">mapRow</span><span class="hljs-params">(ResultSet rs, <span class="hljs-keyword">int</span> rowNum)</span> <span class="hljs-keyword">throws</span> SQLException </span>{</br> 3 Student stu = <span class="hljs-keyword">new</span> Student();</br> 4 stu.setId(rs.getInt(<span class="hljs-string">"ID"</span>));</br> 5 stu.setAge(rs.getInt(<span class="hljs-string">"AGE"</span>));</br> 6 stu.setName(rs.getString(<span class="hljs-string">"NAME"</span>));</br> 7 stu.setSumScore(rs.getString(<span class="hljs-string">"SCORE_SUM"</span>));</br> 8 stu.setAvgScore(rs.getString(<span class="hljs-string">"SCORE_AVG"</span>));</br> 9 <span class="hljs-keyword">return</span> stu;</br> 10 }

      }); }

    <span class="hljs-comment"></br>/**

    • 指定数据源</br>

    • <span class="hljs-doctag">@return</span></br>

    • <span class="hljs-doctag">@author</span> SHANHY</br>

    • <span class="hljs-doctag">@create</span> 2016年1月24日</br> */</span> <span class="hljs-meta">@TargetDataSource</span>(name=<span class="hljs-string">"ds1"</span>)</br> <span class="hljs-function"><span class="hljs-keyword">public</span> List<Student> <span class="hljs-title">getListByDs1</span><span class="hljs-params">()</span></span>{</br> String sql = <span class="hljs-string">"SELECT ID,NAME,SCORE_SUM,SCORE_AVG, AGE FROM STUDENT"</span>;</br> <span class="hljs-keyword">return</span> (List<Student>) jdbcTemplate.query(sql, <span class="hljs-keyword">new</span> RowMapper<Student>(){</br>

      1 <span class="hljs-meta">@Override</span></br> 2 <span class="hljs-function"><span class="hljs-keyword">public</span> Student <span class="hljs-title">mapRow</span><span class="hljs-params">(ResultSet rs, <span class="hljs-keyword">int</span> rowNum)</span> <span class="hljs-keyword">throws</span> SQLException </span>{</br> 3 Student stu = <span class="hljs-keyword">new</span> Student();</br> 4 stu.setId(rs.getInt(<span class="hljs-string">"ID"</span>));</br> 5 stu.setAge(rs.getInt(<span class="hljs-string">"AGE"</span>));</br> 6 stu.setName(rs.getString(<span class="hljs-string">"NAME"</span>));</br> 7 stu.setSumScore(rs.getString(<span class="hljs-string">"SCORE_SUM"</span>));</br> 8 stu.setAvgScore(rs.getString(<span class="hljs-string">"SCORE_AVG"</span>));</br> 9 <span class="hljs-keyword">return</span> stu;</br> 10 }

      }); }

    <span class="hljs-comment"></br>/**

    • 指定数据源</br>

    • <span class="hljs-doctag">@return</span></br>

    • <span class="hljs-doctag">@author</span> SHANHY</br>

    • <span class="hljs-doctag">@create</span> 2016年1月24日</br> */</span></br> <span class="hljs-meta">@TargetDataSource</span>(name=<span class="hljs-string">"ds2"</span>)</br> <span class="hljs-function"><span class="hljs-keyword">public</span> List<Student> <span class="hljs-title">getListByDs2</span><span class="hljs-params">()</span></span>{</br> String sql = <span class="hljs-string">"SELECT ID,NAME,SCORE_SUM,SCORE_AVG, AGE FROM STUDENT"</span>;</br> <span class="hljs-keyword">return</span> (List<Student>) jdbcTemplate.query(sql, <span class="hljs-keyword">new</span> RowMapper<Student>(){</br>

      1 <span class="hljs-meta">@Override</span></br> 2 <span class="hljs-function"><span class="hljs-keyword">public</span> Student <span class="hljs-title">mapRow</span><span class="hljs-params">(ResultSet rs, <span class="hljs-keyword">int</span> rowNum)</span> <span class="hljs-keyword">throws</span> SQLException </span>{</br> 3 Student stu = <span class="hljs-keyword">new</span> Student();</br> 4 stu.setId(rs.getInt(<span class="hljs-string">"ID"</span>));</br> 5 stu.setAge(rs.getInt(<span class="hljs-string">"AGE"</span>));</br> 6 stu.setName(rs.getString(<span class="hljs-string">"NAME"</span>));</br> 7 stu.setSumScore(rs.getString(<span class="hljs-string">"SCORE_SUM"</span>));</br> 8 stu.setAvgScore(rs.getString(<span class="hljs-string">"SCORE_AVG"</span>));</br> 9 <span class="hljs-keyword">return</span> stu;</br> 10 }

      }); } } </code></pre>

<p>要注意的是,在使用MyBatis时,注解@TargetDataSource 不能直接在接口类Mapper上使用。<br>按上面的代码中StudentMapper为接口,代码如下:</p> <pre><code class="hljs java"><span class="hljs-keyword">package</span> org.springboot.sample.mapper;</br>

<span class="hljs-keyword">import</span> java.util.List;</br>

<span class="hljs-keyword">import</span> org.springboot.sample.entity.Student;</br>

<span class="hljs-comment">/**

  • StudentMapper,映射SQL语句的接口,无逻辑实现</br>

  • <span class="hljs-doctag">@author</span> 单红宇(365384722)</br>

  • <span class="hljs-doctag">@myblog</span> http://blog.csdn.net/catoop/</br>

  • <span class="hljs-doctag">@create</span> 2016年1月20日</br> */</span> <span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">StudentMapper</span> </span>{</br>

    <span class="hljs-comment">// 注解 @TargetDataSource 不可以在这里使用</span></br> <span class="hljs-function">List<Student> <span class="hljs-title">likeName</span><span class="hljs-params">(String name)</span></span>;</br>

    <span class="hljs-function">Student <span class="hljs-title">getById</span><span class="hljs-params">(<span class="hljs-keyword">int</span> id)</span></span>;</br>

    <span class="hljs-function">String <span class="hljs-title">getNameById</span><span class="hljs-params">(<span class="hljs-keyword">int</span> id)</span></span>;</br>

} </code></pre>

<hr> <hr> <p>请将下面几个类放到Spring Boot项目中。<br>DynamicDataSource.java<br>DynamicDataSourceAspect.java<br>DynamicDataSourceContextHolder.java<br>DynamicDataSourceRegister.java<br>TargetDataSource.java<br>MProxyTransactionManagementConfiguration.java<br>MTransactionInterceptor.java</p> <pre><code class="hljs scala"><span class="hljs-keyword">package</span> org.springboot.sample.datasource;</br>

<span class="hljs-keyword">import</span> org.springframework.jdbc.datasource.lookup.<span class="hljs-type">AbstractRoutingDataSource</span>;</br>

<span class="hljs-comment">/**</br>

  • 动态数据源

  • @author 单红宇(365384722)</br>

  • @myblog http://blog.csdn.net/catoop/</br>

  • @create 2016年1月22日 */</span> public <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DynamicDataSource</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">AbstractRoutingDataSource</span> </span>{</br>

    <span class="hljs-meta">@Override</span> <span class="hljs-keyword">protected</span> <span class="hljs-type">Object</span> determineCurrentLookupKey() {</br> <span class="hljs-keyword">return</span> <span class="hljs-type">DynamicDataSourceContextHolder</span>.getDataSourceType();</br> }

} </code></pre>

<pre><code class="hljs kotlin"><span class="hljs-keyword">package</span> org.springboot.sample.datasource;</br> <span class="hljs-keyword">import</span> org.aspectj.lang.JoinPoint;</br> <span class="hljs-keyword">import</span> org.aspectj.lang.<span class="hljs-keyword">annotation</span>.After;</br> <span class="hljs-keyword">import</span> org.aspectj.lang.<span class="hljs-keyword">annotation</span>.Aspect;</br> <span class="hljs-keyword">import</span> org.aspectj.lang.<span class="hljs-keyword">annotation</span>.Before;</br> <span class="hljs-keyword">import</span> org.slf4j.Logger;</br> <span class="hljs-keyword">import</span> org.slf4j.LoggerFactory;</br> <span class="hljs-keyword">import</span> org.springframework.stereotype.Component;</br> <span class="hljs-comment"></br>/\*\* \* 切换数据源Advice</br> \* \* <span class="hljs-doctag">@author</span> 单红宇(365384722)</br> \* <span class="hljs-doctag">@myblog</span> http://blog.csdn.net/catoop/</br> \* <span class="hljs-doctag">@create</span> 2016年1月23日</br> \*/</span> <span class="hljs-meta">@Aspect</span></br> <span class="hljs-meta">@Order(-1)</span><span class="hljs-comment">// 保证该AOP在@Transactional之前执行</span> <span class="hljs-meta">@Component</span> <span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DynamicDataSourceAspect</span> </span>{</br> <span class="hljs-keyword">private</span> static <span class="hljs-keyword">final</span> Logger logger = LoggerFactory.getLogger(DynamicDataSourceAspect.<span class="hljs-keyword">class</span>);</br> <span class="hljs-meta">@Before(<span class="hljs-meta-string">"@annotation(ds)"</span>)</span> <span class="hljs-keyword">public</span> void changeDataSource(JoinPoint point, TargetDataSource ds) throws Throwable {</br> String dsId = ds.name();</br> <span class="hljs-keyword">if</span> (!DynamicDataSourceContextHolder.containsDataSource(dsId)) {</br> logger.error(<span class="hljs-string">"数据源\[{}\]不存在,使用默认数据源 &gt; {}"</span>, ds.name(), point.getSignature());</br> } <span class="hljs-keyword">else</span> {</br> logger.debug(<span class="hljs-string">"Use DataSource : {} &gt; {}"</span>, ds.name(), point.getSignature());</br> DynamicDataSourceContextHolder.setDataSourceType(ds.name());</br> } } <span class="hljs-meta">@After(<span class="hljs-meta-string">"@annotation(ds)"</span>)</span></br> <span class="hljs-keyword">public</span> void restoreDataSource(JoinPoint point, TargetDataSource ds) {</br> logger.debug(<span class="hljs-string">"Revert DataSource : {} &gt; {}"</span>, ds.name(), point.getSignature());</br> DynamicDataSourceContextHolder.clearDataSourceType();</br> } } </code></pre> <pre><code class="hljs aspectj"><span class="hljs-keyword">package</span> org.springboot.sample.datasource;</br> <span class="hljs-keyword">import</span> java.util.ArrayList;</br> <span class="hljs-keyword">import</span> java.util.List;</br> <span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DynamicDataSourceContextHolder</span> </span>{</br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> ThreadLocal&lt;String&gt; contextHolder = <span class="hljs-keyword">new</span> ThreadLocal&lt;String&gt;();</br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> List&lt;String&gt; dataSourceIds = <span class="hljs-keyword">new</span> ArrayList&lt;&gt;(); </br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">setDataSourceType</span><span class="hljs-params">(String dataSourceType)</span> </span>{</br> contextHolder.set(dataSourceType);</br> }</br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-function">String <span class="hljs-title">getDataSourceType</span><span class="hljs-params">()</span> </span>{</br> <span class="hljs-function"><span class="hljs-keyword">return</span> contextHolder.<span class="hljs-title">get</span><span class="hljs-params">()</span></span>;</br> } <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">clearDataSourceType</span><span class="hljs-params">()</span> </span>{</br> contextHolder.remove();</br> } <span class="hljs-comment">/\*\* \* 判断指定DataSrouce当前是否存在</br> \* \* <span class="hljs-doctag">@param</span> dataSourceId</br> \* <span class="hljs-doctag">@return</span></br> \* <span class="hljs-doctag">@author</span> SHANHY</br> \* <span class="hljs-doctag">@create</span> 2016年1月24日</br> \*/</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-function"><span class="hljs-keyword">boolean</span> <span class="hljs-title">containsDataSource</span><span class="hljs-params">(String dataSourceId)</span></span>{</br> <span class="hljs-function"><span class="hljs-keyword">return</span> dataSourceIds.<span class="hljs-title">contains</span><span class="hljs-params">(dataSourceId)</span></span>;</br> } } </code></pre> <pre><code class="hljs processing"><span class="hljs-keyword">package</span> org.springboot.sample.datasource;</br> <span class="hljs-keyword">import</span> java.util.<span class="hljs-keyword">HashMap</span>;</br> <span class="hljs-keyword">import</span> java.util.Map;</br> <span class="hljs-keyword">import</span> javax.sql.DataSource;</br> <span class="hljs-keyword">import</span> org.slf4j.Logger;</br> <span class="hljs-keyword">import</span> org.slf4j.LoggerFactory;</br> <span class="hljs-keyword">import</span> org.springframework.beans.MutablePropertyValues;</br> <span class="hljs-keyword">import</span> org.springframework.beans.PropertyValues;</br> <span class="hljs-keyword">import</span> org.springframework.beans.factory.support.BeanDefinitionRegistry;</br> <span class="hljs-keyword">import</span> org.springframework.beans.factory.support.GenericBeanDefinition;</br> <span class="hljs-keyword">import</span> org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;</br> <span class="hljs-keyword">import</span> org.springframework.boot.bind.RelaxedDataBinder;</br> <span class="hljs-keyword">import</span> org.springframework.boot.bind.RelaxedPropertyResolver;</br> <span class="hljs-keyword">import</span> org.springframework.context.EnvironmentAware;</br> <span class="hljs-keyword">import</span> org.springframework.context.annotation.ImportBeanDefinitionRegistrar;</br> <span class="hljs-keyword">import</span> org.springframework.core.convert.ConversionService;</br> <span class="hljs-keyword">import</span> org.springframework.core.convert.support.DefaultConversionService;</br> <span class="hljs-keyword">import</span> org.springframework.core.env.Environment;</br> <span class="hljs-keyword">import</span> org.springframework.core.type.AnnotationMetadata;</br> <span class="hljs-comment">/\*\* \* 动态数据源注册&lt;br/&gt;</br> \* 启动动态数据源请在启动类中(如SpringBootSampleApplication)</br> \* 添加 @Import(DynamicDataSourceRegister.class)</br> \* \* @author 单红宇(365384722)</br> \* @myblog http://blog.csdn.net/catoop/</br> \* @create 2016年1月24日</br> \*/</span> <span class="hljs-keyword">public</span> class DynamicDataSourceRegister</br> implements ImportBeanDefinitionRegistrar, EnvironmentAware { </br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> Logger logger = LoggerFactory.getLogger(DynamicDataSourceRegister.class);</br> <span class="hljs-keyword">private</span> ConversionService conversionService = <span class="hljs-keyword">new</span> DefaultConversionService(); </br> <span class="hljs-keyword">private</span> PropertyValues dataSourcePropertyValues;</br> <span class="hljs-comment">// 如配置文件中未指定数据源类型,使用该默认值</span></br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">Object</span> DATASOURCE\_TYPE\_DEFAULT = <span class="hljs-string">"org.apache.tomcat.jdbc.pool.DataSource"</span>; <span class="hljs-comment">// private static final Object DATASOURCE\_TYPE\_DEFAULT =</span></br> <span class="hljs-comment">// "com.zaxxer.hikari.HikariDataSource";</span></br> <span class="hljs-comment">// 数据源</span></br> <span class="hljs-keyword">private</span> DataSource defaultDataSource;</br> <span class="hljs-keyword">private</span> Map&lt;<span class="hljs-keyword">String</span>, DataSource&gt; customDataSources = <span class="hljs-keyword">new</span> <span class="hljs-keyword">HashMap</span>&lt;&gt;();</br> @Override</br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {</br> Map&lt;<span class="hljs-keyword">Object</span>, <span class="hljs-keyword">Object</span>&gt; targetDataSources = <span class="hljs-keyword">new</span> <span class="hljs-keyword">HashMap</span>&lt;<span class="hljs-keyword">Object</span>, <span class="hljs-keyword">Object</span>&gt;(); <span class="hljs-comment">// 将主数据源添加到更多数据源中</span></br> targetDataSources.put(<span class="hljs-string">"dataSource"</span>, defaultDataSource);</br> DynamicDataSourceContextHolder.dataSourceIds.<span class="hljs-built\_in">add</span>(<span class="hljs-string">"dataSource"</span>);</br> <span class="hljs-comment">// 添加更多数据源</span></br> targetDataSources.putAll(customDataSources);</br> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">String</span> <span class="hljs-built\_in">key</span> : customDataSources.keySet()) {</br> DynamicDataSourceContextHolder.dataSourceIds.<span class="hljs-built\_in">add</span>(<span class="hljs-built\_in">key</span>);</br> } <span class="hljs-comment">// 创建DynamicDataSource</span></br> GenericBeanDefinition beanDefinition = <span class="hljs-keyword">new</span> GenericBeanDefinition();</br> beanDefinition.setBeanClass(DynamicDataSource.class);</br> beanDefinition.setSynthetic(<span class="hljs-keyword">true</span>);</br> MutablePropertyValues mpv = beanDefinition.getPropertyValues();</br> mpv.addPropertyValue(<span class="hljs-string">"defaultTargetDataSource"</span>, defaultDataSource);</br> mpv.addPropertyValue(<span class="hljs-string">"targetDataSources"</span>, targetDataSources);</br> registry.registerBeanDefinition(<span class="hljs-string">"dataSource"</span>, beanDefinition);</br> logger.info(<span class="hljs-string">"Dynamic DataSource Registry"</span>);</br> } <span class="hljs-comment">/\*\* \* 创建DataSource</br> \* \* @param type</br> \* @param driverClassName</br> \* @param url</br> \* @param username</br> \* @param password</br> \* @return</br> \* @author SHANHY</br> \* @create 2016年1月24日</br> \*/</span> @SuppressWarnings(<span class="hljs-string">"unchecked"</span>)</br> <span class="hljs-keyword">public</span> DataSource buildDataSource(Map&lt;<span class="hljs-keyword">String</span>, <span class="hljs-keyword">Object</span>&gt; dsMap) {</br> <span class="hljs-keyword">try</span> {</br> <span class="hljs-keyword">Object</span> type = dsMap.<span class="hljs-built\_in">get</span>(<span class="hljs-string">"type"</span>);</br> <span class="hljs-keyword">if</span> (type == <span class="hljs-keyword">null</span>)</br> type = DATASOURCE\_TYPE\_DEFAULT;<span class="hljs-comment">// 默认DataSource</span></br> Class&lt;? extends DataSource&gt; dataSourceType;</br> dataSourceType = (Class&lt;? extends DataSource&gt;) Class.forName((<span class="hljs-keyword">String</span>) type);</br> <span class="hljs-keyword">String</span> driverClassName = dsMap.<span class="hljs-built\_in">get</span>(<span class="hljs-string">"driver-class-name"</span>).toString();</br> <span class="hljs-keyword">String</span> url = dsMap.<span class="hljs-built\_in">get</span>(<span class="hljs-string">"url"</span>).toString();</br> <span class="hljs-keyword">String</span> username = dsMap.<span class="hljs-built\_in">get</span>(<span class="hljs-string">"username"</span>).toString();</br> <span class="hljs-keyword">String</span> password = dsMap.<span class="hljs-built\_in">get</span>(<span class="hljs-string">"password"</span>).toString();</br> DataSourceBuilder factory = DataSourceBuilder.create().driverClassName(driverClassName).url(url)</br> .username(username).password(password).type(dataSourceType);</br> <span class="hljs-keyword">return</span> factory.build();</br> } <span class="hljs-keyword">catch</span> (ClassNotFoundException e) {</br> e.printStackTrace();</br> }</br> <span class="hljs-keyword">return</span> <span class="hljs-keyword">null</span>;</br> } <span class="hljs-comment">/\*\*</br> \* 加载多数据源配置 \*/</span> @Override <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> setEnvironment(Environment env) {</br> initDefaultDataSource(env);</br> initCustomDataSources(env);</br> } <span class="hljs-comment">/\*\* \* 初始化主数据源 \* \* @author SHANHY \* @create 2016年1月24日 \*/</span> <span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> initDefaultDataSource(Environment env) {</br> <span class="hljs-comment">// 读取主数据源</span></br> RelaxedPropertyResolver propertyResolver = <span class="hljs-keyword">new</span> RelaxedPropertyResolver(env, <span class="hljs-string">"spring.datasource."</span>);</br> Map&lt;<span class="hljs-keyword">String</span>, <span class="hljs-keyword">Object</span>&gt; dsMap = <span class="hljs-keyword">new</span> <span class="hljs-keyword">HashMap</span>&lt;&gt;();</br> dsMap.put(<span class="hljs-string">"type"</span>, propertyResolver.getProperty(<span class="hljs-string">"type"</span>));</br> dsMap.put(<span class="hljs-string">"driver-class-name"</span>, propertyResolver.getProperty(<span class="hljs-string">"driver-class-name"</span>));</br> dsMap.put(<span class="hljs-string">"url"</span>, propertyResolver.getProperty(<span class="hljs-string">"url"</span>));</br> dsMap.put(<span class="hljs-string">"username"</span>, propertyResolver.getProperty(<span class="hljs-string">"username"</span>));</br> dsMap.put(<span class="hljs-string">"password"</span>, propertyResolver.getProperty(<span class="hljs-string">"password"</span>));</br> defaultDataSource = buildDataSource(dsMap);</br> dataBinder(defaultDataSource, env);</br> } <span class="hljs-comment">/\*\* \* 为DataSource绑定更多数据</br> \* \* @param dataSource</br> \* @param env</br> \* @author SHANHY</br> \* @create 2016年1月25日</br> \*/</span></br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> dataBinder(DataSource dataSource, Environment env){</br> RelaxedDataBinder dataBinder = <span class="hljs-keyword">new</span> RelaxedDataBinder(dataSource);</br> <span class="hljs-comment">//dataBinder.setValidator(new LocalValidatorFactory().run(this.applicationContext));</span></br> dataBinder.setConversionService(conversionService);</br> dataBinder.setIgnoreNestedProperties(<span class="hljs-keyword">false</span>);<span class="hljs-comment">//false</span></br> dataBinder.setIgnoreInvalidFields(<span class="hljs-keyword">false</span>);<span class="hljs-comment">//false</span></br> dataBinder.setIgnoreUnknownFields(<span class="hljs-keyword">true</span>);<span class="hljs-comment">//true</span></br> <span class="hljs-keyword">if</span>(dataSourcePropertyValues == <span class="hljs-keyword">null</span>){</br> Map&lt;<span class="hljs-keyword">String</span>, <span class="hljs-keyword">Object</span>&gt; rpr = <span class="hljs-keyword">new</span> RelaxedPropertyResolver(env, <span class="hljs-string">"spring.datasource"</span>).getSubProperties(<span class="hljs-string">"."</span>);</br> Map&lt;<span class="hljs-keyword">String</span>, <span class="hljs-keyword">Object</span>&gt; values = <span class="hljs-keyword">new</span> <span class="hljs-keyword">HashMap</span>&lt;&gt;(rpr);</br> <span class="hljs-comment">// 排除已经设置的属性</span></br> values.remove(<span class="hljs-string">"type"</span>);</br> values.remove(<span class="hljs-string">"driver-class-name"</span>);</br> values.remove(<span class="hljs-string">"url"</span>);</br> values.remove(<span class="hljs-string">"username"</span>);</br> values.remove(<span class="hljs-string">"password"</span>);</br> dataSourcePropertyValues = <span class="hljs-keyword">new</span> MutablePropertyValues(values);</br> }</br> dataBinder.bind(dataSourcePropertyValues);</br> } <span class="hljs-comment">/\*\* \* 初始化更多数据源 \* \* @author SHANHY \* @create 2016年1月24日 \*/</span> <span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> initCustomDataSources(Environment env) {</br> <span class="hljs-comment">// 读取配置文件获取更多数据源,也可以通过defaultDataSource读取数据库获取更多数据源</span></br> RelaxedPropertyResolver propertyResolver = <span class="hljs-keyword">new</span> RelaxedPropertyResolver(env, <span class="hljs-string">"custom.datasource."</span>);</br> <span class="hljs-keyword">String</span> dsPrefixs = propertyResolver.getProperty(<span class="hljs-string">"names"</span>);</br> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">String</span> dsPrefix : dsPrefixs.<span class="hljs-built\_in">split</span>(<span class="hljs-string">","</span>)) {<span class="hljs-comment">// 多个数据源</span></br> Map&lt;<span class="hljs-keyword">String</span>, <span class="hljs-keyword">Object</span>&gt; dsMap = propertyResolver.getSubProperties(dsPrefix + <span class="hljs-string">"."</span>);</br> DataSource ds = buildDataSource(dsMap);</br> customDataSources.put(dsPrefix, ds);</br> dataBinder(ds, env);</br> }</br> }</br> } </code></pre> <pre><code class="hljs css"><span class="hljs-selector-tag">package</span> <span class="hljs-selector-tag">org</span><span class="hljs-selector-class">.springboot</span><span class="hljs-selector-class">.sample</span><span class="hljs-selector-class">.datasource</span>; <span class="hljs-selector-tag">import</span> <span class="hljs-selector-tag">java</span><span class="hljs-selector-class">.lang</span><span class="hljs-selector-class">.annotation</span><span class="hljs-selector-class">.Documented</span>; <span class="hljs-selector-tag">import</span> <span class="hljs-selector-tag">java</span><span class="hljs-selector-class">.lang</span><span class="hljs-selector-class">.annotation</span><span class="hljs-selector-class">.ElementType</span>; <span class="hljs-selector-tag">import</span> <span class="hljs-selector-tag">java</span><span class="hljs-selector-class">.lang</span><span class="hljs-selector-class">.annotation</span><span class="hljs-selector-class">.Retention</span>; <span class="hljs-selector-tag">import</span> <span class="hljs-selector-tag">java</span><span class="hljs-selector-class">.lang</span><span class="hljs-selector-class">.annotation</span><span class="hljs-selector-class">.RetentionPolicy</span>; <span class="hljs-selector-tag">import</span> <span class="hljs-selector-tag">java</span><span class="hljs-selector-class">.lang</span><span class="hljs-selector-class">.annotation</span><span class="hljs-selector-class">.Target</span>; <span class="hljs-comment">/\*\* \* 在方法上使用,用于指定使用哪个数据源 \* \* @author 单红宇(365384722)</br> \* @myblog http://blog.csdn.net/catoop/</br> \* @create 2016年1月23日 \*/</span> @<span class="hljs-keyword">Target</span>({ <span class="hljs-selector-tag">ElementType</span><span class="hljs-selector-class">.METHOD</span>, <span class="hljs-selector-tag">ElementType</span><span class="hljs-selector-class">.TYPE</span> })</br> @<span class="hljs-keyword">Retention</span>(<span class="hljs-keyword">RetentionPolicy</span>.<span class="hljs-keyword">RUNTIME</span>)</br> @Documented</br> public @interface TargetDataSource {</br> <span class="hljs-selector-tag">String</span> <span class="hljs-selector-tag">name</span>();</br> }</br> </code></pre> <p>本文代码博主是经过测试后没有问题才发出来共享给大家的。对于连接池参数配置会应用到所有数据源上。<br>比如配置一个:</p> <pre><code class="hljs stylus">spring<span class="hljs-selector-class">.datasource</span><span class="hljs-selector-class">.maximum-pool-size</span>=<span class="hljs-number">80</span></code></pre> <p>那么我们所有的数据源都会自动应用上。</p>
1<!-- 登录查看 begin --> 2 <!-- 登录查看 end -->
</div>
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )