Read and write separation based on spring AOP method

Source: Internet
Author: User


Why do I need read and write separation

As the business of the website expands continuously, the data increases unceasingly, the user is more and more, the pressure of the database is more and more big, uses the traditional way, for example: the database or the SQL optimization basically has not reached the request, this time may adopt the reading and writing separation strategy to change the present situation. The use of read-write separation technology can effectively reduce the pressure of Master library, but also can be the user query data requests distributed to different slave library, thus ensuring the robustness of the system. second, the two commonly used methods 1, define two database links.

One is Masterdatasource, the other is Slavedatasource, when the data is updated to read Masterdatasource, the query is read slavedatasource. 2, Dynamic Data source switching.

When the program runs, the data source is dynamically woven into the program to select the main library or the library. The main technology uses annotation,spring AOP, reflection, followed by detailed introduction of the method. iii. Dynamic Data source switching for read and write separation 1, mybatis Query and updated annotations distinguish between read and write

Package org.apache.ibatis.annotations;
 
Import java.lang.annotation.Annotation;
Import java.lang.annotation.Retention;
Import Java.lang.annotation.RetentionPolicy;
Import Java.lang.annotation.Target;
 
@Retention (retentionpolicy.runtime)
@Target ({Java.lang.annotation.ElementType.METHOD}) public
@ Interface Select {public
	abstract string[] Value ();
}

Package org.apache.ibatis.annotations;
 
Import java.lang.annotation.Annotation;
Import java.lang.annotation.Retention;
Import Java.lang.annotation.RetentionPolicy;
Import Java.lang.annotation.Target;
 
@Retention (retentionpolicy.runtime)
@Target ({Java.lang.annotation.ElementType.METHOD}) public
@ Interface Update {public
	abstract string[] Value ();
}

You can also customize the annotations to identify the required read and write data sources, as follows:

Package com.javagaozhi.db;
 
Import Java.lang.annotation.ElementType;
Import java.lang.annotation.Retention;
Import Java.lang.annotation.RetentionPolicy;
Import Java.lang.annotation.Target;
 
/**
 * Custom recognition read/write data source annotations
 *
 * @author Administrator * * * */
@Retention (retentionpolicy.runtime)
@Target (elementtype.method) public
@interface DataSource {
	String value ();
}

2, Inherit abstract class Abstractroutingdatasource to implement Dynamicdatasource method

Import Org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
Import org.springframework.stereotype.Component;
 
/** *
 Multi-data source management
 *
 * @author Administrator * * */@Component public
class Multipledatasource Extends Abstractroutingdatasource {
	private static final threadlocal<string> Datasourcekey = new Inheritablethreadlocal<string> ();
 
