文章目录
写了一个小demo,通过mybatis-plus实现多数据源管理
使用了mysql和redis两类数据库。
Mybatis-Plus官网
Mybatis-Plus的多数据源Dynamic-Datasource
1.依赖
springboot版本 2.3.12.RELEASE
springcloud版本 2.2.8.RELEASE
nacos版本 2.1.0
nacos安装部署教程
springboot整合nacos
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>2.3.3</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>2.3.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-autoconfigure</artifactId>
<version>2.2.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
</dependencies>
2.配置文件
项目中的 bootstrap.yaml文件
spring:
application:
name: springboot-muldata
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
namespace: config
file-extension: yaml
group: DEFAULT_GROUP
discovery:
server-addr: 127.0.0.1:8848
bootstrap:
enabled: true
nacos中的配置文件
填写自己的数据库,用户名,密码
server:
port: 8503
spring:
datasource:
dynamic:
primary: master #设置默认的数据源或者数据源组,默认值即为master
strict: false
datasource:
master:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/blog-demo?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
username: root
password: mysql
mysql_2:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/study?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
username: root
password: mysql
redis:
database: 1
host: 127.0.0.1
port: 6379
username: root
password:
#打印sql语句
#因为用了mybatis-plus组件,就不用写mybatis
mybatis-plus:
configuration:
map-underscore-to-camel-case: true # 开启驼峰命名
type-aliases-package: com.example.springbootmuldatasources.entity
mapper-locations: classpath*:mappers/*.xml
3.redis测试
3.1redis配置文件
RedisConfiguration文件
public GenericObjectPoolConfig poolConfig(){
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
//控制一个pool可分配多少个jedis实例
poolConfig.setMaxTotal(500);
//最大空闲数
poolConfig.setMaxIdle(200);
//每次释放连接的最大数目,默认是3
poolConfig.setNumTestsPerEvictionRun(1024);
//逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1
poolConfig.setTimeBetweenEvictionRunsMillis(30000);
//连接的最小空闲时间 默认1800000毫秒(30分钟)
poolConfig.setMinEvictableIdleTimeMillis(-1);
poolConfig.setSoftMinEvictableIdleTimeMillis(10000);
//最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
poolConfig.setMaxWaitMillis(1500);
poolConfig.setTestOnBorrow(true);
poolConfig.setTestWhileIdle(true);
poolConfig.setTestOnReturn(false);
poolConfig.setJmxEnabled(true);
poolConfig.setBlockWhenExhausted(false);
return poolConfig;
}
@Bean
public LettuceConnectionFactory lettuceConnectionFactory() {
LettucePoolingClientConfiguration lettucePoolingClientConfiguration = LettucePoolingClientConfiguration.builder()
.poolConfig(poolConfig())
.build();
// 单机redis
RedisStandaloneConfiguration redisConfig = new RedisStandaloneConfiguration();
redisConfig.setHostName("127.0.0.1");
redisConfig.setPort(6379);
redisConfig.setDatabase(0);
// 哨兵redis
//RedisSentinelConfiguration redisConfig = new RedisSentinelConfiguration();
// 集群redis
// RedisClusterConfiguration redisConfig = new RedisClusterConfiguration();
// Set<RedisNode> nodeses = new HashSet<>();
// String[] hostses = nodes.split("-");
// for (String h : hostses) {
// h = h.replaceAll("\\s", "").replaceAll("\n", "");
// if (!"".equals(h)) {
// String host = h.split(":")[0];
// int port = Integer.valueOf(h.split(":")[1]);
// nodeses.add(new RedisNode(host, port));
// }
// }
// redisConfig.setClusterNodes(nodeses);
// // 跨集群执行命令时要遵循的最大重定向数量
// redisConfig.setMaxRedirects(3);
// redisConfig.setPassword(password);
return new LettuceConnectionFactory(redisConfig, lettucePoolingClientConfiguration);
}
}
3.2controller
@RestController
@RequestMapping("/redis")
public class RedisTestController {
@Autowired
private RedisTemplate redisTemplate;
/**
* redis存入String类型数据的测试
* @return
*/
@GetMapping("/testString")
public String RedisTestString(){
// 设置String的key,value
redisTemplate.opsForValue().set("testString","String");
// 获取redis存储的string类型的value
String testString = (String) redisTemplate.opsForValue().get("testString");
return testString;
}
/**
* redis存入hash类型数据的测试
* @return
*/
@GetMapping("/testHash")
public Map<String,String> RedisTestHash(){
HashMap<String, String> stringStringHashMap = new HashMap<>();
stringStringHashMap.put("testHash1","HashValue1");
stringStringHashMap.put("testHash2","HashValue2");
stringStringHashMap.put("testHash3","HashValue3");
stringStringHashMap.put("testHash4","HashValue4");
//单个存入
redisTemplate.opsForHash().put("testHash","testHash0","HashValue0");
// 设置redis的hash的key,value
redisTemplate.opsForHash().putAll("testHash",stringStringHashMap);
// //获得redis存储的Hash
System.out.println("输出redis存储的Hash");
Object o = redisTemplate.opsForHash().get("testHash", "testHash0");
System.out.println(o);
Map result = redisTemplate.opsForHash().entries("testHash");
System.out.println(result);
return result;
}
/**
* redis存入list类型数据的测试
* @return String
*/
@GetMapping("/testList")
public String RedisTestList(){
ArrayList<String> stringList = new ArrayList<>();
stringList.add("list1");
stringList.add("list2");
stringList.add("list3");
// 设置redis的list的key,value,使用json的形式
String key = "testList1";
redisTemplate.opsForValue().set(key,stringList.toString());
//输出redis存储的list
System.out.println("输出redis存储的testList1");
String result = (String) redisTemplate.opsForValue().get(key);
System.out.println(result);
ArrayList<String> stringList2 = new ArrayList<>();
stringList2.add("list4");
stringList2.add("list5");
stringList2.add("list6");
String key2 = "testList2";
redisTemplate.opsForList().rightPush(key2,stringList2);
//去除list的数据
Object result2 = redisTemplate.opsForList().rightPop(key2);
//取出后数据内就没有了,redis里面就不会有数据所以重新存入
redisTemplate.opsForList().rightPush(key2,stringList2);
System.out.println("输出redis存储的testList2");
System.out.println(result2);
return result+result2;
}
/**
* redis存入Set类型数据的测试
* @return
*/
@GetMapping("/testSet")
public String RedisTestSet(){
String key = "testSet";
Long add = redisTemplate.opsForSet().add(key, "set1", "set2", "set3", "set4");
System.out.println(add);
Object pop = redisTemplate.opsForSet().pop(key);
System.out.println(pop);
String result = pop.toString();
return result;
}
}
3.3测试
http://localhost:8503/redis/testHash
4.mysql测试
4.1数据库表和结构
/*
Navicat Premium Data Transfer
Source Server : hhf-test
Source Server Type : MySQL
Source Server Version : 80019
Source Host : localhost:3306
Source Schema : blog-demo
Target Server Type : MySQL
Target Server Version : 80019
File Encoding : 65001
Date: 26/01/2023 14:55:53
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for dog
-- ----------------------------
DROP TABLE IF EXISTS `dog`;
CREATE TABLE `dog` (
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
`age` int NULL DEFAULT NULL,
`gender` enum('MALE','FEMALE') CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT 'MALE',
PRIMARY KEY (`name`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of dog
-- ----------------------------
INSERT INTO `dog` VALUES ('小花', 6, 'MALE');
INSERT INTO `dog` VALUES ('小黄', 10, 'FEMALE');
SET FOREIGN_KEY_CHECKS = 1;
4.2实体类和枚举
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Dog {
private String name;
private Integer age;
private Gender gender;
}
public enum Gender {
MALE,FEMALE
}
4.3DogMapper.xml
<mapper namespace="com.example.springbootmuldatasources.mapper.DogMapper">
<select id="selectByName" resultType="com.example.springbootmuldatasources.entity.Dog">
select * from dog where name = #{name}
</select>
</mapper>
4.4DogMapper
@Mapper
public interface DogMapper {
//@Select("select * from dog where name = #{name}")
Dog selectByName(String name);
}
4.5service和serviceImpl
service
@Service
public interface DogService {
Dog getByName(String name);
}
serviceImpl
@Service
public class DogServiceImpl implements DogService {
@Autowired
private DogMapper dogMapper;
@Override
public Dog getByName(String name) {
Dog dog = dogMapper.selectByName(name);
return dog;
}
}
4.6controller
@RestController
@RequestMapping("/mysql")
public class MysqlController {
@Autowired
private DogService dogService;
@GetMapping("/getDogName")
public void getOne(){
Dog dog = dogService.getByName("小花");
System.out.println(dog);
}
}
4.7测试
http://localhost:8503/mysql/getDogName