IDEA项目搭建九——MybatisPlus多数据库实现
一、简介
MybatisPlus中引用多数据库时,传统的配置就失效了,需要单独写配置来实现,下面就说一下具体应该如何操作
二、引入MybatisPlus多数据源配置
还是先看一下我的项目结构,Model是单独的模块,请自行创建
1、创建一个Maven项目,修改pom.xml文件增加对spring boot、mybatis plus、druid、mysql connector的引用
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.0.3.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--import druid-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<!--import mysql connector-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.9</version>
</dependency>
<!--import mybatis plus 它会自动引入mybatis及mybatis spring切勿重复引用以免冲突-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>2.3</version>
</dependency>
</dependencies>
2、创建resources文件夹,并创建application.yml文件增加以下配置,此处不需要写mybatis plus的配置了,因为多数据源时这里的mybatis plus会失效,具体原因还没找到
#设置提供的服务名
spring:
application:
name: javademo-tyh-service-hotel
#配置数据库
datasource:
type: com.alibaba.druid.pool.DruidDataSource
db1:
url: jdbc:mysql://10.11.12.237:3306/db_test?useUnicode=true&characterEncoding=utf8
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
db2:
url: jdbc:mysql://10.11.12.237:3306/tyh_test?useUnicode=true&characterEncoding=utf8
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver #设置自己启动的端口
server:
port: 12000
3、在resources文件夹下创建mapper文件夹,在其内部创建两个数据库的两张表的mapper.xml文件,分别编写一个自定义方法
BaseInfoMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- 指明当前xml对应的Mapper -->
<mapper namespace="javademo.tyh.service.hotel.mapper.BaseInfoMapper">
<select id="listCount" resultType="Integer">
select count(*) from base_info;
</select>
</mapper>
UserInfoMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- 指明当前xml对应的Mapper -->
<mapper namespace="javademo.tyh.service.hotel.mapper.UserInfoMapper">
<select id="listCount" resultType="Integer">
select count(*) from user_info;
</select>
</mapper>
4、打开main方法所在的类并修改为如下代码
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication
@MapperScan("javademo.tyh.service.hotel.mapper")//标记扫描的mapper位置
public class AppServiceHotel
{
public static void main( String[] args )
{
SpringApplication.run(AppServiceHotel.class, args);
}
}
5、创建config文件夹,存放mybatis plus的相关配置,此内部的类很多都摘自官网,是按照他的方式进行实现的
创建枚举DBTypeEnum
/**
* 多数据源枚举
*/
public enum DBTypeEnum {
db1("db1"), db2("db2");
private String value;
DBTypeEnum(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
创建数据源操作类DbContextHolder
public class DbContextHolder {
private static final ThreadLocal contextHolder = new ThreadLocal<>();
/**
* 设置数据源
* @param dbTypeEnum
*/
public static void setDbType(DBTypeEnum dbTypeEnum) {
contextHolder.set(dbTypeEnum.getValue());
}
/**
* 取得当前数据源
* @return
*/
public static String getDbType() {
return (String) contextHolder.get();
}
/**
* 清除上下文数据
*/
public static void clearDbType() {
contextHolder.remove();
}
}
创建spring的DataSource抽象类 DynamicDataSource
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; /*
* 扩展Spring的AbstractRoutingDataSource抽象类,实现动态数据源。
* AbstractRoutingDataSource中的抽象方法determineCurrentLookupKey是实现数据源的route的核心,
* 这里对该方法进行Override。 【上下文DbContextHolder为一线程安全的ThreadLocal】
*/
public class DynamicDataSource extends AbstractRoutingDataSource {
/**
* 取得当前使用哪个数据源
* @return
*/
@Override
protected Object determineCurrentLookupKey(){
return DbContextHolder.getDbType();
}
}
创建MybatisPlusConfig配置类
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.baomidou.mybatisplus.MybatisConfiguration;
import com.baomidou.mybatisplus.entity.GlobalConfiguration;
import com.baomidou.mybatisplus.mapper.LogicSqlInjector;
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.JdbcType;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map; /**
* MybatisPlus配置
*/
@Configuration
public class MybatisPlusConfig {
// 分页拦截器
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
//定义db1
@Bean(name = "db1")
@ConfigurationProperties(prefix = "spring.datasource.db1")//与配置文件中的层次结构相同
public DataSource db1() {
return DruidDataSourceBuilder.create().build();
}
//定义db2
@Bean(name = "db2")
@ConfigurationProperties(prefix = "spring.datasource.db2")//与配置文件中的层次结构相同
public DataSource db2() {
return DruidDataSourceBuilder.create().build();
}
/**
* 动态数据源配置
* @return
*/
@Bean
@Primary
public DataSource multipleDataSource(@Qualifier("db1") DataSource db1, @Qualifier("db2") DataSource db2) {
DynamicDataSource dynamicDataSource = new DynamicDataSource();
Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put(DBTypeEnum.db1.getValue(), db1);
targetDataSources.put(DBTypeEnum.db2.getValue(), db2);
dynamicDataSource.setTargetDataSources(targetDataSources);
dynamicDataSource.setDefaultTargetDataSource(db1);
return dynamicDataSource;
} @Bean("sqlSessionFactory")
public SqlSessionFactory sqlSessionFactory() throws Exception {
//***导入MybatisSqlSession配置***
MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
//指明数据源
sqlSessionFactory.setDataSource(multipleDataSource(db1(), db2()));
//指明mapper.xml位置(配置文件中指明的xml位置会失效用此方式代替,具体原因未知)
sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:/mapper/**Mapper.xml"));
//指明实体扫描(多个package用逗号或者分号分隔)
sqlSessionFactory.setTypeAliasesPackage("javademo.tyh.model.base;javademo.tyh.model.hotel"); //***导入Mybatis配置***
MybatisConfiguration configuration = new MybatisConfiguration();
configuration.setJdbcTypeForNull(JdbcType.NULL);
configuration.setMapUnderscoreToCamelCase(true);
configuration.setCacheEnabled(false);
sqlSessionFactory.setConfiguration(configuration);
sqlSessionFactory.setPlugins(new Interceptor[]{paginationInterceptor()}); //***导入全局配置***
sqlSessionFactory.setGlobalConfig(globalConfiguration());
return sqlSessionFactory.getObject();
} /**
* 在代码中配置MybatisPlus替换掉application.yml中的配置
* @return
*/
@Bean
public GlobalConfiguration globalConfiguration() {
GlobalConfiguration conf = new GlobalConfiguration(new LogicSqlInjector());
//主键类型 0:数据库ID自增, 1:用户输入ID,2:全局唯一ID (数字类型唯一ID), 3:全局唯一ID UUID
conf.setIdType(0);
//字段策略(拼接sql时用于判断属性值是否拼接) 0:忽略判断,1:非NULL判断,2:非空判断
conf.setFieldStrategy(2);
//驼峰下划线转换含查询column及返回column(column下划线命名create_time,返回java实体是驼峰命名createTime,开启后自动转换否则保留原样)
conf.setDbColumnUnderline(true);
//是否动态刷新mapper
conf.setRefresh(true);
return conf;
}
}
6、创建mapper文件夹用于存放于xml对应的mapper接口
BaseInfoMapper
import com.baomidou.mybatisplus.mapper.BaseMapper;
import javademo.tyh.model.hotel.BaseInfoModel;
import org.springframework.stereotype.Component; @Component
public interface BaseInfoMapper extends BaseMapper<BaseInfoModel> {
//自定义方法
int listCount();
}
UserInfoMapper
import com.baomidou.mybatisplus.mapper.BaseMapper;
import javademo.tyh.model.hotel.UserInfoModel;
import org.springframework.stereotype.Component; @Component
public interface UserInfoMapper extends BaseMapper<UserInfoModel> {
//自定义方法
int listCount();
}
7、创建service文件夹用于存放业务逻辑类
import javademo.tyh.model.hotel.BaseInfoModel;
import javademo.tyh.model.hotel.UserInfoModel;
import javademo.tyh.service.hotel.config.DBTypeEnum;
import javademo.tyh.service.hotel.config.DbContextHolder;
import javademo.tyh.service.hotel.mapper.BaseInfoMapper;
import javademo.tyh.service.hotel.mapper.UserInfoMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; @Service
public class HotelService { @Autowired
BaseInfoMapper baseMapper;
@Autowired
UserInfoMapper userMapper; public void testDynamicDb() {
//使用db1
DbContextHolder.setDbType(DBTypeEnum.db1);
BaseInfoModel baseModel = baseMapper.selectById(1);
int baseCount = baseMapper.listCount();
System.out.println("db1=" + baseModel.getNickname());
//使用db2
DbContextHolder.setDbType(DBTypeEnum.db2);
UserInfoModel userModel = userMapper.selectById(1);
int userCount = userMapper.listCount();
System.out.println("db2=" + userModel.getUsername());
}
}
8、创建controller文件夹编写一个controller和action用于测试
import javademo.tyh.service.hotel.service.HotelService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; @Controller
@RequestMapping("/hotel")
public class HotelController { @Autowired
HotelService service; @ResponseBody
@RequestMapping("/test")
public void test() {
service.testDynamicDb();
}
}
9、创建自己的实体Model,get/set方法自己生成吧
BaseInfoModel
import com.baomidou.mybatisplus.annotations.TableName;
import java.time.LocalDateTime; @TableName("base_info")
public class BaseInfoModel {
private int id;
private String nickname;
private LocalDateTime updateTime;
}
UserInfoModel
import com.baomidou.mybatisplus.annotations.TableName;
import java.time.LocalDateTime; @TableName("user_info")
public class UserInfoModel {
private int id;
private String username;
private String password;
private int sex;
private int age;
private LocalDateTime createTime;
}
OK,至此Mybatis Plus多数据源配置Demo就完成了,可以运行http://localhost:12000/hotel/test看一下console控制台会得到以下输出,db1和db2就切换成功了
IDEA项目搭建九——MybatisPlus多数据库实现的更多相关文章
- Spring MVC 项目搭建 -5- spring security 使用数据库进行验证
Spring MVC 项目搭建 -5- spring security 使用数据库进行验证 1.创建数据表格(这里使用的是mysql) CREATE TABLE security_role ( id ...
- IDEA项目搭建八——使用MybatisPlus简化数据库交互
一.MybatisPlus简化数据库交互 我们使用Mybatis发现需要在mapper.xml中写很多重复的简单CRUD(增删改查),使用MybatisPlus可以大大简化这部分代码,官方文档http ...
- 真分布式SolrCloud+Zookeeper+tomcat搭建、索引Mysql数据库、IK中文分词器配置以及web项目中solr的应用(1)
版权声明:本文为博主原创文章,转载请注明本文地址.http://www.cnblogs.com/o0Iris0o/p/5813856.html 内容介绍: 真分布式SolrCloud+Zookeepe ...
- Spring MVC 项目搭建 -6- spring security 使用自定义Filter实现验证扩展资源验证,使用数据库进行配置
Spring MVC 项目搭建 -6- spring security使用自定义Filter实现验证扩展url验证,使用数据库进行配置 实现的主要流程 1.创建一个Filter 继承 Abstract ...
- 一个简单的NetCore项目:1 - 搭建框架,生成数据库
1- 启动项目 安装.NETCORE SDK,教程在网上可以搜索的到,这里就不讲述了.简单粗暴的方式就是安装最新的VS2015. 2-搭建框架 2.1 打开VS新建一个项目,在弹出的新建项目对话框中, ...
- Intellij IDEA Java web 项目搭建
Java web 项目搭建 简介 在上一节java web环境搭建中,我们配置了开发java web项目最基本的环境,现在我们将采用Spring MVC+Spring+Hibernate的架构搭建一个 ...
- Java web 项目搭建
Java web 项目搭建 简介 在上一节java web环境搭建中,我们配置了开发java web项目最基本的环境,现在我们将采用Spring MVC+Spring+Hibernate的架构搭建一个 ...
- Spirng+SpringMVC+Maven+Mybatis+MySQL项目搭建(转)
这篇文章主要讲解使用eclipse对Spirng+SpringMVC+Maven+Mybatis+MySQL项目搭建过程,包括里面步骤和里面的配置文件如何配置等等都会详细说明. 如果还没有搭建好环境( ...
- freemarker + spring mvc + spring + mybatis + mysql + maven项目搭建
今天说说搭建项目,使用freemarker + spring mvc + spring + mybatis + mysql + maven搭建web项目. 先假设您已经配置好eclipse的maven ...
随机推荐
- cad.net DeepCloneObjects WasErased
/// <summary> /// 克隆图元到块表记录 /// </summary> /// <param name="objId">id数组& ...
- 故事描述SVM----支持向量机/support vector machine (SVM)
作者:简之链接:https://www.zhihu.com/question/21094489/answer/86273196来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出 ...
- mysql之UPDATE,SELECT,INSERT语法
一 :UPDATE语法 UPDATE 是一个修改表中行的DML语句. #单表语法(常用) UPDATE [LOW_PRIORITY] [IGNORE] table_reference SET as ...
- Spring 声明事务中transactionAttributes属性 + - Exception 实现逻辑
下面是一段典型的Spring 声明事务的配置: <bean id=“baseTxProxy” lazy-init=“true”class=“org.springframework.transac ...
- 解决Eclipse中DDMS一直打印输出Connection attempts的问题
Eclipse/MyEclipse出现以下错误的解决方案: [2015-01-25 16:10:29 - DeviceMonitor] Adb connection Error:远程主机强迫关闭了一个 ...
- 课程三(Structuring Machine Learning Projects),第二周(ML strategy(2)) —— 1.Machine learning Flight simulator:Autonomous driving (case study)
[中文翻译] 为了帮助您练习机器学习的策略, 在本周我们将介绍另一个场景, 并询问您将如何行动.我们认为, 这个工作在一个机器学习项目的 "模拟器" 将给一个任务, 告诉你一个机器 ...
- Spark SQL读取hive数据时报找不到mysql驱动
Exception: Caused by: org.datanucleus.exceptions.NucleusException: Attempt to invoke the "BoneC ...
- c++ vector的内存释放
c++中vector的一个特点是: 内存空间只会增长,不会减小.即为了支持快速的随机访问,vector容器的元素以连续方式存放,每一个元素都挨着前一个元素存储.设想,如果每次vector添加一个新元素 ...
- 当x,y和theta都是向量的时候如何计算损失
function J = computeCost(X, y, theta) %COMPUTECOST Compute cost for linear regression % J = COMPUTEC ...
- spring cloud(断路器——初学五)
Feign使用Hystrix 因为feign已经依赖了hystrix,所以可以直接使用,无需添加再次添加依赖. 1.使用@FeignClient注解中的fallback属性指定回调类 package ...