SSH多个数据源动态数据切换
数据库的结转,为了提高数据记录的查询速度,我们需要将一些数据量比较大的表结构数据清空,但也要保证可以查询到清空之前(即上一年)的数据信息,这里我们采取的方案是,动态连接两个数据库,通过登录时年份的选择来判断连接哪个数据库(例如,登录时选择2017即可连接2017的数据库,查询2017年的记录明细)。
一般情况下我们在spring配置中只配置一个dataSource来连接数据库,然后在SessionFactory中绑定dataSource。如果有需要连接多个数据库时的正确做法是:
具体实现步骤如下:
1、配置文件:applicationContext.xml
(1)、第一个数据源 <bean id="dataSource1" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="com.mysql.jdbc.Driver" /> <property name="jdbcUrl" value="jdbc:mysql://192.168.1.80:3306/db_medicine" /> <property name="user" value="root" /> <property name="password" value="sunland" /> <property name="minPoolSize" value="5" /> <property name="maxPoolSize" value="500" /> <property name="unreturnedConnectionTimeout" value="600" /> <property name="initialPoolSize" value="3" /> <property name="maxIdleTime" value="10" /> <property name="acquireIncrement" value="3" /> <property name="maxStatements" value="0" /> <property name="idleConnectionTestPeriod" value="60" /> <property name="acquireRetryAttempts" value="30" /> <property name="breakAfterAcquireFailure" value="false" /> <property name="testConnectionOnCheckout" value="false" /> </bean> (2)、第二个数据源 <bean id="dataSource2" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="com.mysql.jdbc.Driver" /> <property name="jdbcUrl" value="jdbc:mysql://localhost/db_medicine" /> <property name="user" value="root" /> <property name="password" value="sunland" /> <property name="minPoolSize" value="5" /> <property name="maxPoolSize" value="500" /> <property name="unreturnedConnectionTimeout" value="600" /> <property name="initialPoolSize" value="3" /> <property name="maxIdleTime" value="10" /> <property name="acquireIncrement" value="3" /> <property name="maxStatements" value="0" /> <property name="idleConnectionTestPeriod" value="60" /> <property name="acquireRetryAttempts" value="30" /> <property name="breakAfterAcquireFailure" value="false" /> <property name="testConnectionOnCheckout" value="false" /> </bean> (3)、动态切换配置 <bean id="dataSource" class="com.sunland.util.DynamicDataSource"> <property name="targetDataSources"> <map key-type="java.lang.String"> <entry value-ref="dataSource1" key="dataSource1"></entry> <entry value-ref="dataSource2" key="dataSource2"></entry> </map> </property> <property name="defaultTargetDataSource" ref="dataSource1"> </property> </bean> <!-- 配置hibernate session工厂 --> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.connection.useUnicode">true</prop> <prop key="hibernate.connection.characterEncoding">UTF-8</prop> <prop key="hibernate.connection.autocommit">true</prop> <prop key="hibernate.format_sql">true</prop> <prop key="hibernate.jdbc.batch_size">100</prop> </props> </property> <!-- 自动扫描注解方式配置的hibernate类文件 --> ------ </bean> |
2、AbstractRoutingDataSource实现类,实现数据源路由选择
public class DynamicDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return CustomerContextHolder.getCustomerType(); } } |
3、DatabaseContextHolder, 用来保存当前应该使用的数据源名称
public class CustomerContextHolder { public static final String DATA_SOURCE_A = "dataSource1"; public static final String DATA_SOURCE_B = "dataSource2"; private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>(); public static void setCustomerType(String customerType) { contextHolder.set(customerType); } public static String getCustomerType() { return contextHolder.get(); } public static void clearCustomerType() { contextHolder.remove(); } } |
4、数据源的切换
String years = this.getParameter("years");//获取页面传递参数 if(years.equals("2017")){//根据年份的选择来选择数据库连接信息 CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_B); }else{ CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_A); } |
5、login.jsp新加年度的选择
<!-- 新加登录时选择年份选择框 --> <div style="float: left;"> <input type="hidden" value="2018" name="years" id="txtYears"> <select id="years" name ="years1" style="padding-top:0px; width:80px;height:20px;" > <option value="2018">2018</option> <option value="2017">2017</option> </select> </div>
//from表单请求时,post提交获取不到select的值,这里通过input取值实现 $("#years").change(function(){ $("#txtYears").val($(this).val()); }); |