dynamic-datasource+Mybatis多数据源使用

news2024/12/23 13:02:43

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-datasource


server.port=8088

#设置默认的数据源或者数据源组,默认值即为master
spring.datasource.dynamic.primary=master
#严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
spring.datasource.dynamic.strict=false

spring.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.DruidDataSource

spring.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.DruidDataSource


logging.level.com.example.dynamicdatasource=debug

mybatis.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 {

    @Autowired
    private 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 {

    @Autowired
    private 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 {


    @Autowired
    private 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 {



    @Autowired
    private ProductMapper productMapper;
    @Override
    public 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 {



    @Autowired
    private UserMapper userMapper;

    @Autowired
    private ProductMapper productMapper;


    @DSTransactional
    //使用@Transaction时候 配置类启动类加  @TransactionServiceImpl  现在不加也行
   //@Transactional//切换时候注意maven清理  这个注解此时不允许使用  报表不存在因数据源还在主库里 Table 'dy.t_product' doesn't exist
    public 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 {

    @Autowired
    private UserMapper userMapper;

    @Override
    public 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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1988347.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

腾讯云AI代码助手:智驭Python,编织代码的诗篇 —— 深度测评体验

文章目录 引言&#x1f496;1. 开发环境介绍&#x1f4bb;vscode安装插件方法一&#xff1a;链接访问下载安装方法二&#xff1a;vscode直接安装 2. 使用实例✨1. &#x1f6e1;️代码补全&#xff0c;分秒必争2. &#x1f4a1; 技术对话&#xff0c;智慧碰撞3. &#x1f527; …

【分享】洁净室环境检测必测项目详细解读

环境监测&#xff08;Environmental monitoring&#xff09;在实现此目标中起着重要的作用——它提供了有关制造环境的关键信息&#xff0c;避免放行可能受污染的产品。 由于环境监测在制造过程中的重要性&#xff0c;相关机构围绕市场活动推出了许多法规要求和指南。这些标准随…

el-table自动滚动到最底部

我的需求是这样的&#xff0c;因为我的表格是动态的&#xff0c;可以手动新增行&#xff0c;固定表头&#xff0c;而且需要一屏显示&#xff0c;为了方便用户就需要再新增的时候表格自动向上滚动。 差了官方文档后发现有一个属性可以支持 这个属性正是自己需要的&#xff0c;所…

朵拉朵尚:坚持深耕护肤领域 荣获2023年度影响力品牌奖

朵拉朵尚&#xff1a;坚持深耕护肤领域 荣获2023年度影响力品牌奖 伴随着经济全球化的浪潮&#xff0c;新产业、新业态、新动能不断涌现&#xff0c;我国化妆品消费也迅速崛起&#xff0c;成为近年来化妆品行业发展增长速度最快的国家。1月30日&#xff0c;朵拉朵尚受邀参加快…

使用 Plotly 创建专业可视化时你应该知道的七个关键功能

欢迎来到雲闪世界。我们习惯于在在线报纸上看到交互式可视化&#xff0c;并且我们经常想知道数据记者使用什么工具来创建这些看起来专业的可视化。事实是&#xff0c;创建这种类型的可视化不需要任何特殊软件&#xff1b;Python 中的大多数交互式可视化库都是高度可定制的&…

Stable Diffusion史诗级更新! WebUI 1.10.0时代来了!

前言 大家好&#xff0c;我是每天分享AI应用的萤火君&#xff01; 前几天 AUTOMATIC1111 发布了Stable Diffusion WebUI 1.10&#xff0c;我也在第一时间将云环境的镜像升级到了最新版本&#xff0c;有兴趣的同学可以去体验下&#xff0c;目前已经发布到了AutoDL&#xff0c;…

博客趣二维码生成器网站源码

这款二维码生成源码可以把电子名片、文本、wifi网络、电子邮件、短信、电话号码、网址等信息生成对应的二维码图片。地图位置二维码生成使用是谷歌地图的api地址&#xff0c;懂程序的可以改成国内地图http://www.bokequ.com/588.html

CST软件如何添加和管理自定义的材料?

经常有用户想手动添加材料到CST软件的材料库&#xff0c;或让CST软件指向自定义的材料库&#xff0c;由于CST软件没有自动追踪用户材料数据的功能&#xff0c;这里就需要用户知道一些小技巧&#xff0c;不然看不到这些材料哦 1. 材料库的路径&#xff1a; 首先解释材料库…

Django中事务的基本使用

1. Django事务处理 事务(Transaction): 是一种将多个数据库操作组合成一个单一工作单元的机制. 如果事务中的所有操作都成功完成, 则这些更改将永久保存到数据库中. 如果事务中的某个操作失败, 则整个事务将回滚到事务开始前的状态, 所有的更改都不会被保存到数据库中. 这对于…

流媒体服务器XMedia插件服务安装使用

XMedia是AMS流媒体服务器的一个插件服务&#xff0c;可以扩展支持 FLV 、GB28181上传、WEBRTC、SRT协议上传&#xff0c;增强了服务器的功能 一、服务插件安装 资源下载 XMedia-CentOS7-x86-64-20240710-212007 把安装包放入LINUX服务器&#xff0c;执行如下命令,如果未安装u…

因子分析和非负矩阵分解

因子分析 (Factor Analysis, FA) 因子分析是一种统计方法&#xff0c;用于通过少量潜在变量&#xff08;因子&#xff09;解释观测数据中的相关结构。它在数据降维、特征提取和变量选择中广泛应用。 原理 因子分析假设观测变量是由少数潜在因子线性组合并加上噪声得到的。通…

Stable Diffusion 使用详解(6)---人物风格及背景变换

目录 背景 ControlNet lineart IP-Adapter 实例 生成场景模特 操作 生成效果 生成背景 操作 生成效果 融合 ip-adaptor contrlNet lineart controlNet 生成效果 背景 很多场景下&#xff0c;需要完成人物风格变换&#xff0c;比如现在是写真集&#xff0c;想转…

『 Linux 』网络基础

文章目录 协议分层OSI 七层模型TCP/IP 四层(五层)模型网络协议栈与操作系统的联系报文TCP/IP 通讯过程以太网通信的过程以太网的数据碰撞 协议分层 协议分层是计算机网络中奖网络协议进行组织和管理的方法; 通过将网络通信过程分成多个层次,每个层次负责特定的功能从而简化网络…

打破视频生成难题,腾讯提出 MimicMotion引领AI模仿人体动作新纪元

该论文提出了一种可控的视频生成框架MimicMotion&#xff0c;能够生成高质量且任意长度的视频&#xff0c;模仿特定的运动指导。该研究引入信心感知姿势指导&#xff0c;确保视频帧的高质量和时间平滑性。同时&#xff0c;还引入了基于姿势信心的区域性损失放大策略&#xff0c…

hashmap底层原理(数据结构 put原理 get原理 remove原理)

目录 一、数据结构 二、put原理 进入put方法 第一步&#xff1a;通过 HashMap 自己提供的hash 算法算出当前 key 的hash 值 第二步&#xff1a; 进入putVal(hash(key), key, value, false, true) 第三步&#xff1a; resize 完整源码 putval resize 流程图​ 三、get原…

如何不需要通过试单(多单未成功)来关闭被禁用的PayPal账号

轮询自检系统 可以最大程度不浪费订单&#xff0c;当你的PayPal被禁止收单时&#xff0c;无需通过试单(多单不成功)功能来关闭你的账号&#xff0c;极大的保证订单的成功率。 除了在接单时候系统自检&#xff0c;我们还提供一个批量检测PayPal账号系统&#xff0c;可大批量的检…

【运维自动化-配置平台】平台管理功能如何使用

蓝鲸智云配置平台&#xff0c;以下简称配置平台 配置平台里的平台管理功能是管理员的一些操作&#xff0c;比如一些全局纬度的设置1、全局配置-业务通用 业务快照名称&#xff1a;通常不需要修改&#xff0c;保持平台搭建好默认业务&#xff08;蓝鲸&#xff09;即可 拓扑最大…

主从备份及安装准备

主从复制 学习内容 1. 备份的三种类型 1. 热备份 2. 逻辑备份 3. 物理备份 2. 情景 ⼊职企业&#xff0c;发现企业架构为⼀主多从&#xff0c;但是两台从服务器和主库不同 步&#xff0c;但是每天会全库北⽅主服务器上的数据到从服务器&#xff0c;由于数据量 不是很⼤&a…

C++校园线上点餐系统-计算机毕业设计源码82032

摘要 本论文旨在设计并实现一种基于C语言的校园线上点餐系统&#xff0c;以解决校园内学生和教职员工点餐的便利性问题。该系统采用C语言作为主要开发语言&#xff0c;结合文件操作、数据结构和用户界面设计等技术&#xff0c;实现了一个功能完善的点餐系统。 论文介绍了校园线…

【书生大模型实战营第三期 | 基础岛第2关-8G 显存玩转书生大模型 Demo】

学习心得&#xff1a;8G 显存玩转书生大模型 Demo 摘要 本文是对《8G 显存玩转书生大模型 Demo》文档的学习心得。通过阅读文档&#xff0c;我了解了如何在有限的硬件资源下部署和使用大型语言模型&#xff0c;包括InternLM2-Chat-1.8B、InternLM-XComposer2-VL-1.8B和Intern…