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 "/> < ;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 "/> < ;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);