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

wordpress 站内资讯企业咨询管理公司是干嘛的

wordpress 站内资讯,企业咨询管理公司是干嘛的,wordpress主题进的慢,旅游+网站建设整体思路#xff1a; 引入基本依赖SpringBootAopMySqlMyBatislombok在配置文件中配置多个数据源创建数据源配置类用于读取配置编写用于标识切换数据源的注解创建数据源切换工具类DataSourceContextHolder编写切面类用于在注解生效处切换数据源编写配置类#xff0c;加载数据…整体思路 引入基本依赖SpringBootAopMySqlMyBatislombok在配置文件中配置多个数据源创建数据源配置类用于读取配置编写用于标识切换数据源的注解创建数据源切换工具类DataSourceContextHolder编写切面类用于在注解生效处切换数据源编写配置类加载数据源创建动态数据源类并继承AbstractRoutingDataSource指定使用哪个数据源关键 项目demo gitee地址多数据源动态切换demo 1.引入依赖 dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactIdversion2.7.10/version/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-aop/artifactIdversion2.7.10/version/dependencydependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion8.0.21/version/dependencydependencygroupIdorg.mybatis.spring.boot/groupIdartifactIdmybatis-spring-boot-starter/artifactIdversion2.1.3/version/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdversion1.18.22/version/dependencydependencygroupIdcom.alibaba/groupIdartifactIddruid/artifactIdversion1.2.20/version/dependency 2.在配置文件中配置多个数据源 这里配置了上海深圳北京3个数据源需要自己创建这3个库multi-shmulti-szmulti-bj #默认数据源 datasource.defaultsh #上海库 spring.datasource.sh.urljdbc:mysql://localhost:3306/multi-sh?useUnicodetruecharacterEncodingutf-8useSSLfalseserverTimezoneUTC spring.datasource.sh.driver-class-namecom.mysql.cj.jdbc.Driver spring.datasource.sh.usernameroot spring.datasource.sh.password123#深圳库 spring.datasource.sz.urljdbc:mysql://localhost:3306/multi-sz?useUnicodetruecharacterEncodingutf-8useSSLfalseserverTimezoneUTC spring.datasource.sz.driver-class-namecom.mysql.cj.jdbc.Driver spring.datasource.sz.usernameroot spring.datasource.sz.password123#北京库 spring.datasource.bj.urljdbc:mysql://localhost:3306/multi-bj?useUnicodetruecharacterEncodingutf-8useSSLfalseserverTimezoneUTC spring.datasource.bj.driver-class-namecom.mysql.cj.jdbc.Driver spring.datasource.bj.usernameroot spring.datasource.bj.password123 3.创建数据源配置类用于读取配置 spring获取统一前缀配置需要可以看我之前的文章SpringBoot项目获取统一前缀配置以及获取非确定名称配置 package com.gooluke.datasource;import lombok.Getter; import lombok.Setter; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component;import java.util.Map;/*** author gooluke*/ Setter Getter Component ConfigurationProperties(prefix spring) public class MultiDataSourceProperties {/*** 这里的datasource是因为配置是spring.datasource.xx.xx,要配置成datasource,这样才会把配置自动映射进来* 分别映射到url、driverClassName、username、password*/private MapString, DataSourceConfig datasource;SetterGetterpublic static class DataSourceConfig {private String url;private String driverClassName;private String username;private String password;} }4.编写用于标识切换数据源的注解 package com.gooluke.common.annotation;import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/*** author gooluke*/ Target({ElementType.METHOD, ElementType.TYPE}) Retention(RetentionPolicy.RUNTIME) public interface FixedDataSource {String value();/*** 是否需要还原回之前的数据源(拓展)*/boolean needRecover() default false;}5.创建数据源切换工具类DataSourceContextHolder package com.gooluke.datasource;import com.gooluke.config.DataSourceConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory;/*** author gooluke* 将数据源信息存放至ThreadLocal*/ public class DatasourceContextHolder {private static final Logger log LoggerFactory.getLogger(DatasourceContextHolder.class);private static final ThreadLocalString DATASOURCE_THREAD_LOCAL new ThreadLocal();public static void setDatasource(String datasource) {if (datasource ! null DataSourceConfig.dataSources.get(datasource) null) {String errorMsg String.format(数据源[%s]未配置, datasource);log.error(errorMsg);throw new RuntimeException(errorMsg);}DATASOURCE_THREAD_LOCAL.set(datasource);}public static String getDatasource() {return DATASOURCE_THREAD_LOCAL.get();}public static void clearDatasource() {DATASOURCE_THREAD_LOCAL.remove();} }6.编写切面类用于在注解生效处切换数据源 package com.gooluke.aspect;import com.gooluke.common.annotation.FixedDataSource; import com.gooluke.datasource.DatasourceContextHolder; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component;/*** author gooluke* 切换数据源切面类* 这个已不再使用使用com.gooluke.aop.DataSourceAnnotationAdvisor替代*/ Aspect Component public class DataSourceAspect {private static final Logger log LoggerFactory.getLogger(DataSourceAspect.class);/*** 注解加在方法上*/Pointcut(annotation(com.gooluke.common.annotation.FixedDataSource))private void methodPointCut() {}/*** 注解加在方法上*/Pointcut(within(com.gooluke.common.annotation.FixedDataSource))public void classPointcut() {}Around(value methodPointCut() || classPointcut())public Object around(ProceedingJoinPoint joinPoint) throws Throwable {//记录当前数据源和准备切换的数据源String oldDatasource DatasourceContextHolder.getDatasource();MethodSignature methodSignature (MethodSignature) joinPoint.getSignature();java.lang.reflect.Method method methodSignature.getMethod();FixedDataSource annotation method.getAnnotation(FixedDataSource.class);//方法上获取注解为空再从类上获取if (annotation null) {annotation method.getDeclaringClass().getAnnotation(FixedDataSource.class);}String newDatasource annotation.value();//切换数据源并执行操作DatasourceContextHolder.setDatasource(newDatasource);try {return joinPoint.proceed();} finally {//是否切换回初始数据源if (annotation.needRecover()) {DatasourceContextHolder.setDatasource(oldDatasource);}}} }7.编写配置类加载数据源 这个配置类主要就是将我们配置的多数据源解析然后统一管理dynamicDataSource.setTargetDataSources(targetDataSources); 以及设置默认数据源。 package com.gooluke.config;import com.alibaba.druid.pool.DruidDataSource; import com.gooluke.aop.DataSourceAnnotationAdvisor; import com.gooluke.aop.DataSourceAnnotationInterceptor; import com.gooluke.datasource.DynamicDataSource; import com.gooluke.datasource.MultiDataSourceProperties; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; 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 gooluke*/Configuration Slf4j public class DataSourceConfig {public static final MapString, String dataSources new HashMap();AutowiredMultiDataSourceProperties dataSourceProperties;Value(${datasource.default:})private String defaultDataSourceName;BeanPrimarypublic DynamicDataSource dynamicDataSource() {DynamicDataSource dynamicDataSource new DynamicDataSource();//存放所有数据源MapObject, Object targetDataSources new HashMap();MapString, MultiDataSourceProperties.DataSourceConfig datasourceMap dataSourceProperties.getDatasource();if (datasourceMap.entrySet().size() 1 (defaultDataSourceName null || defaultDataSourceName.isEmpty())) {throw new RuntimeException(存在多个数据源未配置默认数据源datasource.default);}datasourceMap.forEach((datasourceName, config) - {DataSource dataSource createDataSource(config);targetDataSources.put(datasourceName, dataSource);dataSources.put(datasourceName, datasourceName);log.info(已初始化数据库{}, datasourceName);if (datasourceMap.size() 1 || (defaultDataSourceName ! null !defaultDataSourceName.isEmpty() defaultDataSourceName.equals(datasourceName))) {//这里设置默认数据源dynamicDataSource.setDefaultTargetDataSource(dataSource);log.info(已设置默认数据源: {}, datasourceName);}});//这里把数据源统一管理dynamicDataSource.setTargetDataSources(targetDataSources);return dynamicDataSource;}private DataSource createDataSource(MultiDataSourceProperties.DataSourceConfig dataSourceConfig) {DruidDataSource dataSource new DruidDataSource();dataSource.setUrl(dataSourceConfig.getUrl());dataSource.setDriverClassName(dataSourceConfig.getDriverClassName());dataSource.setUsername(dataSourceConfig.getUsername());dataSource.setPassword(dataSourceConfig.getPassword());dataSource.setValidationQuery(SELECT 1);dataSource.setTestWhileIdle(true);dataSource.setTestOnBorrow(false);dataSource.setTestOnReturn(false);dataSource.setPoolPreparedStatements(true);dataSource.setMaxPoolPreparedStatementPerConnectionSize(20);return dataSource;}BeanPrimarypublic SqlSessionFactory sqlSessionFactory(DynamicDataSource dynamicDataSource) throws Exception {SqlSessionFactoryBean sessionFactory new SqlSessionFactoryBean();sessionFactory.setDataSource(dynamicDataSource);PathMatchingResourcePatternResolver resolver new PathMatchingResourcePatternResolver();org.springframework.core.io.Resource[] resources resolver.getResources(classpath:/mapper/*.xml);//org.springframework.core.io.Resource config resolver.getResource(classpath:mybatis-config.xml);sessionFactory.setMapperLocations(resources);//sessionFactory.setConfigLocation(config);return sessionFactory.getObject();}BeanPrimarypublic DataSourceTransactionManager transactionManager(DynamicDataSource dynamicDataSource) {return new DataSourceTransactionManager(dynamicDataSource);}}8.创建动态数据源类并继承AbstractRoutingDataSource指定使用哪个数据源关键 这里可以理解为就是一个口子让我们自己指定数据源如果你返回的是null则会指定我们配置类中设置的默认数据源dynamicDataSource.setDefaultTargetDataSource(dataSource); package com.gooluke.datasource;import lombok.extern.slf4j.Slf4j; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;/*** author gooluke* 动态数据源*/ Slf4j public class DynamicDataSource extends AbstractRoutingDataSource {/*** 这里返回ThreadLocal中的数据源*/Overrideprotected Object determineCurrentLookupKey() {return DatasourceContextHolder.getDatasource();}}9.请求完成后记得清空ThreadLocal否则会造成内存泄漏 编写一个拦截器在请求完成后remove package com.gooluke.interceptor;import com.gooluke.datasource.DatasourceContextHolder; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;/*** author gooluke*/ Component Slf4j public class DataSourceInterceptor implements HandlerInterceptor {Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {DatasourceContextHolder.clearDatasource();log.info(请求处理完成清除数据源);} }10.代码演示 将注解加在实现类方法上或者加在mapper/dao接口上一般加在这里因为dao接口一般都是操作同一个库这里指定了其它别的方法直接调用即可 10.1 service层 package com.gooluke.service.impl;import com.gooluke.dao.UserInfoDao; import com.gooluke.dao.UserInfoDao2; import com.gooluke.entity.TUserInfo; import com.gooluke.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;import java.util.List;/*** author gooluke*/ Service public class UserServiceImpl implements UserService {Autowiredprivate UserInfoDao userInfoDao;Autowiredprivate UserInfoDao2 userInfoDao2;/*** 在这里没有设置数据源dao层设置了数据源可以自动切换*/Overridepublic ListTUserInfo selectList() {//先查深圳库再查上海库ListTUserInfo tUserInfos userInfoDao.selectUserList(new TUserInfo());tUserInfos.forEach(System.out::println);ListTUserInfo tUserInfos2 userInfoDao2.selectUserList(new TUserInfo());tUserInfos2.forEach(System.out::println);tUserInfos.addAll(tUserInfos2);return tUserInfos;}}10.2 dao层 dao1指定深圳库: package com.gooluke.dao;import com.gooluke.common.annotation.FixedDataSource; import com.gooluke.common.constants.DataSourceName; import com.gooluke.entity.TUserInfo; import org.apache.ibatis.annotations.Mapper;import java.util.List;/*** author gooluke*/ Mapper FixedDataSource(DataSourceName.SHENZHEN) public interface UserInfoDao {ListTUserInfo selectUserList(TUserInfo userInfo);}dao2指定上海库: package com.gooluke.dao;import com.gooluke.common.annotation.FixedDataSource; import com.gooluke.common.constants.DataSourceName; import com.gooluke.entity.TUserInfo; import org.apache.ibatis.annotations.Mapper;import java.util.List;/*** author gooluke*/ Mapper FixedDataSource(DataSourceName.SHANGHAI) public interface UserInfoDao2 {ListTUserInfo selectUserList(TUserInfo userInfo);}10.3 观察结果 切库成功分别查询了不同库的数据并在最后清空了ThreadLocal中的数据 11.动态数据源开源dynamic-datasource-spring-boot-starter 上面这种Aop的实现方式在注解加在service接口的方法上其实是不生效的当然也不建议加在service接口上通常是加在实现类类上或者方法上。而Mapper/Dao接口的实现类是通过mybatis动态代理生成的注解加在Mapper/Dao接口上是能生效的我没有找到为啥他的实现类可以的文章。而我们也可以通过别的方式把注解加在接口上的场景通过Aop拦截只是不建议。下面是开源组件-动态数据源 com.baomidou:dynamic-datasource-spring-boot-starter:3.3.2 的Aop方案有兴趣的可以去看一下他的源码我的工程里也是用的这种方案需要在配置类中声明bean 11.1 创建一个DataSourceAnnotationAdvisor去继承AbstractPointcutAdvisor类并实现BeanFactoryAware接口 11.2 重写getPointcut()、getAdvice()、setBeanFactory()方法 11.3 配置声明Bean Beanpublic DataSourceAnnotationAdvisor dataSourceAnnotationAdvisor() {DataSourceAnnotationInterceptor dataSourceAnnotationInterceptor new DataSourceAnnotationInterceptor();return new DataSourceAnnotationAdvisor(dataSourceAnnotationInterceptor);}
http://www.hkea.cn/news/14470286/

