首页 > 代码库 > 【瞎折腾系列】Spring DataSource 【结论:没弄好】

【瞎折腾系列】Spring DataSource 【结论:没弄好】

本来想弄个多数据源,但是技术不高,嗯,宣布失败。。。

嗯,结论是失败了。。。

求高手给我讲讲这些东西啊,感激不尽啊~~~

 

以下的折腾也是基于之前配置的Spring Mybatis框架。

想弄多数据源,首先想到的就是从datasource入手。

spring-database.xml改成了两个datasource:

<bean id="dataSourceA"  class="com.alibaba.druid.pool.DruidDataSource">            <property name="driverClassName" value="com.mysql.jdbc.Driver" />        <property name="url" value="jdbc:mysql://localhost:3306/mydb" />        <property name="username" value="root" />        <property name="password" value="123456" />        <!-- 初始化连接大小 -->        <property name="initialSize" value="0" />        <!-- 连接池最大使用连接数量 -->        <property name="maxActive" value="20" />        <!-- 连接池最小空闲 -->        <property name="minIdle" value="0" />        <!-- 获取连接最大等待时间 -->        <property name="maxWait" value="60000" />        <property name="validationQuery"><value>SELECT 1</value></property>         <property name="testOnBorrow" value="false" />        <property name="testOnReturn" value="false" />        <property name="testWhileIdle" value="true" />        <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->        <property name="timeBetweenEvictionRunsMillis" value="60000" />        <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->        <property name="minEvictableIdleTimeMillis" value="25200000" />        <!-- 打开removeAbandoned功能 -->        <property name="removeAbandoned" value="true" />        <!-- 1800秒,也就是30分钟 -->        <property name="removeAbandonedTimeout" value="1800" />        <!-- 关闭abanded连接时输出错误日志 -->        <property name="logAbandoned" value="true" />        <!-- 监控数据库 -->        <!-- <property name="filters" value="http://www.mamicode.com/stat" /> -->        <property name="filters" value="mergeStat" />    </bean>        <!-- 2 -->        <bean id="dataSourceB"  class="com.alibaba.druid.pool.DruidDataSource">            <property name="driverClassName" value="com.mysql.jdbc.Driver" />        <property name="url" value="jdbc:mysql://localhost:3306/test" />        <property name="username" value="root" />        <property name="password" value="123456" />        <!-- 初始化连接大小 -->        <property name="initialSize" value="0" />        <!-- 连接池最大使用连接数量 -->        <property name="maxActive" value="20" />        <!-- 连接池最小空闲 -->        <property name="minIdle" value="0" />        <!-- 获取连接最大等待时间 -->        <property name="maxWait" value="60000" />        <property name="validationQuery"><value>SELECT 1</value></property>         <property name="testOnBorrow" value="false" />        <property name="testOnReturn" value="false" />        <property name="testWhileIdle" value="true" />        <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->        <property name="timeBetweenEvictionRunsMillis" value="60000" />        <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->        <property name="minEvictableIdleTimeMillis" value="25200000" />        <!-- 打开removeAbandoned功能 -->        <property name="removeAbandoned" value="true" />        <!-- 1800秒,也就是30分钟 -->        <property name="removeAbandonedTimeout" value="1800" />        <!-- 关闭abanded连接时输出错误日志 -->        <property name="logAbandoned" value="true" />        <!-- 监控数据库 -->        <!-- <property name="filters" value="http://www.mamicode.com/stat" /> -->        <property name="filters" value="mergeStat" />    </bean>

之后想着自己实现个datasource然后插在sqlSessionFactory和DruidDataSource之间:

    <bean id="MyDataSource"    class="com.hi.test.datasource.MyDataSource">    </bean>

MyDataSource.java:

