【详解】JavaSpringMVC+MyBitis+多数据源切换
【详解】JavaSpringMVC+MyBitis+多数据源切换
在企业级应用开发中,经常需要处理来自不同数据库的数据。为了满足这一需求,我们可以通过配置多个数据源来实现对不同数据库的访问。本文将介绍如何在Spring MVC框架下结合MyBatis实现多数据源的动态切换。
1. 环境准备
- Java:1.8 或更高版本
- Spring Boot:2..0.RELEASE
- MyBatis:.5.2
- 数据库:MySQL(示例使用两个不同的数据库实例)
2. 添加依赖
首先,在pom.xml
文件中添加必要的依赖:
<dependencies>
<!-- Spring Boot Starter Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- MyBatis Spring Boot Starter -->
<dependency>
<groupId>spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
<!-- MySQL Connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Spring Boot Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
. 配置多数据源
在application.properties
文件中配置两个数据源:
# 数据源1
spring.datasource.datasource1.jdbc-url=jdbc:mysql://localhost:06/db1?useSSL=false&serverTimezone=UTC
spring.datasource.datasource1.username=root
spring.datasource.datasource1.password=password
spring.datasource.datasource1.driver-class-name=jdbc.Driver
# 数据源2
spring.datasource.datasource2.jdbc-url=jdbc:mysql://localhost:06/db2?useSSL=false&serverTimezone=UTC
spring.datasource.datasource2.username=root
spring.datasource.datasource2.password=password
spring.datasource.datasource2.driver-class-name=jdbc.Driver
4. 创建数据源配置类
创建一个配置类来管理多个数据源:
代码语言:javascript代码运行次数:0运行复制import org.apache.ibatis.session.SqlSessionFactory;
import spring.SqlSessionFactoryBean;
import spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.annotation.Bean;
import org.annotation.Configuration;
import org.annotation.Primary;
import org.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
@Configuration
@MapperScan(basePackages = "", sqlSessionFactoryRef = "sqlSessionFactory")
public class DataSourceConfig {
@Bean(name = "datasource1")
@ConfigurationProperties(prefix = "spring.datasource.datasource1")
public DataSource dataSource1() {
return ().build();
}
@Bean(name = "datasource2")
@ConfigurationProperties(prefix = "spring.datasource.datasource2")
public DataSource dataSource2() {
return ().build();
}
@Bean(name = "sqlSessionFactory")
@Primary
public SqlSessionFactory sqlSessionFactory(@Qualifier("datasource1") DataSource dataSource) throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
factoryBean.setMapperLocati(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
return factoryBean.getObject();
}
@Bean(name = "transactionManager")
@Primary
public DataSourceTransactionManager transactionManager(@Qualifier("datasource1") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
5. 动态数据源切换
为了实现动态数据源切换,我们需要创建一个动态数据源类和一个切面来管理数据源的选择:
5.1 动态数据源类
代码语言:javascript代码运行次数:0运行复制import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DynamicDataSourceContextHolder.getDataSourceKey();
}
}
5.2 数据源上下文持有者
代码语言:javascript代码运行次数:0运行复制public class DynamicDataSourceContextHolder {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
public static void setDataSourceKey(String key) {
contextHolder.set(key);
}
public static String getDataSourceKey() {
return contextHolder.get();
}
public static void clearDataSourceKey() {
contextHolder.remove();
}
}
5. 切面管理数据源选择
代码语言:javascript代码运行次数:0运行复制import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class DataSourceAspect {
@Before("@annotation(annotation.TargetDataSource)")
public void switchDataSource(JoinPoint point) {
MethodSignature signature = (MethodSignature) point.getSignature();
TargetDataSource targetDataSource = signature.getMethod().getAnnotation();
if (targetDataSource != null) {
String dataSource = targetDataSource.value();
DynamicDataSourceContextHolder.setDataSourceKey(dataSource);
}
}
}
5.4 自定义注解
代码语言:javascript代码运行次数:0运行复制import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUTIME)
@Documented
public @interface TargetDataSource {
String value();
}
6. 使用示例
假设我们有两个数据库表user
和order
分别位于db1
和db2
中,我们可以这样编写DAO层:
6.1 UserMapper
代码语言:javascript代码运行次数:0运行复制import entity.User;
import org.apache.ibatis.annotati.Select;
import org.apache.ibatis.annotati.Mapper;
@Mapper
public interface UserMapper {
@Select("SELECT * FROM user WHERE id = #{id}")
User getUserById(@Param("id") int id);
}
6.2 OrderMapper
代码语言:javascript代码运行次数:0运行复制import entity.Order;
import org.apache.ibatis.annotati.Select;
import org.apache.ibatis.annotati.Mapper;
@Mapper
public interface OrderMapper {
@Select("SELECT * FROM order WHERE id = #{id}")
Order getOrderById(@Param("id") int id);
}
6. Service层
代码语言:javascript代码运行次数:0运行复制import annotation.TargetDataSource;
import entity.User;
import entity.Order;
import .UserMapper;
import .OrderMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
@Autowired
private OrderMapper orderMapper;
@TargetDataSource("datasource1")
public User getUserById(int id) {
return userMapper.getUserById(id);
}
@TargetDataSource("datasource2")
public Order getOrderById(int id) {
return orderMapper.getOrderById(id);
}
}
通过上述步骤,我们成功地在Spring MVC项目中实现了MyBatis的多数据源动态切换。这种方法不仅提高了系统的灵活性,还使得跨数据库操作变得更加简单和高效。希望这篇文章能对你有所帮助!
以上是一个关于在Spring MVC框架下结合MyBatis实现多数据源动态切换的技术博客文章。希望对你有所帮助!当然可以!下面是一个简单的示例,展示如何在Spring MVC项目中使用MyBatis实现多数据源切换。这个例子将包括以下几个部分:
- 配置文件:定义多个数据源和对应的SQLSessionFactory。
- 自定义数据源切换策略:通过一个注解来动态选择数据源。
- Service层:使用自定义注解来指定数据源。
- Controller层:调用Service层的方法。
1. 配置文件
首先,我们需要在applicationContext.xml
中配置多个数据源和对应的SQLSessionFactory。
<beans xmlns=";
xmlns:xsi=";
xmlns:context=";
xmlns:tx=";
xsi:schemaLocation="
.xsd
.xsd
.xsd">
<!-- 数据源1 -->
<bean id="dataSource1" class="org.apachem.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassame" value="jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:06/db1"/>
<property name="username" value="user1"/>
<property name="password" value="password1"/>
</bean>
<!-- 数据源2 -->
<bean id="dataSource2" class="org.apachem.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassame" value="jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:06/db2"/>
<property name="username" value="user2"/>
<property name="password" value="password2"/>
</bean>
<!-- 动态数据源 -->
<bean id="dynamicDataSource" class="config.DynamicDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry key="dataSource1" value-ref="dataSource1"/>
<entry key="dataSource2" value-ref="dataSource2"/>
</map>
</property>
<property name="defaultTargetDataSource" ref="dataSource1"/>
</bean>
<!-- SQLSessionFactory1 -->
<bean id="sqlSessionFactory1" class="spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource1"/>
<property name="mapperLocati" value="classpath:mapper/db1/*.xml"/>
</bean>
<!-- SQLSessionFactory2 -->
<bean id="sqlSessionFactory2" class="spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource2"/>
<property name="mapperLocati" value="classpath:mapper/db2/*.xml"/>
</bean>
<!-- SqlSessionTemplate1 -->
<bean id="sqlSessionTemplate1" class="spring.SqlSessionTemplate">
<ctructor-arg index="0" ref="sqlSessionFactory1"/>
</bean>
<!-- SqlSessionTemplate2 -->
<bean id="sqlSessionTemplate2" class="spring.SqlSessionTemplate">
<ctructor-arg index="0" ref="sqlSessionFactory2"/>
</bean>
<!-- Transaction Manager -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dynamicDataSource"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- 扫描Service层 -->
<context:component-scan base-package="service"/>
</beans>
2. 自定义数据源切换策略
创建一个动态数据源类DynamicDataSource
,并定义一个注解@TargetDataSource
来指定数据源。
package config;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.getDataSource();
}
}
package config;
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUTIME)
@Documented
public @interface TargetDataSource {
String value();
}
创建一个线程本地变量DataSourceContextHolder
来保存当前的数据源。
package config;
public class DataSourceContextHolder {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
public static void setDataSource(String dataSource) {
contextHolder.set(dataSource);
}
public static String getDataSource() {
return contextHolder.get();
}
public static void clearDataSource() {
contextHolder.remove();
}
}
. Service层
在Service层中使用@TargetDataSource
注解来指定数据源。
package service;
import config.TargetDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.annotation.Transactional;
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
@Transactional
@TargetDataSource("dataSource1")
public void addUserToDB1(User user) {
userMapper.insertUser(user);
}
@Transactional
@TargetDataSource("dataSource2")
public void addUserToDB2(User user) {
userMapper.insertUser(user);
}
}
4. Controller层
在Controller层中调用Service层的方法。
代码语言:javascript代码运行次数:0运行复制package controller;
import service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@PostMapping("/db1")
public String addUserToDB1(@RequestBody User user) {
userService.addUserToDB1(user);
return "User added to DB1";
}
@PostMapping("/db2")
public String addUserToDB2(@RequestBody User user) {
userService.addUserToDB2(user);
return "User added to DB2";
}
}
5. Mapper接口和XML文件
定义Mapper接口和对应的XML文件。
代码语言:javascript代码运行次数:0运行复制package ;
import entity.User;
import org.apache.ibatis.annotati.Insert;
import org.apache.ibatis.annotati.Mapper;
@Mapper
public interface UserMapper {
@Insert("ISERT ITO users (name, email) VALUES (#{name}, #{email})")
void insertUser(User user);
}
在src/main/resources/mapper/db1/UserMapper.xml
和src/main/resources/mapper/db2/UserMapper.xml
中定义SQL映射。
<!-- src/main/resources/mapper/db1/UserMapper.xml -->
<mapper namespace=".UserMapper">
<insert id="insertUser" parameterType="entity.User">
ISERT ITO users (name, email) VALUES (#{name}, #{email})
</insert>
</mapper>
<!-- src/main/resources/mapper/db2/UserMapper.xml -->
<mapper namespace=".UserMapper">
<insert id="insertUser" parameterType="entity.User">
ISERT ITO users (name, email) VALUES (#{name}, #{email})
</insert>
</mapper>
6. 实体类
定义一个简单的实体类User
。
package entity;
public class User {
private String name;
private String email;
// Getters and Setters
}
以上代码展示了如何在Spring MVC项目中使用MyBatis实现多数据源切换。通过自定义注解和动态数据源类,可以在运行时根据需要切换不同的数据源。希望这个示例对你有帮助!如果有任何问题或需要进一步的帮助,请随时告诉我。在Java项目中使用Spring MVC框架结合MyBatis进行开发时,如果需要处理多个数据库的数据源切换,可以通过配置Spring的AbstractRoutingDataSource
来实现。以下是一个详细的步骤和示例代码,展示如何在一个Spring MVC + MyBatis项目中实现多数据源切换。
1. 添加依赖
首先,在你的pom.xml
文件中添加Spring、MyBatis及相关依赖:
<dependencies>
<!-- Spring MVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5..10</version>
</dependency>
<!-- MyBatis -->
<dependency>
<groupId>spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<!-- MySQL Connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.2</version>
</dependency>
<!-- HikariCP Connection Pool -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>4.0.</version>
</dependency>
</dependencies>
2. 配置数据源
创建一个配置类来定义多个数据源,并通过AbstractRoutingDataSource
实现数据源的动态切换。
import org.apache.ibatis.session.SqlSessionFactory;
import spring.SqlSessionFactoryBean;
import spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.annotation.Bean;
import org.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
@Configuration
@MapperScan("")
public class DataSourceConfig {
@Bean
public DataSource dataSource() {
DynamicDataSource dynamicDataSource = new DynamicDataSource();
Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put("dataSource1", dataSource1());
targetDataSources.put("dataSource2", dataSource2());
dynamicDataSource.setTargetDataSources(targetDataSources);
dynamicDataSource.setDefaultTargetDataSource(dataSource1());
return dynamicDataSource;
}
@Bean
public DataSource dataSource1() {
HikariDataSource dataSource = new HikariDataSource();
dataSource.setDriverClassame("jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:06/db1");
dataSource.setUsername("root");
dataSource.setPassword("password");
return dataSource;
}
@Bean
public DataSource dataSource2() {
HikariDataSource dataSource = new HikariDataSource();
dataSource.setDriverClassame("jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:06/db2");
dataSource.setUsername("root");
dataSource.setPassword("password");
return dataSource;
}
@Bean
public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
return factoryBean.getObject();
}
@Bean
public DataSourceTransactionManager transactionManager(@Qualifier("dataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
. 实现动态数据源切换
创建一个继承自AbstractRoutingDataSource
的类来管理数据源的切换逻辑。
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.getDataSourceKey();
}
}
4. 数据源上下文管理
创建一个线程安全的上下文管理器来保存当前线程使用的数据源键。
代码语言:javascript代码运行次数:0运行复制public class DataSourceContextHolder {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
public static void setDataSourceKey(String key) {
contextHolder.set(key);
}
public static String getDataSourceKey() {
return contextHolder.get();
}
public static void clearDataSourceKey() {
contextHolder.remove();
}
}
5. 切换数据源
在需要切换数据源的地方,调用DataSourceContextHolder
的方法来设置当前线程使用的数据源。
@RestController
public class UserController {
@Autowired
private UserMapper userMapper;
@GetMapping("/users1")
public List<User> getUsersFromDataSource1() {
DataSourceContextHolder.setDataSourceKey("dataSource1");
List<User> users = userMapper.selectAll();
();
return users;
}
@GetMapping("/users2")
public List<User> getUsersFromDataSource2() {
DataSourceContextHolder.setDataSourceKey("dataSource2");
List<User> users = userMapper.selectAll();
();
return users;
}
}
6. Mapper接口
定义MyBatis的Mapper接口,用于访问数据库。
代码语言:javascript代码运行次数:0运行复制public interface UserMapper {
List<User> selectAll();
}
7. XML映射文件
在resources/mapper
目录下创建XML映射文件,例如UserMapper.xml
。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis//DTD Mapper .0//E" ".dtd">
<mapper namespace=".UserMapper">
<select id="selectAll" resultType="model.User">
SELECT * FROM user
</select>
</mapper>
以上步骤展示了如何在Spring MVC + MyBatis项目中实现多数据源切换。通过这种方式,你可以在不同的请求或业务逻辑中灵活地切换数据源。
#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格
推荐阅读
留言与评论(共有 12 条评论) |
本站网友 大鸭梨团购 | 8分钟前 发表 |
本站网友 宫颈癌治疗 | 0秒前 发表 |
sqlSessionFactoryRef = "sqlSessionFactory") public class DataSourceConfig { @Bean(name = "datasource1") @ConfigurationProperties(prefix = "spring.datasource.datasource1") public DataSource dataSource1() { return ().build(); } @Bean(name = "datasource2") @ConfigurationProperties(prefix = "spring.datasource.datasource2") public DataSource dataSource2() { return ().build(); } @Bean(name = "sqlSessionFactory") @Primary public SqlSessionFactory sqlSessionFactory(@Qualifier("datasource1") DataSource dataSource) throws Exception { SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean(); factoryBean.setDataSource(dataSource); factoryBean.setMapperLocati(new PathMatchingResourcePatternResolver().getResources("classpath | |
本站网友 美胸是什么 | 10分钟前 发表 |
mapper/*.xml")); return factoryBean.getObject(); } @Bean(name = "transactionManager") @Primary public DataSourceTransactionManager transactionManager(@Qualifier("datasource1") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } }5. 动态数据源切换为了实现动态数据源切换 | |
本站网友 宜阳二手房 | 11分钟前 发表 |
我们成功地在Spring MVC项目中实现了MyBatis的多数据源动态切换 | |
本站网友 浑浑噩噩什么意思 | 21分钟前 发表 |
代码语言:javascript代码运行次数:0运行复制package controller; import service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/users") public class UserController { @Autowired private UserService userService; @PostMapping("/db1") public String addUserToDB1(@RequestBody User user) { userService.addUserToDB1(user); return "User added to DB1"; } @PostMapping("/db2") public String addUserToDB2(@RequestBody User user) { userService.addUserToDB2(user); return "User added to DB2"; } }5. Mapper接口和XML文件定义Mapper接口和对应的XML文件 | |
本站网友 上海杨雄 | 11分钟前 发表 |
代码语言:javascript代码运行次数:0运行复制@RestController public class UserController { @Autowired private UserMapper userMapper; @GetMapping("/users1") public List<User> getUsersFromDataSource1() { DataSourceContextHolder.setDataSourceKey("dataSource1"); List<User> users = userMapper.selectAll(); (); return users; } @GetMapping("/users2") public List<User> getUsersFromDataSource2() { DataSourceContextHolder.setDataSourceKey("dataSource2"); List<User> users = userMapper.selectAll(); (); return users; } }6. Mapper接口定义MyBatis的Mapper接口 | |
本站网友 开核是什么意思 | 2分钟前 发表 |
email) VALUES (#{name} | |
本站网友 大连医大 | 6分钟前 发表 |
代码语言:javascript代码运行次数:0运行复制package config; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; public class DynamicDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return DataSourceContextHolder.getDataSource(); } } package config; import java.lang.annotation.*; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUTIME) @Documented public @interface TargetDataSource { String value(); }创建一个线程本地变量DataSourceContextHolder来保存当前的数据源 | |
本站网友 军华软件 | 20分钟前 发表 |
本站网友 40628 | 17分钟前 发表 |
mapper/db2/*.xml"/> </bean> <!-- SqlSessionTemplate1 --> <bean id="sqlSessionTemplate1" class="spring.SqlSessionTemplate"> <ctructor-arg index="0" ref="sqlSessionFactory1"/> </bean> <!-- SqlSessionTemplate2 --> <bean id="sqlSessionTemplate2" class="spring.SqlSessionTemplate"> <ctructor-arg index="0" ref="sqlSessionFactory2"/> </bean> <!-- Transaction Manager --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dynamicDataSource"/> </bean> <tx | |
本站网友 建材价格查询 | 29分钟前 发表 |
用于访问数据库 |