当前位置: 首页 > news >正文

盐城网站建设服务php商城

盐城网站建设服务,php商城,深圳小企业网站建设,wordpress调整行间距如来说世界#xff0c;非世界#xff0c;是名世界 如来说目录#xff0c;非目录#xff0c;是名目录 前言前期准备代码实现演示扩展 前言 本篇博客基于SpringBoot整合MyBatis-plus#xff0c;如果有不懂这个的#xff0c; 可以查看我的这篇博客#xff1a;快速CRUD的秘诀…如来说世界非世界是名世界 如来说目录非目录是名目录 前言前期准备代码实现演示扩展 前言 本篇博客基于SpringBoot整合MyBatis-plus如果有不懂这个的 可以查看我的这篇博客快速CRUD的秘诀之SpringBoot整合MyBatis-Plus MyBatis-Plus官方推荐的简单切换数据源可以参考上期博客SpringBoot快速集成多数据源(自动版) 那么问题来了我上期博客已经实现过一次多数据源切换了并且非常简单为什么还要出一期定制版呢 是这样的在上一期博客中通过DS注解在不同的方法上然后再通过调用不同的方法来实现调用不同的数据源 那么如果有8个数据源呢是不是要写8个方法8个判断呢 那如果再有8个业务需要切换数据源呢想想头就大了 所以到底有没有方法能够简化代码呢反正切换大概都是一样的逻辑。 本博主灵光一现这篇博客也就应运而生了 当然如果已经规定好了哪些业务用哪些数据源不存在同一个业务要根据不同的用户来切换的烦恼您就用官方推荐的方式吧甭折腾了 前期准备 跟上期同样为了实现效果先在本地的mysql库里面创建两个数据库 然后在两个数据库里面分别创建同样的users表但是插入不同的数据 mydb的数据 mydb2的数据 代码实现 1.在pom.xml文件中引入AOP所需的依赖aspectjweaver !-- 使用AOP来增强对象 -- dependencygroupIdorg.aspectj/groupIdartifactIdaspectjweaver/artifactIdversion1.9.7/version /dependency2.在application.yml中进行配置 server:port: 8080# 配置数据源 spring:datasource:master:# 数据库路径jdbc:mysql://localhost:3306/mydb 的缩写,并配置时区jdbc-url: jdbc:mysql:///mydb?serverTimezoneGMT%2B8username: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driver # 3.2.0开始支持SPI可省略此配置slave:jdbc-url: jdbc:mysql:///mydb2?serverTimezoneGMT%2B8username: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driver# 打印MyBatis SQL 日志 logging:level:com.guqueyue.dynamicdatasourcetest.dao: debug # 写接口的包名这里需要注意的是数据源的路径名不能用url要用jdbc-url 3.编写DataSourceType类用以设置数据源 package com.guqueyue.dynamicdatasourcetest.config;import lombok.extern.slf4j.Slf4j;/*** Author: guqueyue* Description: 用以设置数据源* Date: 2023/12/25**/ Slf4j public class DataSourceType {// 内部枚举类用以选择特定的数据源public enum DataBaseType {master,slave}// 使用ThreadLocal保证线程安全private static final ThreadLocalDataBaseType TYPE new ThreadLocal();// 往当前线程中设置数据源类型public static void setDataBaseType(DataBaseType dataBaseType) {if (dataBaseType null) {throw new NullPointerException();}TYPE.set(dataBaseType);log.info(\033[31;0;42;30;1;2;3;4;41m 线程:[ Thread.currentThread().getName() ],取了[ getDataBaseType() ]这个数据源);}// 获取数据源类型public static DataBaseType getDataBaseType() {return TYPE.get() null ? DataBaseType.master : TYPE.get();}// 清空数据源类型public static void clearDataBaseType() {TYPE.remove();} } 4.扩展determineCurrentLookupKey()方法来实现数据源的切换 package com.guqueyue.dynamicdatasourcetest.config;import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;/*** Author: guqueyue* Description: 通过扩展determineCurrentLookupKey()方法来实现数据源的切换* Date: 2023/12/25**/ public class DynamicDataSource extends AbstractRoutingDataSource {Overrideprotected Object determineCurrentLookupKey() {return DataSourceType.getDataBaseType();} } 5.重头戏编写多数据源配置类DynamicDataSourceConfig: package com.guqueyue.dynamicdatasourcetest.config;import com.baomidou.mybatisplus.core.config.GlobalConfig; import com.baomidou.mybatisplus.extension.incrementer.OracleKeyGenerator; import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionTemplate; import org.mybatis.spring.annotation.MapperScan; 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.context.annotation.DependsOn; import org.springframework.context.annotation.Primary; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.jdbc.datasource.DataSourceTransactionManager;import javax.sql.DataSource; import java.util.HashMap; import java.util.Map;/*** Author: guqueyue* Description: 多数据源配置类* Date: 2023/12/25**/ Configuration MapperScan(basePackages com.guqueyue.dynamicdatasourcetest.dao, sqlSessionFactoryRef SqlSessionFactory) // basePackages为接口地址 public class DynamicDataSourceConfig {// 将这个对象放入Spring容器中Bean(name masterDataSource)// 表示这个数据源为默认数据源Primary// 读取 application.yml 中的配置参数映射成为一个对象// prefix表示配置文件中参数的前缀ConfigurationProperties(prefix spring.datasource.master)public DataSource getMasterDataSource() {return DataSourceBuilder.create().build();}Bean(name slaveDataSource)ConfigurationProperties(prefix spring.datasource.slave)public DataSource getSlaveDataSource() {return DataSourceBuilder.create().build();}Bean(name dynamicDataSource)public DynamicDataSource dataSource(Qualifier(masterDataSource) DataSource masterDataSource, Qualifier(slaveDataSource) DataSource slaveDataSource) {// 核心点: targetDataSource为 数据源和注入的Bean 之间的映射MapObject, Object targetDataSource new HashMap();targetDataSource.put(DataSourceType.DataBaseType.master, masterDataSource);targetDataSource.put(DataSourceType.DataBaseType.slave, slaveDataSource);DynamicDataSource dataSource new DynamicDataSource();dataSource.setTargetDataSources(targetDataSource);dataSource.setDefaultTargetDataSource(masterDataSource); // 设置默认数据源return dataSource;}Bean(name SqlSessionFactory)DependsOn(globalConfig) // 明确调用顺序在调用本方法前先调用 globalConfig() 方法public SqlSessionFactory sqlSessionFactory(Qualifier(dynamicDataSource) DataSource dynamicDataSource) throws Exception {// SqlSessionFactoryBean bean new SqlSessionFactoryBean();MybatisSqlSessionFactoryBean bean new MybatisSqlSessionFactoryBean();bean.setDataSource(dynamicDataSource);// 设置xml文件路径 // bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(classpath*:mapper/*.xml));bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(classpath*:com/guqueyue/dynamicdatasourcetest/dao/*.xml));// 设置别名的扫描 - 实体类的包名引用bean.setTypeAliasesPackage(com.guqueyue.dynamicdatasourcetest.entity);bean.setGlobalConfig(globalConfig());return bean.getObject();}/*** Description 解决Oracle数据库下用 KeySequence注解 实现主键序列自增失效 问题解决* Param []* return com.baomidou.mybatisplus.core.config.GlobalConfig**/Beanpublic GlobalConfig globalConfig() {GlobalConfig globalConfig new GlobalConfig();globalConfig.setDbConfig(new GlobalConfig.DbConfig().setKeyGenerator(new OracleKeyGenerator()));return globalConfig;}Bean(name sqlSessionTemplate)Primary // 首选public SqlSessionTemplate sqlSessionTemplate(Qualifier(SqlSessionFactory) SqlSessionFactory sqlSessionFactory) {return new SqlSessionTemplate(sqlSessionFactory);}/*** Description 事务管理* Param [dataSource]* return org.springframework.jdbc.datasource.DataSourceTransactionManager**/Bean(name dataSourceTransactionManager)Primary // 首选public DataSourceTransactionManager dataSourceTransactionManager(Qualifier(dynamicDataSource) DataSource dataSource) {return new DataSourceTransactionManager(dataSource);} } 6.编写自定义注解 关于自定义注解的了解可以参考我的这篇博客框架的灵魂之注解基础篇 package com.guqueyue.dynamicdatasourcetest.annotation;import java.lang.annotation.*;/*** Author: guqueyue* Description: 自定义注解用以切换数据源* Date: 2023/12/25**/ Target({ElementType.METHOD}) // 注解使用范围为方法 Retention(RetentionPolicy.RUNTIME) // 注解的生命周期为运行时 Documented public interface MyDataSource {// DataSourceType.DataBaseType value() default DataSourceType.DataBaseType.master; // 默认使用master库 } 7.进行自定义注解拦截使用AOP来增强对象 这里有一个核心逻辑我们根据MyDataSource 自定义注解拦截方法然后根据方法所传的第一个参数值来判断使用哪个数据源。 这样我们就不用编写很多方法了。当然如果没找到就默认为主数据源。 package com.guqueyue.dynamicdatasourcetest.aop;import com.guqueyue.dynamicdatasourcetest.annotation.MyDataSource; import com.guqueyue.dynamicdatasourcetest.config.DataSourceType; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component;/*** Author: guqueyue* Description: 自定义注解拦截使用AOP来增强对象* Date: 2023/12/25**/ Slf4j Aspect Component public class DynamicDataSourceAspect {// 拦截自定义注解, annotation()里面是注解的路径需要根据你自己的替换Before(annotation(com.guqueyue.dynamicdatasourcetest.annotation.MyDataSource))public void changeDataSource(JoinPoint point) {// // 获取增强方法 // MethodSignature methodSignature (MethodSignature) point.getSignature(); // // 获取增强方法的反射对象 // Method method methodSignature.getMethod(); // // 获取MyDataSource注解 // MyDataSource myDataSource method.getAnnotation(MyDataSource.class);String dataSourceType master;// 获取方法的第一个参数Object[] args point.getArgs();if (args ! null args.length 0) {dataSourceType args[0].toString();}// 选择数据源switch (dataSourceType) {case slave:DataSourceType.setDataBaseType(DataSourceType.DataBaseType.slave);break;default: // 默认为主数据源DataSourceType.setDataBaseType(DataSourceType.DataBaseType.master);break;}}// 在方法执行完之后清除特定数据源的配置使用默认数据源After(annotation(myDataSource))public void restoreDataSource(JoinPoint point, MyDataSource myDataSource) {DataSourceType.clearDataBaseType();} }总体实现下来的项目结构为 演示 1.控制层代码 package com.guqueyue.dynamicdatasourcetest.controller;import com.guqueyue.dynamicdatasourcetest.entity.User; import com.guqueyue.dynamicdatasourcetest.service.IUserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import java.util.List;/*** Author: guqueyue* Description: 用户控制层* Date: 2023/12/25**/ RestController RequestMapping(/user) public class UserController {Autowiredprivate IUserService userService;/*** 查询用户列表* return*/RequestMapping(/list)public ListUser userList(String type) {return userService.selectUserList(type);} }2.service接口 package com.guqueyue.dynamicdatasourcetest.service;import com.baomidou.mybatisplus.extension.service.IService; import com.guqueyue.dynamicdatasourcetest.entity.User;import java.util.List;/*** Author: guqueyue* Description: 用户service接口* Date: 2023/12/25**/ public interface IUserService extends IServiceUser {ListUser selectUserList(String type); }3.service实现类 package com.guqueyue.dynamicdatasourcetest.service.impl;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.guqueyue.dynamicdatasourcetest.annotation.MyDataSource; import com.guqueyue.dynamicdatasourcetest.dao.UserMapper; import com.guqueyue.dynamicdatasourcetest.entity.User; import com.guqueyue.dynamicdatasourcetest.service.IUserService; import org.springframework.stereotype.Service;import javax.annotation.Resource; import java.util.List;/*** Author: guqueyue* Description: 用户实现类* Date: 2023/12/25**/ Service public class UserServiceImpl extends ServiceImplUserMapper, User implements IUserService {Resourceprivate UserMapper userMapper;Overridepublic ListUser selectUserList(String type) {// do something: 此处可根据实际情况进行业务选择如根据当前登录的用户信息来选择不同的数据库// 此处为了方便演示直接用前端传入的type来判断return userMapper.selectUserList(type);} }4.dao层 package com.guqueyue.dynamicdatasourcetest.dao;import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.guqueyue.dynamicdatasourcetest.annotation.MyDataSource; import com.guqueyue.dynamicdatasourcetest.entity.User; import org.apache.ibatis.annotations.Select;import java.util.List;/*** Author: guqueyue* Description: 映射接口UserMapper* Date: 2023/12/25**/ public interface UserMapper extends BaseMapperUser {MyDataSourceSelect(SELECT id,password,username FROM users)ListUser selectUserList(String type); }5.启动项目看效果 根据之前自定义注解拦截时编写的逻辑我们会根据selectUserList()方法中的第一个参数type来决定取哪个数据源。 话不多说项目启动 在控制台看到tomcat在你配置的端口号上启动了说明项目启动成功了 Tomcat started on port(s): 8080 (http) with context path 在浏览器输入http://localhost:8080/user/list?typemaster 可以看到控制台打印 浏览器返回 再在浏览器输入http://localhost:8080/user/list?typeslave 可以看到控制台打印 浏览器返回 说明成功切换了不同的数据源 扩展 本文在演示的时候在dao层使用的是Select注解来执行SQL语句并没有使用xml文件。 如需使用xml文件执行SQL语句的话 可以参照我的这篇博客快速CRUD的秘诀之SpringBoot整合MyBatis-Plus 的扩展部分。 但不同的是需要在多数据源配置类DynamicDataSourceConfig的sqlSessionFactory()方法中进行配置而不是applicaton.yml配置文件中 Bean(name SqlSessionFactory)DependsOn(globalConfig) // 明确调用顺序在调用本方法前先调用 globalConfig() 方法public SqlSessionFactory sqlSessionFactory(Qualifier(dynamicDataSource) DataSource dynamicDataSource) throws Exception {// SqlSessionFactoryBean bean new SqlSessionFactoryBean();MybatisSqlSessionFactoryBean bean new MybatisSqlSessionFactoryBean();bean.setDataSource(dynamicDataSource);// 设置xml文件路径 // bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(classpath*:mapper/*.xml));bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(classpath*:com/guqueyue/dynamicdatasourcetest/dao/*.xml));// 设置别名的扫描 - 实体类的包名引用bean.setTypeAliasesPackage(com.guqueyue.dynamicdatasourcetest.entity);bean.setGlobalConfig(globalConfig());return bean.getObject();}将这两行代码根据你的实际情况修改即可 // 设置xml文件路径 // bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(classpath*:mapper/*.xml));bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(classpath*:com/guqueyue/dynamicdatasourcetest/dao/*.xml));// 设置别名的扫描 - 实体类的包名引用bean.setTypeAliasesPackage(com.guqueyue.dynamicdatasourcetest.entity);我们下期博客再见
http://www.zqtcl.cn/news/37233/

