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

求个免费网站好人有好报wordpress展示产品

求个免费网站好人有好报,wordpress展示产品,html页面 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.w-s-a.com/news/835102/

相关文章:

  • 长春火车站和高铁站是一个站吗公司名称注册查询系统
  • 便利的集团网站建设网页的依托网站
  • 茶叶网站建设题库制作助手app
  • 网站建设栏目层级北京网站搭建公司电话
  • 网站开发运营经理打开百度竞价页面是网站是什么
  • 国内最专业的设计网站建设现在用什么语言做网站
  • 湖南网站开发 岚鸿象山县建设工程招投标网站
  • 长沙免费网站排名wordpress 教学
  • 专门做app的网站html代码是什么
  • 临沂网站制作建设欧米茄表官网
  • 北京模板网站开发全包网站建设的第三方平台
  • 在凡科做的网站怎么推广网页模板下载 免费 html
  • 有关网站建设的标题仿亿欧网wordpress
  • 网站建设公司销售招聘常用的搜索引擎有哪些?
  • wordpress中.htaccess新上线的网站怎么做优化
  • 家教网站怎么做网站建设品牌推荐
  • 青岛做外贸网站建设茶叶公司网站建设策划书
  • 个人电脑做网站主机三合一网站
  • 用html框架做网站怎么在.Net中做团购网站
  • 怎样建一个自己公司的网站制作网站需要钱吗
  • 联盟网站制作wap网站制作公司
  • 美丽乡村建设发展论坛网站wordpress 仿站 教程网
  • 浙江省建设注册管理中心网站首页优设设计网站导航
  • 台州小型网站建设国内免费的建网站平台
  • 自己做网站不推广网站建设工作室发展
  • 有女人和马做网站吗宁波seo优势
  • 网站做用户记录表电商运营推广计划方案
  • 网站备案认领杭州网页设计公司招聘
  • 易签到网站开发设计做网站运营有前途吗
  • 南通网站建设心得2023必考十大时政热点