Here, we take an article that uses Jndi to access the two data sources configured by the application server to simulate simultaneous operation of different databases such as MySQL and Oracle. In fact, the last example may be used to simulate the MySQL database master-slave configuration read and write separation more appropriate. So, in this case, we're going to complete the configuration instance of the read-write separation simulation on the web side.
Last example, the configuration of the Jndi data source and the configuration of the spring datasource are not repeated here. The following focuses on the implementation of the DAO layer dynamic library call. Can see the article "Spring Learning Note (18) using Jndi impersonation to access the application Server multi-data source instance"
1. DAO Layer Design
/*************** Interface Design ************/ Public interface Mybasedao {Sessionfactory getsessionfactory (); <E> E Add (Object object); <e>e Queryunique (class<e> clazz, Integer EntityId);voidSetsourcetype (Integer sourcetype);}/**************** Implementation class design ******************/@Repository Public class Mybasedaoimpl implements Mybasedao{ //Because this class is a singleton, taking into account thread safety issues, this is the basis for using threadlocal as a judge of which data source to invoke PrivateThreadlocal<integer> sourcetype =NewThreadlocal<integer> ();@Autowired @Qualifier("Sessionfactory")PrivateSessionfactory sessionfactory;@Autowired @Qualifier("SessionFactory2")PrivateSessionfactory SessionFactory2;@Override PublicSessionfactorygetsessionfactory() {if(Sourcetype.get () = =NULL){//If there is no value, the data source is used by default 1Sourcetype.set (1); }Switch(Sourcetype.get ()) { Case 1://Using Data source 1, in this case the main library, which is primarily responsible for writing returnSessionfactory; Case 2://Using Data source 2, in this case from the library, which is primarily responsible for reading returnSessionFactory2;default:Throw NewIllegalArgumentException ("Unknown sourcetype"); } }@Override//Simulate a write operation to have the main library data source call Public<E> EAdd(Object object) {return(E) Getsessionfactory (). Opensession (). Save (object); }@Override//Simulates a read operation to make calls from the library data source Public<E> EQueryunique(class<e> clazz, Integer EntityId) {return(E) Getsessionfactory (). Opensession (). Get (Clazz, EntityId); }@Override//Common AOP Enhanced class modify data source Type Public void Setsourcetype(Integer sourcetype) { This. Sourcetype.set (SourceType); }}
2. AOP Class Design
@Aspect Public class datasourceselector {//using pre-enhancement @Before("Execution (* com.yc.dao.mybasedaoimpl.add* (..))")//write Operation Public void Before1(Joinpoint joinpoint) {((Mybasedao) Joinpoint.gettarget ()). Setsourcetype (1);//Switch to the main library}@Before("Execution (* com.yc.dao.mybasedaoimpl.query* (..))")//Read operation Public void Before2(Joinpoint joinpoint) {((Mybasedao) Joinpoint.gettarget ()). Setsourcetype (2);//Switch to from library}}
For an AOP configuration tutorial, you can refer to the article in the previous AOP section of this series. Then we also need to register our facets in the IOC container.
<aop:aspectj-autoproxy /> <!-- 使@AspectJ注解生效 --><bean class="com.yc.aop.DataSourceSelector" /><!-- 注册切面 -->
3. Modifying the Controller
For the controller of the previous article, make the following modifications:
@Controller Public class jnditestcontroller { @Autowired PrivateMybasedao Mybasedao;@RequestMapping("Testjndi")@ResponseBody PublicObjectTestjndi() {User user =NewUser (); User.setname ("NEW_USER_FRON_YC1"); Integer newId = mybasedao.add (user); System.out.println ("New UserId ="+ newId);//Get our newly inserted IDSystem.out.println ("is new User here?"+ Mybasedao.queryunique (Com.yc.model2.User.class, newId));returnNewId; }}
4. Test and result analysis
Run the server and enter it in the browser and http://localhost:8090/yc/testJNDI
we'll see the console print information:
New UserId = 4
Is new User here? Null
Newuserid is the one we inserted into the main library, with an ID of 4.
But we read it immediately, but we didn't read it. This means that the database we have stored is not the same as the one we read, which simply implements the read and write separation. In order to verify this, we have shown the database as shown, obviously we have stored our test data in yc1, not in YC2!
Spring Learning Note (*) MySQL read-write separation backend AOP control instance