Spring Boot combined with Mybatis to solve multiple data source problems

Source: Internet
Author: User
Tags aop log4j

Recently in the study of spring Cloud to build a micro-service related, for a large system, need to split into multiple microservices, each service equivalent to a module, responsible for different things, and of course, the database also need to remain relatively independent, so that need to involve multiple databases, then, How do I configure a multiple data source using spring boot?

First, we need a custom annotation named: DataSource

@Retention (Retentionpolicy.runtime)//define the annotation at run-time level
@Target (Elementtype.method)//apply this annotation to a method
Public @interface DataSource {

String value () default "user";
}
Then create the class for the data source: Dynamicdatasourceholder
public class Dynamicdatasourceholder {

/**
* default data source
*
*/
public static final String Default_datasource = "user";

public static final Threadlocal<string> holder = new threadlocal<string> ();

public static void Setdatasource (String name) {
Holder.set (name);
}

public static String Getdatasouce () {
return Holder.get ();
}

public static void Cleardatasouce () {
Holder.remove ();
}

}

To configure a Dynamic Data source class: Dynamicdatasource

public class Dynamicdatasource extends Abstractroutingdatasource {

@Override
Protected Object Determinecurrentlookupkey () {
return Dynamicdatasourceholder.getdatasouce ();
}

}

@Configuration
@PropertySource ("Classpath:jdbc.properties")
@MapperScan (basepackages ={"Com.drive.dbuser.dao"}, Sqlsessionfactoryref = "sqlsessionfactory")   // Configuring the location of the mapper action
public class Mybatisconfig {

@Bean (name = "User")
@ConfigurationProperties (prefix = "user")
Public DataSource Datasourceuser () {
Return Datasourcebuilder.create (). build ();
} //Generate user data source

@Bean (name = "Drive")
@ConfigurationProperties (prefix = "drive")
Public DataSource datasourcedrive () {
Return Datasourcebuilder.create (). build ();
} //Generate drive data source


@Bean (name = "Order")
@ConfigurationProperties (prefix = "order")
Public DataSource Datasourceorder () {
Return Datasourcebuilder.create (). build ();
}//Generate order data source

@Bean (name = "Dynamicdatasource")
Public DataSource DataSource () {
Dynamicdatasource Dynamicdatasource = new Dynamicdatasource ();
Default data Source---User
Dynamicdatasource.setdefaulttargetdatasource (Datasourceuser ());
Configuring multiple data sources
Map<object, object> datasourcemap = new HashMap (5);
Datasourcemap.put ("User", Datasourceuser ());
Datasourcemap.put ("Drive", datasourcedrive ());
Datasourcemap.put ("Order", Datasourceorder ());
Dynamicdatasource.settargetdatasources (DATASOURCEMAP);
return dynamicdatasource;
}//Configure multiple data sources

@Bean
Public Sqlsessionfactory Sqlsessionfactory () throws Exception {
Sqlsessionfactorybean Factorybean = new Sqlsessionfactorybean ();
Factorybean.setdatasource (DataSource ()); //
Add an XML directory
Resourcepatternresolver resolver = new Pathmatchingresourcepatternresolver ();
try {
Factorybean.setmapperlocations (Resolver.getresources ("Classpath*:com/drive/dbuser/mapper/*.xml")); Location in effect
return Factorybean.getobject ();
} catch (Exception e) {
E.printstacktrace ();
throw new RuntimeException (e);
}
}//Creating a session Factory
/* @Bean
Public Sqlsessiontemplate sqlsessiontemplate () throws Exception {//sqlsessiontemplate is the core of mybatis-spring. This class is responsible for managing MyBatis's sqlsession, calling MyBatis's SQL method
Sqlsessiontemplate template = new Sqlsessiontemplate (Sqlsessionfactory ()); Use the factory configured above
return template;
}*/
}

Let's take a look at Jdbc.properties configuration file information:
#用户服务库
user.url=jdbc:mysql:***
user.username=***
user.password=***
#打车服务库
Drive.url=
Drive.username=
drive.password=
#订单服务库
Order.url=
Order.username=
Order.password=1

User.driverclassname=com.mysql.jdbc.driver
Drive.driverclassname=com.mysql.jdbc.driver
Order.driverclassname=com.mysql.jdbc.driver



So that our multi-data source is configured, then how to invoke it, for example, I need to go to the user database to check the data, and then go to the drive database to add data, so how to dynamically change the data source?
We can use one of the core AOP in spring, first we need to open AOP in the Application.properties file
Spring.aop.auto=true
#开启AOP

Then create the Datasourceaspect class,
@Aspect
@Component
public class Datasourceaspect {

@Pointcut ("Execution (* com.drive.dbuser.dao.*.* (..))")
public void Declarejointpointexpression () {
}

@Before ("Declarejointpointexpression ()")
public void Beforeswitchds (Joinpoint point) {
Get the current Access class
class<?>[] ClassName = Point.gettarget (). GetClass (). Getinterfaces ();
Get access to the method name
String methodName = Point.getsignature (). GetName ();
The type of the parameter that gets the method
Class[] Argclass = ((methodsignature) point.getsignature ()). Getparametertypes ();
String DataSource = Dynamicdatasourceholder.default_datasource;
try {
Method object to get access to
method = Classname[0].getmethod (MethodName, Argclass);
Determine if @datasource annotations exist
if (Method.isannotationpresent (Datasource.class)) {
DataSource annotation = method.getannotation (Datasource.class);
Remove the data source name from the annotation
DataSource = Annotation.value ();
}
} catch (Exception e) {
E.printstacktrace ();
}
Toggle Data Source
Dynamicdatasourceholder.setdatasource (DataSource);
}


@After ("Declarejointpointexpression ()")
public void Afterswitchds (Joinpoint point) {
Dynamicdatasourceholder.cleardatasouce ();
}

}

At this point, let's look at the content of the DAO Layer:
@DataSource ("User")
List<customervo> Selectcustomer (Customervo Customervo);

We create a slice class, and when we call the DAO layer, we first look at the annotations on the method on the mapper interface and inject it as a data source into the dynamicdatasourceholder so that we can dynamically switch the data source.

Finally, we need to add a
@EnableAutoConfiguration (exclude = {Datasourceautoconfiguration.class})//Avoid loading unnecessary automation configurations by disabling the specified automation configuration
@EnableConfigurationProperties //annotations are used to turn on support for the @configurationproperties annotation configuration bean, which tells the spring Boot Enable support @configurationproperties: Annotations are primarily used to convert the properties configuration file to a bean

Of course, don't forget to configure the required dependencies in Pom.xml:

 <dependency> 
<groupid>org.springframework.boot</groupid>
<artifactId> Spring-boot-starter-web</artifactid>
</dependency>

<dependency>
<groupId> Org.springframework.boot</groupid>
<artifactid>spring-boot-starter-aop</artifactid>
</dependency>



<!--Spring Boot Mybatis dependent-->
<dependency>
<groupId> Org.mybatis.spring.boot</groupid>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>

<!--MySQL Connection driver dependent--
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.9</version>
</dependency>

<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.7.4</version>
</dependency>

<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.12</version>
</dependency>

<!--log4j-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>

Well, it's done, my favorite friends remember to pay attention to me!





Spring Boot combined with Mybatis to solve multiple data source problems

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.