dynamic-datasource+Mybatis多数据源使用
Gitee地址:dynamic-datasource: 基于 SpringBoot 多数据源 动态数据源 主从分离 快速启动器 支持分布式事务
依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.3</version> </dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version> </dependency> <!--dynamic-datasource --> <dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot3-starter</artifactId><version>4.3.1</version> </dependency> <dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.21</version> </dependency>
application.properties
spring.application.name=dynamic-datasourceserver.port=8088#设置默认的数据源或者数据源组,默认值即为master spring.datasource.dynamic.primary=master #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源 spring.datasource.dynamic.strict=falsespring.datasource.dynamic.datasource.master.url=jdbc:mysql://localhost:3306/dy?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true spring.datasource.dynamic.datasource.master.username=root spring.datasource.dynamic.datasource.master.password=root spring.datasource.dynamic.datasource.master.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.dynamic.datasource.master.type=com.alibaba.druid.pool.DruidDataSourcespring.datasource.dynamic.datasource.slave.url=jdbc:mysql://localhost2:3306/dy?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true spring.datasource.dynamic.datasource.slave.username=root spring.datasource.dynamic.datasource.slave.password=root spring.datasource.dynamic.datasource.slave.driver-class-name=com.mysql.cj.jdbc.Driver #去掉默认使用HikariCP spring.datasource.dynamic.datasource.slave.type=com.alibaba.druid.pool.DruidDataSourcelogging.level.com.example.dynamicdatasource=debugmybatis.type-aliases-package=com.example.dynamicdatasource.pojo mybatis.mapper-locations=classpath*:mappers/*Mapper.xml #驼峰 mybatis.configuration.map-underscore-to-camel-case=true
package com.example.dynamicdatasource.controller;import com.example.dynamicdatasource.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;/*** @author hrui* @date 2024/8/6 15:49*/
@RestController
public class ProductController {@Autowiredprivate ProductService productService;@GetMapping("/saveProduct")public String saveProduct(){productService.saveProduct();return "saveProduct success";}
}
package com.example.dynamicdatasource.controller;import com.example.dynamicdatasource.service.TransactionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;/*** @author hrui* @date 2024/8/6 16:10*/
@RestController
public class TransactionController {@Autowiredprivate TransactionService transactionService;@GetMapping("/trans")public String saveUserAndProduct() {transactionService.saveUserAndProduct();return "success";}
}
package com.example.dynamicdatasource.controller;import com.example.dynamicdatasource.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;/*** @author hrui* @date 2024/8/6 15:49*/
@RestController
public class UserController {@Autowiredprivate UserService userService;@GetMapping("/saveUser")public String saveUser() {userService.saveUser();return "success";}
}
package com.example.dynamicdatasource.service;/*** @author hrui* @date 2024/8/6 15:49*/
public interface ProductService {void saveProduct();
}
package com.example.dynamicdatasource.service;/*** @author hrui* @date 2024/8/6 16:11*/
public interface TransactionService {void saveUserAndProduct();
}
package com.example.dynamicdatasource.service;/*** @author hrui* @date 2024/8/6 15:49*/
public interface UserService {void saveUser();
}
package com.example.dynamicdatasource.service.impl;import com.example.dynamicdatasource.mapper.ProductMapper;
import com.example.dynamicdatasource.pojo.Product;
import com.example.dynamicdatasource.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.math.BigDecimal;/*** @author hrui* @date 2024/8/6 15:49*/
@Service
public class ProductServiceImpl implements ProductService {@Autowiredprivate ProductMapper productMapper;@Overridepublic void saveProduct() {Product product = new Product();product.setName("product");product.setPrice(new BigDecimal(100));int i=productMapper.saveProduct(product);System.out.println(i>0?"插入成功":"插入失败");}
}
package com.example.dynamicdatasource.service.impl;import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.example.dynamicdatasource.mapper.ProductMapper;
import com.example.dynamicdatasource.mapper.UserMapper;
import com.example.dynamicdatasource.pojo.Product;
import com.example.dynamicdatasource.pojo.User;
import com.example.dynamicdatasource.service.TransactionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.math.BigDecimal;/*** @author hrui* @date 2024/8/6 16:11*/
@Service
public class TransactionServiceImpl implements TransactionService {@Autowiredprivate UserMapper userMapper;@Autowiredprivate ProductMapper productMapper;@DSTransactional//使用@Transaction时候 配置类启动类加 @TransactionServiceImpl 现在不加也行//@Transactional//切换时候注意maven清理 这个注解此时不允许使用 报表不存在因数据源还在主库里 Table 'dy.t_product' doesn't existpublic void saveUserAndProduct() {//判断是否开启事务
// if( TransactionSynchronizationManager.isActualTransactionActive()){
// System.out.println("开启事务");
// }else{
// System.out.println("未开启事务");
// }User user = new User(null, "李四", "123456", 18, "男", "北京");Product product = new Product(null, "手机", new BigDecimal(1000));int i=userMapper.saveUser(user);int i2=productMapper.saveProduct(product);System.out.println(1/0);System.out.println(i>0&&i2>0?"插入成功":"插入失败");}
}
package com.example.dynamicdatasource.service.impl;import com.example.dynamicdatasource.mapper.UserMapper;
import com.example.dynamicdatasource.pojo.User;
import com.example.dynamicdatasource.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;/*** @author hrui* @date 2024/8/6 15:49*/
@Service
public class UserServiceImpl implements UserService {@Autowiredprivate UserMapper userMapper;@Overridepublic void saveUser() {User user = new User(null, "张三", "123456", 18, "男", "北京");int i=userMapper.saveUser(user);System.out.println(i>0?"插入成功":"插入失败");}
}
package com.example.dynamicdatasource.mapper;import com.baomidou.dynamic.datasource.annotation.DS;
import com.example.dynamicdatasource.pojo.Product;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Options;/*** @author hrui* @date 2024/8/6 15:50*/
@DS("slave")
public interface ProductMapper {@Insert("insert into t_product(name,price) values(#{name},#{price})")//返回自增主键@Options(useGeneratedKeys = true, keyProperty = "id")int saveProduct(Product product);}
package com.example.dynamicdatasource.mapper;import com.example.dynamicdatasource.pojo.User;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Options;/*** @author hrui* @date 2024/8/6 15:50*/
public interface UserMapper {@Insert("insert into t_user(name,sex,age,address,password) values(#{name},#{sex},#{age},#{address},#{password})")//返回自增主键@Options(useGeneratedKeys = true, keyProperty = "id")int saveUser(User user);
}
package com.example.dynamicdatasource.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.math.BigDecimal;/*** @author hrui* @date 2024/8/6 15:50*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Product {private Integer id;private String name;private BigDecimal price;
}
package com.example.dynamicdatasource.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;/*** @author hrui* @date 2024/8/6 15:50*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {private Integer id;private String name;private String password;private Integer age;private String sex;private String address;
}