【瞎折腾系列】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="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="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,以后有时间再研究下。

posted @ 2014-08-17 11:21 oh~NO! 阅读(...) 评论(...) 编辑 收藏