相关文章:

  • 网站开发者工具的网络选项tornado 做网站
  • 赣州建网站机械设计网
  • 有什么好的网站做旅行计划好的高端网站
  • 会展官方网站建设免费网址大全免费观看
  • WordPress自媒体MNews大型网站建设优化排名
  • 怎么进入公司网站网站注册备案查询
  • 如何确保网站安全南宁3及分销网站制作
  • 郑州网站关键词优化外包网站推广方案中确定目标是指
  • 一个网站主机多少钱一年上海建设机械网站
  • 建的网站打开很慢福州网站制作案例
  • 大连网站建设dl zw网站开发推进计划表
  • 商洛网站建设公司上海工商网查询官网
  • 温州企业建站程序西安网络公司
  • 医院网站和公众号建设方案有没有做任务能兑换现金的网站
  • 软件培训网站建设企业管理课程培训
  • 南昌网站设计单位公司黄冈黄页88网黄冈房产估价
  • 做企业网站排名优化要多少钱昆明云南微网站建设
  • 南宁商城网站建设简述网站建设的概念
  • 做设计有必要买素材网站会员吗太原在建
  • php自己做网站访问量计算珠海建设网站公司
  • 上海松江建设工程开发有限公司网站wordpress建的大型网站
  • 海南建设局网站抖音推广佣金平台
  • 做最精彩的绳艺网站大学生网页设计大赛作品
  • 去公司叫自己做网站不会做附近哪有学编程的地方
  • 光泽网站建设wzjseo做网站 做app
  • 网站域名怎么申请银川网站建设公司哪家不错
  • 网站流量钱是谁给的关键词的优化方法
  • 果洛wap网站建设宁波妇科医院
  • 国内很多网站不是响应式邯郸之战
  • 大型旅行社自建网站中国新闻社是什么级别媒体