手机网站怎么做才适合优化,中英文双语的网站怎么建设,类似 wordpress,wordpress更新服务评论1. 概述 仓库地址#xff1a;https://gitee.com/aopmin/multi-datasource-demo 随着项目规模的扩大和业务需求的复杂化#xff0c;单一数据源已经不能满足实际开发中的需求。在许多情况下#xff0c;我们需要同时操作多个数据库#xff0c;或者需要将不同类型的数据存储在不…1. 概述 仓库地址https://gitee.com/aopmin/multi-datasource-demo 随着项目规模的扩大和业务需求的复杂化单一数据源已经不能满足实际开发中的需求。在许多情况下我们需要同时操作多个数据库或者需要将不同类型的数据存储在不同的数据库中。这时多数据源场景成为必不可少的解决方案。
市面上常见的多数据源实现方案如下 方案1基于Spring框架提供的AbstractRoutingDataSource。 优点 简单易用支持动态切换数据源适用于少量数据源情况。场景适用于需要动态切换数据源且数据库较少的情况。文档地址 方案2使用MP提供的Dynamic-datasource多数据源框架。 文档地址https://baomidou.com/guides/dynamic-datasource/#dynamic-datasource 方案3通过自定义注解在方法或类上指定数据源实现根据注解切换数据源的功能。 优点 灵活性高能够精确地控制数据源切换在代码中直观明了。场景 适用于需要在代码层面进行数据源切换并对数据源切换有精细要求的情况。 方案4使用动态代理技术在运行时动态切换数据源实现多数据源的切换。 优点 灵活性高支持在运行时动态切换数据源适合对数据源切换的逻辑有特殊需求的情况。场景 适用于需要在运行时动态决定数据源切换策略的情况。 … 2. 基于SpringBoot的多数据源实现方案 1、执行sql脚本(分别创建两个数据库里面都提供一张user表)
-- 创建数据库ds1
CREATE DATABASE ds1;-- 使用ds1数据库
USE ds1;-- 创建user表
CREATE TABLE user (id INT PRIMARY KEY AUTO_INCREMENT COMMENT 主键id,username VARCHAR(50) COMMENT 用户名,gender TINYINT(1) COMMENT 性别:0男1女
);-- 向user表插入数据
INSERT INTO user (username, gender) VALUES
(张三, 1),
(李四, 0),
(王五, 1);-- 创建数据库ds2
CREATE DATABASE ds2;-- 使用ds2数据库
USE ds2;-- 创建user表
CREATE TABLE user (id INT PRIMARY KEY AUTO_INCREMENT COMMENT 主键id,username VARCHAR(50) COMMENT 用户名,gender TINYINT(1) COMMENT 性别:0男1女
);-- 向user表插入数据
INSERT INTO user (username, gender) VALUES
(赵六, 1),
(陈七, 0),
(宝国, 1);2、创建一个maven工程向pom.xml中添加依赖
!--锁定SpringBoot版本--
parentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion2.7.10/versionrelativePath/ !-- lookup parent from repository --
/parentdependencies!--jdbc起步依赖--dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-jdbc/artifactId
/dependency!--test起步依赖--dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactId/dependency!--mysql驱动--dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion8.0.20/version/dependency!--lombok--dependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactId/dependency!--jdbc起步依赖--dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-jdbc/artifactId/dependency
/dependencies3、编写实体类
package cn.aopmin.entity;import lombok.*;/*** 实体类** author 白豆五* since 2024/7/4*/
Data
Builder
NoArgsConstructor
AllArgsConstructor
ToString
public class User {private Integer id;private String username;private Integer gender;
}4、创建application.yml文件配置数据源
spring:#动态数据源配置datasource:ds1:driverClassName: com.mysql.cj.jdbc.DriverjdbcUrl: jdbc:mysql://localhost:3306/ds1?serverTimezoneAsia/ShanghaiuseUnicodetruecharacterEncodingutf8useSSLfalseusername: rootpassword: 123456ds2:driverClassName: com.mysql.cj.jdbc.DriverjdbcUrl: jdbc:mysql://localhost:3306/ds2?serverTimezoneAsia/ShanghaiuseUnicodetruecharacterEncodingutf8useSSLfalseusername: rootpassword: 123456logging:level:cn.aopmin: debug5、编写数据源配置类
package cn.aopmin.config;import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;/*** 数据源配置类* 配置多数据源和动态数据源** author 白豆五* since 2024/7/4*/
Configuration
public class DataSourceConfig {//定义数据源1Bean(ds1)ConfigurationProperties(prefix spring.datasource.ds1)public DataSource ds1() {return DataSourceBuilder.create().build();}//定义数据源2Bean(ds2)ConfigurationProperties(prefix spring.datasource.ds2)public DataSource ds2() {return DataSourceBuilder.create().build();}//定义动态数据源Bean(name dataSource)public DataSource dynamicDataSource(Qualifier(ds1) DataSource ds1,Qualifier(ds2) DataSource ds2) {//1.定义数据源mapMapObject, Object targetDataSources new HashMap();targetDataSources.put(ds1, ds1);targetDataSources.put(ds2, ds2);//2.实例化自定义的DynamicDataSource对象, 并设置数据源mapDynamicDataSource dynamicDataSource new DynamicDataSource();dynamicDataSource.setTargetDataSources(targetDataSources);//3.设置默认数据源,未匹配上则使用默认数据源dynamicDataSource.setDefaultTargetDataSource(ds1);return dynamicDataSource;}// 通过JdbcTemplate Beanpublic JdbcTemplate jdbcTemplate(Qualifier(dataSource) DataSource ds) {return new JdbcTemplate(ds);}
}6、创建DynamicDataSource动态数据类
package cn.aopmin.config;import cn.aopmin.common.DataSourceContextHolder;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;/*** AbstractRoutingDataSource(抽象的数据源路由器) 的基本原理是, 它维护了一个数据源的集合每个数据源都有唯一的一个标识符* 当应用程序需要访问数据库的时候,AbstractRoutingDataSource会根据某种匹配规则例如请求参数、用户身份等来选择一个合适的数据源* 并将请求转发给这个数据源。*/
public class DynamicDataSource extends AbstractRoutingDataSource {/*** 获取数据源名称* return*/Overrideprotected Object determineCurrentLookupKey() {return DataSourceContextHolder.getDataSource();}
}7、定义一个ThreadLocal工具类
package cn.aopmin.common;/*** 使用ThreadLocal保存数据源名称** author 白豆五* since 2024/7/4*/
public class DataSourceContextHolder {private static final ThreadLocalString contextHolder new ThreadLocal();// 将数据源名称绑定到当前线程上public static void setDataSource(String dataSourceName) {contextHolder.set(dataSourceName);}// 获取当前线程上的数据源名称public static String getDataSource() {return contextHolder.get();}// 清除数据源名称public static void clearDataSource() {contextHolder.remove();}
}8、创建启动类
package cn.aopmin;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;/*** 启动类** author 白豆五* since 2024/7/3*/
SpringBootApplication
public class Demo01Application {public static void main(String[] args) {SpringApplication.run(Demo01Application.class, args);}
}9、创建UserService
package cn.aopmin.service;import cn.aopmin.common.DataSourceContextHolder;
import cn.aopmin.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;/*** author 白豆五* since 2024/7/4*/
Service
public class UserService {Autowiredprivate JdbcTemplate jdbcTemplate;public void insertDs1(User user) {try {// todo:自定义注解SpringAop实现数据源的切换DataSourceContextHolder.setDataSource(ds1);String sql insert into user(username,gender) values(?,?);jdbcTemplate.update(sql,user.getUsername(), user.getGender());} finally {DataSourceContextHolder.clearDataSource();}}public void insertDs2(User user) {try {DataSourceContextHolder.setDataSource(ds2);String sql insert into user(username,gender) values(?,?);jdbcTemplate.update(sql,user.getUsername(), user.getGender());} finally {DataSourceContextHolder.clearDataSource();}}
}10、编写测试
package cn.aopmin.service;import cn.aopmin.Demo01Application;
import cn.aopmin.entity.User;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;import javax.annotation.Resource;SpringBootTest(classes {Demo01Application.class})
public class UserServiceTest {Resourceprivate UserService userService;Testpublic void testInsertDs1() {User user new User();user.setUsername(jack);user.setGender(0);user.setGender(1);userService.insertDs1(user);}Testpublic void testInsertDs2() {User user new User();user.setUsername(rose);user.setGender(1);userService.insertDs2(user);}
}最终效果 3. 基于Dynamic-datasource实现方案 mp文档https://baomidou.com/guides/dynamic-datasource/#_top 1、创建SpringBoot工程引入Dynamic-datasource依赖
dependencygroupIdcom.baomidou/groupIdartifactIddynamic-datasource-spring-boot-starter/artifactIdversion3.5.2/version
/dependency2、配置数据源
spring:#多数据源配置datasource:dynamic:primary: master #设置默认数据源strict: false #是否严格检查动态数据源提供的数据库名datasource:#数据源1master:url: jdbc:mysql:///ds1?useUnicodetruecharacterEncodingutf-8useSSLfalseserverTimezoneAsia/Shanghaiusername: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driver#数据源2slave1:url: jdbc:mysql:///ds2?useUnicodetruecharacterEncodingutf-8useSSLfalseserverTimezoneAsia/Shanghaiusername: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driver3、实体类
package cn.aopmin.entity;import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;/*** 实体类** author 白豆五* since 2024/7/4*/
Data
Builder
NoArgsConstructor
AllArgsConstructor
public class User {private Integer id;private String username;private Integer gender;
}4、业务类
package cn.aopmin.service;import cn.aopmin.entity.User;
import com.baomidou.dynamic.datasource.annotation.DS;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;/*** 通过DS注解切换数据源* author 白豆五* since 2024/7/4*/
Service
// DS(master) //不加DS注解会使用默认数据源
public class UserService {Autowiredprivate JdbcTemplate jdbcTemplate;public void insertDs1(User user) {String sql insert into user(username,gender) values(?,?);jdbcTemplate.update(sql,user.getUsername(), user.getGender());}DS(slave1)public void insertDs2(User user) {String sql insert into user(username,gender) values(?,?);jdbcTemplate.update(sql,user.getUsername(), user.getGender());}
}4、测试类
package cn.aopmin.service;import cn.aopmin.entity.User;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;import javax.annotation.Resource;SpringBootTest
public class UserServiceTest2 {Resourceprivate UserService userService;Testpublic void testInsertDs1() {User user new User();user.setUsername(jack);user.setGender(0);user.setGender(1);userService.insertDs1(user);}Testpublic void testInsertDs2() {User user new User();user.setUsername(rose);user.setGender(1);userService.insertDs2(user);}
}