SpringBoot 通过 Druid 多数据源集成 MyBatis-Plus
需要引入 maven 包:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.4</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
Druid 注解多数据源
配置文件
spring.datasource.first.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.first.jdbc-url=jdbc:mysql://127.0.0.1:3306/vuedb?serverTimezone=UTC
spring.datasource.first.username=xxx
spring.datasource.first.password=xxx
spring.datasource.second.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.second.jdbc-url=jdbc:mysql://127.0.0.1:3306/test?serverTimezone=UTC
spring.datasource.second.username=xxx
spring.datasource.second.password=xxx
mybatis.mapper-location=classpath*:mapper/*.xml
数据源配置
数据源通用方法 AbstractDatasource:
import com.alibaba.druid.pool.DruidDataSource; import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; import org.apache.ibatis.session.SqlSessionFactory; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.core.io.support.ResourcePatternResolver; import javax.sql.DataSource; public abstract class AbstractDbConfig { protected SqlSessionFactory sqlSessionFactory(DataSource dataSource, String mapperLocation) throws Exception { MybatisSqlSessionFactoryBean factoryBean = new MybatisSqlSessionFactoryBean(); factoryBean.setDataSource(dataSource); ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver(); Resource[] resource= resourceResolver.getResources(mapperLocation); factoryBean.setMapperLocations(resource); return factoryBean.getObject(); } protected DataSource dataSourceFactory(String driveClassName, String url, String userName, String password){ DruidDataSource datasource = new DruidDataSource(); datasource.setDriverClassName(driveClassName); datasource.setUrl(url); datasource.setUsername(userName); datasource.setPassword(password); datasource.setMaxActive(20); datasource.setInitialSize(20); return datasource; } }
在这个配置类中,应该使用
MybatisSqlSessionFactoryBean
而不是SqlSessionFactoryBean
,否则会报错:Invalid bound statement (not found)
对应不同的数据源,进行匹配
import com.jueee.repository.FirstRepository; import org.mybatis.spring.SqlSessionTemplate; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.PlatformTransactionManager; import javax.sql.DataSource; @Configuration @MapperScan(basePackages = {"com.jueee"},annotationClass = FirstRepository.class, sqlSessionTemplateRef = "firstUserTemplate") public class DataSourceConfigFirst extends AbstractDbConfig { @Value("${spring.datasource.first.jdbc-url}") private String url; @Value("${spring.datasource.first.username}") private String userName; @Value("${spring.datasource.first.password}") private String password; @Value("${spring.datasource.first.driver-class-name}") private String driveClassName; @Value(value = "${mybatis.mapper-location}") private String mapperLocation; @Bean(name = "firstUser") public DataSource secondaryDataSource() { return dataSourceFactory(driveClassName, url, userName, password); } @Bean(name = "firstUserTemplate") public SqlSessionTemplate firstUserSqlTemplate() throws Exception { return new SqlSessionTemplate((sqlSessionFactory(secondaryDataSource(), mapperLocation))); } @Bean @Qualifier("firstUserTransaction") public PlatformTransactionManager firstUserTransaction() { return new DataSourceTransactionManager(secondaryDataSource()); } }
第二数据源配置如下:
import com.jueee.repository.SecondRepository; import org.mybatis.spring.SqlSessionTemplate; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.PlatformTransactionManager; import javax.sql.DataSource; @Configuration @MapperScan(basePackages = {"com.jueee"},annotationClass = SecondRepository.class, sqlSessionTemplateRef = "secondUserTemplate") public class DataSourceConfigSecond extends AbstractDbConfig { @Value("${spring.datasource.second.jdbc-url}") private String url; @Value("${spring.datasource.second.username}") private String userName; @Value("${spring.datasource.second.password}") private String password; @Value("${spring.datasource.second.driver-class-name}") private String driveClassName; @Value(value = "${mybatis.mapper-location}") private String mapperLocation; @Bean(name = "secondUser") public DataSource secondaryDataSource() { return dataSourceFactory(driveClassName, url, userName, password); } @Bean(name = "secondUserTemplate") public SqlSessionTemplate secondUserSqlTemplate() throws Exception { return new SqlSessionTemplate((sqlSessionFactory(secondaryDataSource(), mapperLocation))); } @Bean @Qualifier("secondUserTransaction") public PlatformTransactionManager secondUserTransaction() { return new DataSourceTransactionManager(secondaryDataSource()); } }
定义注解
定义注解,分别作为不同数据库的表识。
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Component;
import java.lang.annotation.*;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Component
@Mapper
public @interface FirstRepository {
String value() default "";
}
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Component;
import java.lang.annotation.*;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Component
@Mapper
public @interface SecondRepository {
String value() default "";
}
Bean
com.jueee.bean.User
类:
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("user")
public class User {
private Long id;
private String username;
private String nickname;
}
com.jueee.bean.Book
类:
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("book")
public class Book {
private Long id;
private String author;
private String description;
private String title;
}
Mapper
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.jueee.bean.User;
import com.jueee.repository.FirstRepository;
@FirstRepository
public interface UserMapper extends BaseMapper<User> {
}
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.jueee.bean.Book;
import com.jueee.repository.SecondRepository;
@SecondRepository
public interface BookMapper extends BaseMapper<Book> {
}
Service
import com.jueee.bean.User;
import com.jueee.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public User selectById(int id){
return userMapper.selectById(id);
}
}
import com.jueee.bean.Book;
import com.jueee.mapper.BookMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class BookService {
@Autowired
private BookMapper bookMapper;
public List<Book> selectAll(){
return bookMapper.selectList(null);
}
}
测试类
import com.jueee.bean.Book;
import com.jueee.bean.User;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
@Slf4j
@SpringBootTest
public class UserServiceTest {
@Autowired
private UserService userService;
@Autowired
private BookService bookService;
@Test
public void selectById(){
User user = userService.selectById(1);
log.info(user.getNickname());
}
@Test
public void selectAll(){
List<Book> list = bookService.selectAll();
list.forEach(t->log.info(t.getAuthor()+" - "+t.getTitle()));
}
}
相关文章