相关文章:

  • 黑龙江企业网站建设公司怎样免费建立网站
  • 北京东八区网站建设python做网站开发
  • 小说网站建设多少钱wordpress会员卡
  • 如何做外文网站专业的企业进销存软件比较好
  • 牡丹江站最大的源码分享平台
  • 枸杞网站的建设方案seo81
  • 苏州做i网站的网站首页文案模板
  • 做一个什么网站好山东机械加工网
  • dedecms做网站怎么查看1元建站
  • 网站建设推广的方法Wordpress双主题
  • 做网站做哪个网站建设的教材
  • 吉林科技网站建设公司网站建设费入哪个科目
  • 生成拼贴的网站广告公关公司
  • 做网站推广被骗中国纪检监察报价格
  • 济南建站公司效果专业网站制作公司咨询
  • 工程科技 网站设计浙江城乡建设网站
  • 北京网站建设公司华网制作作视频制作软件app手机版免费版
  • 上海外贸网站推广服务商城网站建设 数商云
  • php商务网站开发成都网站建设 四川冠辰网站建设
  • 昆山网站电商网站建设需求分析书
  • 天津做不锈钢的网站小公司做网站多少钱
  • 北京seo网站内部优化潍坊建设gc局网站
  • 哪些免费的网站可以做企业宣传工作图片
  • 西宁网站推广网站没更新
  • 青岛即墨网站开发wordpress必备工具
  • 仪征建设局网站网页翻译功能
  • 营销型网站建设题库宁夏建设厅网站官网
  • jsp做电影网站wordpress在文章中加背景
  • 国外化工网站模板做推广网站多少钱
  • 怎么做地下彩票网站天元建设集团有限公司六大板块