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

如何做网站的统计阜阳建设大厦网站

如何做网站的统计,阜阳建设大厦网站,赣州章贡区旅游景点,做餐饮在环保局网站备案多数据源产生的场景 一般情况下#xff0c;不会有多数据源这样的场景出现#xff0c;但老项目或者特殊需求的项目#xff0c;可能会有这样的场景 同一个应用需要访问两个数据库不用数据库中间件的读写分离 注入数据源选择的时机 声明两个数据源实例#xff0c;在getConnect…多数据源产生的场景 一般情况下不会有多数据源这样的场景出现但老项目或者特殊需求的项目可能会有这样的场景 同一个应用需要访问两个数据库不用数据库中间件的读写分离 注入数据源选择的时机 声明两个数据源实例在getConnection的时候根据业务的不同注入不同数据源的连接 环境准备 准备sql脚本建立两个库这里mysql为例 create database stu; create database tech; use stu; create table student (id varchar(50) not null comment 主键,name varchar(50) null comment 姓名,stu_no varchar(50) null comment 学号,constraint student_pk primary key (id) );insert into student values (1,张同学,111); insert into student values (2,李同学,222); use tech; create table teacher (id varchar(50) not null comment 主键,name varchar(50) null comment 姓名,teach_no varchar(50) null comment 教师号,constraint teacher_pk primary key (id) );insert into teacher values (1,王老师,111); insert into teacher values (2,高老师,222); 实现DataSource方式实现多数据源 配置多数据源 server:port: 9000 spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedatasource1:url: jdbc:mysql://shilei.tech:3306/stu?useSSLtrueserverTimezoneAsia/Shanghaiusername: rootpassword: root123456driver-class-name: com.mysql.cj.jdbc.Driverdatasource2:url: jdbc:mysql://shilei.tech:3306/tech?useSSLtrueserverTimezoneAsia/Shanghaiusername: rootpassword: root123456driver-class-name: com.mysql.cj.jdbc.Driverdruid:initial-size: 5min-idle: 1max-active: 20mybatis-plus:mapper-locations: classpath:/mapper/*.xmltype-aliases-package: com.datasource.dynamicdatasource.model添加数据源配置 package com.datasource.dynamicdatasource.config;import com.alibaba.druid.pool.DruidDataSource; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;import javax.sql.DataSource;/*** author sl*/ Configuration public class DataSourceConfig {Bean(dataSource1)ConfigurationProperties(prefix spring.datasource.datasource1)public DataSource dataSource1(){DruidDataSource druidDataSource new DruidDataSource();return druidDataSource;}Bean(dataSource2)ConfigurationProperties(prefix spring.datasource.datasource2)public DataSource dataSource2(){DruidDataSource druidDataSource new DruidDataSource();return druidDataSource;} }实现DataSource多数据源 package com.datasource.dynamicdatasource.config;import org.springframework.beans.factory.InitializingBean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary;import javax.annotation.Resource; import javax.sql.DataSource; import java.io.PrintWriter; import java.sql.Connection; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; import java.util.logging.Logger;/*** author sl* Primary主要注入的bean*/ Configuration Primary public class DynamicDataSource implements DataSource {public static ThreadLocalString nameFlag new ThreadLocal();Resourceprivate DataSource dataSource1;Resourceprivate DataSource dataSource2;Overridepublic Connection getConnection() throws SQLException {if(student.equals(nameFlag.get())){return dataSource1.getConnection();}return dataSource2.getConnection();}Overridepublic Connection getConnection(String username, String password) throws SQLException {return null;}Overridepublic T T unwrap(ClassT iface) throws SQLException {return null;}Overridepublic boolean isWrapperFor(Class? iface) throws SQLException {return false;}Overridepublic PrintWriter getLogWriter() throws SQLException {return null;}Overridepublic void setLogWriter(PrintWriter out) throws SQLException {}Overridepublic void setLoginTimeout(int seconds) throws SQLException {}Overridepublic int getLoginTimeout() throws SQLException {return 0;}Overridepublic Logger getParentLogger() throws SQLFeatureNotSupportedException {return null;} }测试多数据源 package com.datasource.dynamicdatasource.controller;import com.datasource.dynamicdatasource.config.DynamicDataSource; import com.datasource.dynamicdatasource.model.Student; import com.datasource.dynamicdatasource.model.Teacher; import com.datasource.dynamicdatasource.service.StudentService; import com.datasource.dynamicdatasource.service.TeacherService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController;import java.util.List;/*** author sl*/ RestController public class TestDataSourceController {Autowiredprivate StudentService studentService;Autowiredprivate TeacherService teacherService;GetMapping(/stu)public String getStu(){DynamicDataSource.nameFlag.set(student);ListStudent allStudent studentService.findAllStudent();return allStudent.toString();}GetMapping(/tech)public String getTech(){DynamicDataSource.nameFlag.set(teacher);ListTeacher allTeacher teacherService.findAllTeacher();return allTeacher.toString();} }效果如下所示 此实现方式的弊端 实现DataSource接口我们本质上只使用了一个方法就是getConnection()这个无参的方法其他方法当内部调用时可能会导致错误我们不可能实现所有的方法所以我们继承AbstractRoutingDataSource抽象类 继承AbstractRoutingDataSource实现多数据源 AbstractRoutingDataSource的结构 可以看到AbstractRoutingDataSource继承自DataSource提供了一些实现方法 AbstractRoutingDataSource的重要属性  targetDataSources 所有数据源 (需指定) defaultTargetDataSource 默认数据源(需指定) resolvedDataSources targetDataSources 负责最终切换的数据源map 等于 tagetDataSources 继承AbstractRoutingDataSource实现多数据源 package com.datasource.dynamicdatasource.config;import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;import javax.annotation.Resource; import javax.sql.DataSource; import java.util.HashMap; import java.util.Map;/*** author sl* Primary主要注入的bean*/ Configuration Primary public class DynamicDataSource extends AbstractRoutingDataSource {public static ThreadLocalString nameFlag new ThreadLocal();Resourceprivate DataSource dataSource1;Resourceprivate DataSource dataSource2;Overrideprotected Object determineCurrentLookupKey() {// 返回当前数据源的标识return nameFlag.get();}Overridepublic void afterPropertiesSet() {// 为targetDataSources 初始化所有数据源MapObject,Object targetDataSourcesnew HashMap();targetDataSources.put(student,dataSource1);targetDataSources.put(teacher,dataSource2);super.setTargetDataSources(targetDataSources);// 设置默认数据源super.setDefaultTargetDataSource(dataSource1);// 循环给resolvedDataSources也就是最终数据源mapsuper.afterPropertiesSet();} }determineCurrentLookupKey的作用  看一段源码就是通过determineCurrentLookupKey获取数据源的key然后去resolvedDataSources中取数据源resolvedDataSources数据源其实就是targetDataSources protected DataSource determineTargetDataSource() {Assert.notNull(this.resolvedDataSources, DataSource router not initialized);Object lookupKey determineCurrentLookupKey();DataSource dataSource this.resolvedDataSources.get(lookupKey);if (dataSource null (this.lenientFallback || lookupKey null)) {dataSource this.resolvedDefaultDataSource;}if (dataSource null) {throw new IllegalStateException(Cannot determine target DataSource for lookup key [ lookupKey ]);}return dataSource;} 测试多数据源 package com.datasource.dynamicdatasource.controller;import com.datasource.dynamicdatasource.config.DynamicDataSource; import com.datasource.dynamicdatasource.model.Student; import com.datasource.dynamicdatasource.model.Teacher; import com.datasource.dynamicdatasource.service.StudentService; import com.datasource.dynamicdatasource.service.TeacherService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController;import java.util.List;/*** author sl*/ RestController public class TestDataSourceController {Autowiredprivate StudentService studentService;Autowiredprivate TeacherService teacherService;GetMapping(/stu)public String getStu(){// 默认数据源就是studentListStudent allStudent studentService.findAllStudent();return allStudent.toString();}GetMapping(/tech)public String getTech(){DynamicDataSource.nameFlag.set(teacher);ListTeacher allTeacher teacherService.findAllTeacher();return allTeacher.toString();} }AOP自定义注解方式AbstractRoutingDataSource实现多数据源 数据源的切换还是使用AbstractRoutingDataSource只不过切换方式采用aop拦截自定义注解切换数据源这种方式也是mybatis-plus多数据源插件所采用的方式 自定义注解 package com.datasource.dynamicdatasource.annotation;import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/*** author sl*/ Target({ElementType.TYPE, ElementType.METHOD}) Retention(RetentionPolicy.RUNTIME) public interface MyDataSource {String value() default student; }配置切面 dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-aop/artifactId /dependency package com.datasource.dynamicdatasource.aspect;import com.datasource.dynamicdatasource.annotation.MyDataSource; import com.datasource.dynamicdatasource.config.DynamicDataSource; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.stereotype.Component;import java.lang.reflect.Method;/*** author sl*Aspect 标识是一个切面*/ Aspect Component public class DatasourceAspect {/*** 切点规则*/Pointcut(annotation(com.datasource.dynamicdatasource.annotation.MyDataSource))public void pointcut() {}Before(pointcut())public void dataSourceAspect(JoinPoint joinPoint){// 获取方法Method method ((MethodSignature) joinPoint.getSignature()).getMethod();// 判断方法中是否添加了注解if(method.isAnnotationPresent(MyDataSource.class)){// 获取方法上的注解MyDataSource annotation method.getAnnotation(MyDataSource.class);String value annotation.value();// 设置数据源DynamicDataSource.nameFlag.set(value);}} }测试自定义注解切换数据源 GetMapping(/tech)MyDataSource(teacher)public String getTech(){ListTeacher allTeacher teacherService.findAllTeacher();return allTeacher.toString();} dynamic-datasource多数据源组件实现多数据源 官方文档及搭建指南地址多数据源 | MyBatis-Plus 引入依赖 dependencygroupIdcom.baomidou/groupIdartifactIddynamic-datasource-spring-boot-starter/artifactIdversion3.6.1/version /dependency 配置数据源 server:port: 9000 spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedynamic:#设置默认的数据源或者数据源组,默认值即为masterprimary: master#严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源strict: falsedatasource:master:url: jdbc:mysql://shilei.tech:3306/stu?useSSLtrueserverTimezoneAsia/Shanghaiusername: rootpassword: root123456driver-class-name: com.mysql.cj.jdbc.Driverteacher:url: jdbc:mysql://shilei.tech:3306/tech?useSSLtrueserverTimezoneAsia/Shanghaiusername: rootpassword: root123456driver-class-name: com.mysql.cj.jdbc.Driverdruid:initial-size: 5min-idle: 1max-active: 20mybatis-plus:mapper-locations: classpath:/mapper/*.xmltype-aliases-package: com.datasource.dynamicdatasource.model测试数据源切换 数据源切换使用DS注解不使用此注解使用默认数据源方法上使用类上使用  package com.datasource.dynamicdatasource.controller;import com.baomidou.dynamic.datasource.annotation.DS; import com.datasource.dynamicdatasource.model.Student; import com.datasource.dynamicdatasource.model.Teacher; import com.datasource.dynamicdatasource.service.StudentService; import com.datasource.dynamicdatasource.service.TeacherService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController;import java.util.List;/*** author sl*/ RestController public class TestDataSourceController {Autowiredprivate StudentService studentService;Autowiredprivate TeacherService teacherService;GetMapping(/stu)public String getStu(){ListStudent allStudent studentService.findAllStudent();return allStudent.toString();}GetMapping(/tech)DS(teacher)public String getTech(){ListTeacher allTeacher teacherService.findAllTeacher();return allTeacher.toString();} }项目启动日志中可以看到两个数据源的加载信息 访问tech以及stu都能正常访问代表动态数据源添加成功 需要注意的问题 使用多数据源要注意事务的控制提交和回滚策略可以观看spring多数据源事务解决方案
http://www.w-s-a.com/news/116459/