package com.hi.test.datasource;import java.io.PrintWriter;import java.sql.Connection;import java.sql.SQLException;import java.sql.SQLFeatureNotSupportedException;import java.util.logging.Logger;import javax.sql.DataSource;import com.alibaba.druid.pool.DruidDataSource;public class MyDataSource implements DataSource{        DruidDataSource druidDataSource;        public DruidDataSource getDruidDataSource() {        return druidDataSource;    }    public void setDruidDataSource(DruidDataSource druidDataSource) {        this.druidDataSource = druidDataSource;    }    public PrintWriter getLogWriter() throws SQLException {        // TODO Auto-generated method stub        return druidDataSource.getLogWriter();    }    public int getLoginTimeout() throws SQLException {        // TODO Auto-generated method stub        return druidDataSource.getLoginTimeout();    }    public Logger getParentLogger() throws SQLFeatureNotSupportedException {        // TODO Auto-generated method stub        return druidDataSource.getParentLogger();    }    public void setLogWriter(PrintWriter arg0) throws SQLException {        // TODO Auto-generated method stub        druidDataSource.setLogWriter(arg0);            }    public void setLoginTimeout(int arg0) throws SQLException {        // TODO Auto-generated method stub        druidDataSource.setLoginTimeout(arg0);            }    public boolean isWrapperFor(Class<?> arg0) throws SQLException {        // TODO Auto-generated method stub        return druidDataSource.isWrapperFor(arg0);    }    public <T> T unwrap(Class<T> arg0) throws SQLException {        // TODO Auto-generated method stub        return druidDataSource.unwrap(arg0);    }    public Connection getConnection() throws SQLException {        // TODO Auto-generated method stub        return druidDataSource.getConnection();    }    public Connection getConnection(String arg0, String arg1)            throws SQLException {        // TODO Auto-generated method stub        return druidDataSource.getConnection(arg0, arg1);    }}

之后的sqlsessionfactory配置:

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><!--         <property name="dataSource" ref="dataSource" /> --><property name="dataSource" ref="MyDataSource" /><property name="configLocation" value="classpath:mybatis-config.xml"></property>      </bean>

 

好了,之后就想着怎么把MyDataSource里的druidDataSource和dataSourceA或者B关联上。

 

先写个工具获取spring的bean:

SpringUtil:

package com.hi.test.datasource;import org.springframework.beans.BeansException;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;public class SpringUtil implements ApplicationContextAware{    private static ApplicationContext applicationContext;        public void setApplicationContext(ApplicationContext applicationContext)            throws BeansException {        // TODO Auto-generated method stub        this.applicationContext=applicationContext;            }    public static Object getObject(String id) {        Object object = null;        object = applicationContext.getBean(id);         return object;    }}

然后再配置文件里注册下:

<bean id="springUtil" class="com.hi.test.datasource.SpringUtil" />

之后再controller里:

        MyDataSource mds=(MyDataSource)SpringUtil.getObject("MyDataSource");        DruidDataSource dataSourceA=(DruidDataSource)SpringUtil.getObject("dataSourceA");        DruidDataSource dataSourceB=(DruidDataSource)SpringUtil.getObject("dataSourceB");        mds.setDruidDataSource(dataSourceA);        txTestService.insert();

但是想到这么修改MyDataSource的依赖和直接修改sqlSessionFactory的依赖有什么区别啊。。。o(╯□╰)o囧。

然后开始琢磨着怎么修改MyDataSource类。

但是想到spring里的这些bean都是单例的啊。

我要是对MyDataSource的实例变量进行修改的话,全局的配置就变了啊。即同一时刻只是连接着一个数据源。

之后想到是不是要自己去生成sqlSessionFactory之类的对象,对于不同的数据源,生成不同的这类链接对象,

让sqlSessionFactory这类对象不由spring管理,自己进行管理。

之后使用的话,根据希望操作的不同数据库,选取不同的连接对象。

但是这么做的话,似乎偏离了这套框架。

所以就没有再继续下去了。。。。

 

最后还想到,一个数据源,连着mysql,如果这个mysql是个代理的话,就像nginx代理一样,真正的tomcat之类的服务在后面。

有没有mysql的代理,真正执行sql的时候,是这个代理后面的数据库服务器执行的。

搜了搜资料,找到个Amoeba,以后有时间再研究下。