	/**
	 * Set data source
	 *
	 * @param dataSource
	 *
	/public static void Setdatasourcekey (String dataSource) {
    	Datasourcekey.set (DataSource);
	}
 
	/**
	 * Returns the current data source *
	/@Override protected Object Determinecurrentlookupkey () {
    	return Datasourcekey.get ();
	}
}
3. Define slice datasourceaspect, switch read/write data source
Import Java.lang.reflect.Method;
Import Org.apache.ibatis.annotations.Select;
Import Org.apache.ibatis.annotations.Update;
Import Org.aspectj.lang.ProceedingJoinPoint;
Import Org.aspectj.lang.annotation.Around;
Import Org.aspectj.lang.annotation.Aspect;
Import Org.aspectj.lang.reflect.MethodSignature;
 
Import org.springframework.stereotype.Component; /** * Defines the data source slice, dynamically switches the data source while the program is running * * @author Administrator */@Aspect @Component public class Datasourceaspect {@Around
	("Execution (* com.javagaozhi.dao.*.* (..))")
    	Public Object before (Proceedingjoinpoint point) throws Throwable {Object target = Point.gettarget ();
    	String method = Point.getsignature (). GetName ();
    	class<?>[] Classz = Target.getclass (). Getinterfaces ();
    	Class<?>[] Parametertypes = ((methodsignature) point.getsignature ()). GetMethod (). Getparametertypes ();
        Method M = Classz[0].getmethod (method, parametertypes); Select the corresponding data source according to the annotation type, select Choose Read Data source, update select Write data source if (null! = M &&
    	M.isannotationpresent (Select.class)) {Multipledatasource.setdatasourcekey ("Datasource-slave"); } else if (null! = M && m.isannotationpresent (Update.class)) {Multipledatasource.setdatasourcekey ("DataS
    	Ource-master ");
    	} else {return null;
	} return Point.proceed (); }
}

4. Applicationcontext-datasource.xml Configuration
<!--data source 1--> <bean id= "Datasource-master" class= "Org.apache.tomcat.jdbc.pool.DataSource" destroy-method= "C  
        	Lose "> <property name=" poolproperties "> <bean class=" org.apache.tomcat.jdbc.pool.PoolProperties "> <property name= "Driverclassname" value= "Com.mysql.jdbc.Driver"/> <property name= "url" value= "J Dbc:mysql://localhost:3306/test?useunicode=true&characterencoding=utf8&allowmultiqueries=true "/> &lt ;p roperty name= "username" value= "root"/> <property name= "password" value= "root"/> <propert Y name= "jmxenabled" value= "true"/> <property name= "Testwhileidle" value= "true"/> <property n Ame= "Testonborrow" value= "true"/> <property name= "Testonreturn" value= "false"/> <propert  
        	Y name= "Validationinterval" value= "30000"/> <property name= "validationquery" value= "Select 1"/> <property name= "TImebetweenevictionrunsmillis "value=" 30000 "/> <property name=" maxactive "value="/> "< Property Name= "InitialSize" value= "1"/> <property name= "maxwait" value= "10000"/> <proper  
        	Ty name= "Minevictableidletimemillis" value= "30000"/> <property name= "minidle" value= "/>"  
        	<property name= "logabandoned" value= "false"/> <property name= "removeabandoned" value= "true"/> <property name= "removeabandonedtimeout" value= "/> <property name=" jdbcinterceptors "value=" org. Apache.tomcat.jdbc.pool.interceptor.connectionstate;org.apache.tomcat.jdbc.pool.interceptor.statementfinalizer  "/> </bean> </property> </bean> <!--data source 2--> <bean id=" Datasource-slave "
    	class= "Org.apache.tomcat.jdbc.pool.DataSource" destroy-method= "Close" > <property name= "poolproperties" > <bean class= "Org.apache.tomcat.jdBc.pool.PoolProperties "> <property name=" driverclassname "value=" Com.mysql.jdbc.Driver "/> &lt ;p roperty name= "url" value= "Jdbc:mysql://localhost:3306/test_read?useunicode=true&characterencoding=utf8 &allowmultiqueries=true "/> <property name=" username "value=" root "/> <property name=" Password "value=" root "/> <property name=" jmxenabled "value=" true "/> <property name=" Testwhil Eidle "value=" true "/> <property name=" Testonborrow "value=" true "/> <property name=" Testonr Eturn "value=" false "/> <property name=" Validationinterval "value=" 30000 "/> <property nam  
        	E= "Validationquery" value= "Select 1"/> <property name= "Timebetweenevictionrunsmillis" value= "30000"/>  
        	<property name= "maxactive" value= "/>" <property "name=" 1 initialsize <property name= "maxwait" value= "10000"/> <property name= "Minevictableidletimemillis" value= "30000"/> <property name= "m Inidle "value=" "/> <property name=" logabandoned "value=" false "/> <property name=" Remov Eabandoned "value=" true "/> <property name=" removeabandonedtimeout "value="/> <property Name= "Jdbcinterceptors" value= "Org.apache.tomcat.jdbc.pool.interceptor.connectionstate;o
 
Rg.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer "/> </bean> </property> </bean> <bean id= "Multipledatasource" class= "Com.alifi.uums.db.MultipleDataSource" > <property name= " 
        	Defaulttargetdatasource "ref=" Datasource-master "/> <property name=" targetdatasources "> <map> <entry key= "Datasource-master" value-ref= "Datasource-master"/> <entry key= "DataSource-slave" value- ref= "Datasource-slave"/> </map> </property> </bean> <bean class= "Org.mybatis.spring.SqlSessionFactoryBean" id= "sqlsessionfactory" > <property name= " DataSource "ref=" Multipledatasource "/> <property value=" Classpath:system-mybatis-conf.xml "Name=" Configlocation "/> </bean>
5. The DAO layer directly uses annotations Select, update operation database
/**
 * Find user by ID
 *
 * @param user
 * @return User
 *
/@Select ("select * from Piao_user where id= #{id} ")
User GetUser (String ID);

/**
 * Update user Information
 *
 * @param users
 * @return User
 *
/@Update ("Update from  Piao_user set Nickname= ' Zhang San ' where Id= #{id} ")
User GetUser (String ID);




Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.