What is the most graceful way to switch Web project data sources?

Source: Internet
Author: User

As business changes/requirements change, Java EE applications are forced to connect multiple data sources for business processing.

How do you dynamically switch data sources in the most elegant/concise way without affecting the original project structure?

This article has once added the data source after the dynamic switch practice as an example, describes the whole thought and the practice process, the article if has the mistake, also looks correct.

1. Rely on Spring Dynamic Data source implementation

Spring provides an abstract routed data source object called Abstractroutingdatasource inherited from Abstractdatasource and implements the DataSource interface in the JDK.

It also means that the class that inherits Abstractroutingdatasource and rewrites it determinecurrentlookupkey methods can act as a data source and personalize multiple data source dynamic routing switching.

(If you are usually careful enough, the current open source database connection pool is implemented DataSource interface and has its own personalized encapsulation.) )

 Public class extends Abstractroutingdatasource {    @Override    protected  Object Determinecurrentlookupkey () {        return  dbcontextholder.getdbtype ();    }}

For a Web request to be understood as a separate thread, it is reasonable to hold the current data source in the threads.

 Public classDbcontextholder {Private Static FinalThreadLocal Contextholder =NewThreadlocal<>(); /*** Set Data source * *@paramDbsourceenum The name of the database enumeration to set*/     Public Static voidSetdbtype (Dbsourceenum dbsourceenum) {Contextholder.set (Dbsourceenum.getvalue ()); }    /*** Get Current data source*/     Public StaticString Getdbtype () {returnstring.valueof (Contextholder.get ()); }    /*** Clear Contextual data*/     Public Static voidCleardbtype () {contextholder.remove (); }}

Of course, for later expansion and maintenance, and the ease of use, here the data source object We introduce the enumeration type.

This allows other colleagues to programmatically use enumerations, which can be quite convenient to change, as well as some custom markers for two of data sources.

 Public enum Dbsourceenum {One    ("DataSource1"), and one    ("DataSource2")    ; Private String value;    Dbsourceenum (String value) {        this. Value = value;    }       Public String GetValue () {        return  value;    }}

The above datasource1/datasource2 is the Id of the data source object that was loaded in Spring-context.

  <   Bean  name  = "DataSource1"   class  = "Com.alibaba.druid.pool.DruidDataSource"   Init-method  = "Init"   Destroy-method  = "Close"  >          ......     </ bean  >   
    <name= "DataSource2"  class= " Com.alibaba.druid.pool.DruidDataSource "  init-method=" Init "  destroy-method  = "Close">     ... </ Bean >

Next, configure the Dynamicdatasource that inherits from Abstractroutingdatasource in the context.

   <BeanID= "DataSource"class= "Com.rambo.spm.core.multidb.DynamicDataSource">        < Propertyname= "Targetdatasources">            <MapKey-type= "Java.lang.String">                <entryKey= "DataSource1"Value-ref= "DataSource1"/>                <entryKey= "DataSource2"Value-ref= "DataSource2"/>            </Map>        </ Property>        < Propertyname= "Defaulttargetdatasource"ref= "DataSource1"/>    </Bean>

Ok to use this dynamicdatasource when configuring the subsequent DAO layer.

2. The most elegant way to switch data sources

After doing this, the dynamic switching of the data source object is already working, and is programmed in the business layer as follows.

        Dbcontextholder.setdbtype (dbsourceenum.one);        List<Menu> menulist = menuservice.selectlist (null);         Dbcontextholder.setdbtype (dbsourceenum.two);        List<User> userlist = userservice.selectlist (null);

The disadvantage is obvious, connected to the data source 2 o'clock to switch/not conducive to the expansion/switchover is not at that time to bury the thunder of the chances of a great.

When communicating with the team, we discuss a scheme that uses powerful AOP to intercept DAO layer objects and dynamically switch data sources.

For DAO layer objects, which table to access the database is deterministic, write custom annotations, and bind to the DAO layer object.

The custom data source annotations are as follows:

@Inherited @retention (retentionpolicy.runtime) @Target (elementtype.type)  public @Interface  DataSource {    default  dbsourceenum.one;}

write the slice processing object, intercept the DAO layer object before use, switch the data source conveniently, if there is no data source annotation, set as default.

So for the first data source in the original project DAO layer object, there is no need to make any modifications, the slice processing is as follows.

    @Before ("Cut ()")    publicvoid  dobefore (joinpoint joinpoint) {          = Joinpoint.gettarget (). GetClass (). Getannotation (DataSource.  Class);         null ? datasource.value (): Dbsourceenum.one);        Log.info ("Current data source is:" + Dbcontextholder.getdbtype ());    }

The intricate abstraction and inheritance of the DAO layer in most projects will make it difficult for you to intercept AOP slices, and there is always a way to think and practice more.

Well, that's it, isn't it? It's easier to extend, program, understand, and, of course, be more elegant than an AOP interception method, which is more extensible, more programmable, more understandable, and more difficult to code.

Code already hosted in: Https://git.oschina.net/LanboEx/spmvc-mybatis.git interested friends, you can check the local run.

What is the most graceful way to switch Web project data sources?

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.