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