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 ...
随机推荐
- redis 分布式读写锁
http://zhangtielei.com/posts/blog-redlock-reasoning.html 链接里这篇 blog 讨论了 redis 分布式锁的实现以及安全性 我要参考 基于单R ...
- Shell-8--数值运算及处理
RANDOM 默认范围是 0~32767
- 第五篇: 路由网关(zuul)
在微服务架构中,需要几个基础的服务治理组件,包括服务注册与发现.服务消费.负载均衡.断路器.智能路由.配置管理等,由这几个基础组件相互协作,共同组建了一个简单的微服务系统. 在Spring Cloud ...
- 转载 12步轻松搞定python装饰器
作者: TypingQuietly 原文链接: https://www.jianshu.com/p/d68c6da1587a 呵呵!作为一名教python的老师,我发现学生们基本上一开始很难搞定pyt ...
- oracle生成AWR报告方法
2018-04-02 19:59:42 在10g 11g中AWR自动的每隔一小时进行一次数据采集并生成快照.下面是生成AWR报告的步骤: 1:使用oracle用户在数据库服务器上执行如下命令 sqlp ...
- 如何在Mac下配置Github和Bitbucket的SSH
--- title: 如何在Mac下配置Github和Bitbucket的SSH date: 2017-12-23 21:10:30 tags: - Mac - Git - Github catego ...
- MySQL 中的数字类型
MySQL 中数据类型常用的就三大类: 数字类型/numeric types 日期和时间/date and time types 字符类型/string (character and byte) ty ...
- 前端进击的巨人(五):学会函数柯里化(curry)
柯里化(Curring, 以逻辑学家Haskell Curry命名) 写在开头 柯里化理解的基础来源于我们前几篇文章构建的知识,如果还未能掌握闭包,建议回阅前文. 代码例子会用到 apply/call ...
- TCP/IP 笔记 - 传输控制协议
与UDP不同,TCP提供面向连接的.可靠的.基于字节流的传输层协议,且提供差错纠正. TCP传输的概念 对与分组丢失和比特差错的处理方法,最直接的方法是重发分组,直到它被正确接收. 这需要一种方法来判 ...
- nginx介绍(三) - 虚拟主机
前言 前面提到过, 由nginx来分发请求到tomcat中, 那么怎么来区分这些tomcat呢? 我们一般访问网站的时候, 是不是可以使用 ip : port (127.0.0.1:8080)的方式来 ...