相关文章:

  • 哈尔滨网站设计公司哪家更好shopify和wordpress
  • 岚县网站建设网站建设中效果
  • 网站建设软文推广网站建设分金手指排名十四
  • 网站建设要什么知识广州注册公司地址怎么解决
  • 自己可以做开奖网站吗wordpress和hexo
  • 成都网站关键词优化wordpress价格
  • 网站开发后端站建设 app开发网站
  • 毕业设计做网站好的想法开发网站代码量
  • 西宁网站建设排名wordpress的站点地址如何配置
  • 医院网站建设 价格app和网站开发的成本
  • 常见的网站开发工具山东建设厅官方网站李兴军
  • 二级院系网站建设情况做网站域名是什么意思
  • 网站开发双语辽宁省建设厅网站怎样下载表格
  • 网站后台密码怎么修改百度查重免费入口
  • 衡阳网站页面设计公司绍兴网站设计
  • 青岛手机建站多少钱做图表的网站 免费
  • 如何去建立和设计一个公司网站开封建设教育协会网站
  • 南充市住房和城乡建设局考试网站wordpress 下载模板站
  • 有没有单纯做旅游攻略的网站保定建站方案
  • 2017网站建设报价方案2022年企业所得税税率表一览
  • 可以做婚礼视频的网站有哪些工程公司管理制度
  • 做农产品网站需要做的准备中文手机网站设计案例
  • 福州做网站软件seo搜索优化专员招聘
  • 建站技术博客wordpress响应时间
  • 农业网站模板WordPress安徽省建设工程造价管理协会网站
  • 网站后台策划书破解版手游app平台
  • 宿迁网站建设介绍公司wordpress 文章 分类 页面
  • 建设通同类网站网站设计公司种类
  • 台州专业做网站网站可以个人做吗
  • 个人logo在线生成免费乐陵德州seo公司