首页 > 代码库 > spring hibernate配置切换数据源,实现读写分离

spring hibernate配置切换数据源,实现读写分离

spring的配置如下

 <!-- 主数据源-->  
    <bean id="masterDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">  
        <property name="driverClassName" value=http://www.mamicode.com/"com.mysql.jdbc.Driver" />>


这里需要三个类配合  

DynamicDataSource  <pre name="code" class="html">DataSourceAdvice
<pre name="code" class="html">DataSourceSwitcher 




c.p.aop.DynamicDataSource.java如下:
public  class DynamicDataSource extends AbstractRoutingDataSource {  
  
    @Override  
    protected Object determineCurrentLookupKey() {  
        return DataSourceSwitcher.getDataSource();  
    }

	public Logger getParentLogger() {
		// TODO Auto-generated method stub
		return null;
	}

	public <T> T unwrap(Class<T> iface,String m) throws SQLException {
		// TODO Auto-generated method stub
		return null;
	}

	public boolean isWrapperFor(Class<?> iface,String m) throws SQLException {
		// TODO Auto-generated method stub
		return false;
	}  
  
}  

c.p.aop.DataSourceAdvice.java,配置如下public class DataSourceAdvice implements MethodBeforeAdvice, AfterReturningAdvice, ThrowsAdvice {      // service方法执行之前被调用      public void before(Method method, Object[] args, Object target) throws Throwable {          System.out.println("切入点: " + target.getClass().getName() + "类中" + method.getName() + "方法");          if(method.getName().startsWith("add")               || method.getName().startsWith("add")              || method.getName().startsWith("update")              || method.getName().startsWith("delete")){              System.out.println("切换到: master");              DataSourceSwitcher.setMaster();                      }          else  {              System.out.println("切换到: slave");              DataSourceSwitcher.setSlave();          }      }        // service方法执行完之后被调用      public void afterReturning(Object arg0, Method method, Object[] args, Object target) throws Throwable {      }        // 抛出Exception之后被调用      public void afterThrowing(Method method, Object[] args, Object target, Exception ex) throws Throwable {          DataSourceSwitcher.setSlave();          System.out.println("出现异常,切换到: slave");      }    }<pre name="code" class="html">DataSourceSwitcher.java代码如下public class DataSourceSwitcher {      @SuppressWarnings("rawtypes")      private static final ThreadLocal contextHolder = new ThreadLocal();        @SuppressWarnings("unchecked")      public static void setDataSource(String dataSource) {          Assert.notNull(dataSource, "dataSource cannot be null");          contextHolder.set(dataSource);      }        public static void setMaster(){          clearDataSource();      }            public static void setSlave() {          setDataSource("slave");      }            public static String getDataSource() {          return (String) contextHolder.get();      }        public static void clearDataSource() {          contextHolder.remove();      }  }

配置好这些虽然可以实现读写分离,但是有一个问题是,当插入数据的时候,程序会把数据插入到主数据库里面,这时从数据库没有这条插入的数据,这样造成数据不同步,mysql有方法可以实现从数据库同步主数据库的方法。

我们可以按照以下步骤实现

1.配置主数据库的my.ini文件,在最后面加入

#---------------------------------------------

server-id=242

log-bin=mysql-bin

relay-log=relay-bin

relay-log-index=relay-bin-index

replicate-do-db=要同步的数据库

#---------------------------------------------

重启mysql服务。


2.从数据库也配置对应的my.ini文件

#---------------------------------------------

server-id=243

log-bin=mysql-bin

relay-log=relay-bin

relay-log-index=relay-bin-index

replicate-do-db=要同步的数据库

#---------------------------------------------

重启mysql服务。


3.配置从数据库的同步

从数据库敲打以下命令

服务242上用MySQL命令行工具执行如下语句:

mysql> stop slave;

mysql> change master to master_host=‘主数据库ip‘,master_user=‘root‘,master_password=‘abcd‘;

mysql> start slave;

mysql> show slave status\G;

这样就可以实现同步的问题了。


spring hibernate配置切换数据源,实现读写分离