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

网站需求表购物网站开发会遇到的的问题

网站需求表,购物网站开发会遇到的的问题,企业名录联系电话,广东圆心科技网站开发网站模板设计实现单库分表 思路#xff1a;student表数据量大#xff0c;所以将其进行分表处理。一共有三个分表#xff0c;分别是student0#xff0c;student1#xff0c;student2#xff0c;在新增数据的时候#xff0c;根据请求头中的meta-tenant参数决定数据存在哪张表表。 数…实现单库分表 思路student表数据量大所以将其进行分表处理。一共有三个分表分别是student0student1student2在新增数据的时候根据请求头中的meta-tenant参数决定数据存在哪张表表。 数据库 1. 建立数据库study1 2. 在数据库中建表分别为studentstudent0student1student2四个表结构都一样只是表名不一样 CREATE TABLE student (id int NOT NULL AUTO_INCREMENT,name varchar(50) DEFAULT NULL,age int DEFAULT NULL,credit varchar(14) DEFAULT NULL,tenant_id int DEFAULT NULL COMMENT 租户id,PRIMARY KEY (id) ) ENGINEInnoDB AUTO_INCREMENT4 DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_0900_ai_ci; 引入pom !-- https://mvnrepository.com/artifact/org.apache.shardingsphere/shardingsphere-jdbc-core-spring-boot-starter -- dependencygroupIdorg.apache.shardingsphere/groupIdartifactIdshardingsphere-jdbc-core-spring-boot-starter/artifactIdversion5.1.1/version /dependency配置文件application.yml #单库分表 spring:main:allow-bean-definition-overriding: trueshardingsphere:datasource:names: ds1ds1:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/study1?serverTimezoneUTCuseUnicodetruecharacterEncodingutf-8username: rootpassword: root1234mode:type: Memoryoverwrite: truerules:sharding:tables:student:actual-data-nodes: ds1.student$-{0..2}key-generate-strategy:column: idkey-generator-name: snowflakebinding-tables:- studentdefault-table-strategy:standard:sharding-algorithm-name: custom_inlinesharding-column: tenant_iddefault-sharding-column: tenant_idsharding-algorithms:custom_inline:type: CLASS_BASEDprops:strategy: STANDARDalgorithmClassName: com.cyy.config.TablePreciseShardingAlgorithmprops:sql-show: true tenant:enable: true #启用多租户column: tenant_id 实现标准分片算法接口 package com.cyy.config;import org.apache.shardingsphere.sharding.api.sharding.standard.PreciseShardingValue; import org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingValue; import org.apache.shardingsphere.sharding.api.sharding.standard.StandardShardingAlgorithm; import org.springframework.stereotype.Component;import java.util.Collection;/*** 标准分表算法*/ Component public class TablePreciseShardingAlgorithm implements StandardShardingAlgorithmInteger {Overridepublic String doSharding(CollectionString collection, PreciseShardingValueInteger preciseShardingValue) {String tableName preciseShardingValue.getLogicTableName().toLowerCase() (preciseShardingValue.getValue() %10);return tableName;}Overridepublic CollectionString doSharding(CollectionString collection, RangeShardingValueInteger rangeShardingValue) {return collection;}Overridepublic void init() {}Overridepublic String getType() {return null;} }配置租户上下文相关内容 用到的常量 package com.cyy.constant;/*** 多租户相关的常量*/ public class TenantConstant {public static final String META_TENANT_ID meta-tenant;public static final String META_TENANT_ID_PARAM tenantId;public static final Long TENANT_ID_DEFAULT 1l; }定义租户上下文 package com.cyy.config;/*** 定义租户上下文通过上下文保存当前租户的信息*/ public class TenantContextHolder {private static final ThreadLocalLong CONETXT_HOLDER new ThreadLocal();public static void set(Long l){CONETXT_HOLDER.set(l);}public static Long getTenantId(){return CONETXT_HOLDER.get();}public static void remove(){CONETXT_HOLDER.remove();} }设置多租户的相关的属性 package com.cyy.config;import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties;import java.util.HashSet; import java.util.Set;Data /*** 将配置文件中的属性自动映射都Java对象的字段中* 指定配置文件中的配置项的前缀为tenant简化Vlue注解不需要加很多的Value*/ ConfigurationProperties(prefix tenant) public class TenantProperties {//不需要加tenantid的mapper方法名public static SetString NOT_PROCEED new HashSet();//不需要加tenentid的表名public static SetString NOT_TABLES new HashSet();//是否开启多租户读取的是配置文件中的tenant.enable的值等价于Value(${tenant.enable})private boolean enable false;//多租户字段private String column tenant_id; }配置租户上下文拦截器 package com.cyy.interceptor;import com.cyy.config.TenantContextHolder; import com.cyy.config.TenantProperties; import com.cyy.constant.TenantConstant; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor;import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;/*** HandlerInterceptor是在handler处理请求之前或者之后执行的拦截器可以对请求做预处理或者对响应结果做统一处理实现日志记录或者权限认证等功能* HandlerInterceptor可以拦截所有的请求也可以只拦截特定的亲故*/ Slf4j Component public class TenantContextHandlerInterceptor implements HandlerInterceptor {Resourceprivate TenantProperties tenantProperties;public TenantContextHandlerInterceptor(){}/*** 在请求处理前设置租户上下文* param request current HTTP request* param response current HTTP response* param handler chosen handler to execute, for type and/or instance evaluation* return* throws Exception*/Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {log.info(对请求进行统一拦截);if (tenantProperties.isEnable()){//从请求头中获取tenantIdString tenantId request.getHeader(TenantConstant.META_TENANT_ID);if (StringUtils.isNotBlank(tenantId)){TenantContextHolder.set(Long.parseLong(tenantId));} else {TenantContextHolder.set(TenantConstant.TENANT_ID_DEFAULT);}log.info(获取到的租户id为【{}】,TenantContextHolder.getTenantId());}return true;}/*** 请求处理完成之后的回调* param request current HTTP request* param response current HTTP response* param handler handler (or {link HandlerMethod}) that started asynchronous* execution, for type and/or instance examination* param ex exception thrown on handler execution, if any* throws Exception*/Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {TenantContextHolder.remove();} }将租户上下文拦截器添加到springmvc配置中 对服务器的所有请求进行拦截从请求头的meta-tenant参数中获取tenant_id值并设置租户id package com.cyy.config;import com.cyy.interceptor.TenantContextHandlerInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import javax.annotation.Resource; import java.util.List;/*** 通过实现WebMvcConfigurer接口可以自定义springmvc的配置例如添加拦截器*/ Configuration public class CustomeConfig implements WebMvcConfigurer {Resourceprivate MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter;/*** TenantContextHandlerInterceptor类本身就是一个Bean在这块再次声明一个相同Bean的时候会报错* 可以在配置文件中添加配置allow-bean-definition-overriding: true允许bean定义覆盖* return*/Bean(tenantContextHandlerInterceptor)public HandlerInterceptor customerInterceptor(){return new TenantContextHandlerInterceptor();}/*** 添加拦截器* param registry*/Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(customerInterceptor());}Overridepublic void configureMessageConverters(ListHttpMessageConverter? converters) {converters.add(0,mappingJackson2HttpMessageConverter);} }配置mybatis的插件 继承多租户拦截器TenantLineInnerInterceptor package com.cyy.interceptor;import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler; import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor; import com.cyy.config.TenantContextHolder; import com.cyy.config.TenantProperties; import org.apache.ibatis.executor.Executor; import org.apache.ibatis.mapping.BoundSql; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.session.ResultHandler; import org.apache.ibatis.session.RowBounds;import java.sql.SQLException; import java.util.Objects;/*** 继承多租户拦截器*/ public class CustomTenantLineInnerInterceptor extends TenantLineInnerInterceptor {private TenantProperties tenantProperties;public TenantProperties getTenantProperties(){return tenantProperties;}public void setTenantProperties(TenantProperties tenantProperties){this.tenantProperties tenantProperties;}Overridepublic void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {if (TenantProperties.NOT_PROCEED.stream().anyMatch(s - s.equalsIgnoreCase(ms.getId()))){return;}if (Objects.isNull(TenantContextHolder.getTenantId())){return;}super.beforeQuery(executor, ms, parameter, rowBounds, resultHandler, boundSql);}public CustomTenantLineInnerInterceptor(final TenantProperties tenantProperties, final TenantLineHandler tenantLineHandler){super(tenantLineHandler);this.setTenantProperties(tenantProperties);this.setTenantLineHandler(tenantLineHandler);} }添加多租户拦截器到mybatisplus拦截器中 将多租户拦截器CustomTenantLineInnerInterceptor添加到MybatisPlusInterceptor的拦截器中 package com.cyy.config;import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler; import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor; import com.cyy.interceptor.CustomTenantLineInnerInterceptor; import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.LongValue; import org.mybatis.spring.annotation.MapperScan; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;import javax.annotation.Resource; import java.util.Objects;Configuration MapperScan(com.cyy.mapper) public class MybatisPlusConfig {Resourceprivate TenantProperties tenantProperties;Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor(){MybatisPlusInterceptor mybatisPlusInterceptor new MybatisPlusInterceptor();//添加多租户拦截器if (tenantProperties.isEnable()){mybatisPlusInterceptor.addInnerInterceptor(tenantLineInnerInterceptor());}//分页插件mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));//防止全表更新与删除插件mybatisPlusInterceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());//乐观锁插件mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());return mybatisPlusInterceptor;}public TenantLineInnerInterceptor tenantLineInnerInterceptor(){return new CustomTenantLineInnerInterceptor(tenantProperties, new TenantLineHandler() {/*** 获取租户id* return*/Overridepublic Expression getTenantId() {Long tenantId TenantContextHolder.getTenantId();if (Objects.nonNull(tenantId)){return new LongValue(tenantId);}return null;}/*** 获取多租户的字段名* return*/Overridepublic String getTenantIdColumn() {return tenantProperties.getColumn();}/*** 根据表名判断是否忽略拼接多租户条件* param tableName 表名* return*/Overridepublic boolean ignoreTable(String tableName) {return tenantProperties.NOT_TABLES.stream().anyMatch((t) - t.equalsIgnoreCase(tableName));}});} }测试代码  测试数据插入的controller package com.cyy.controller;import com.cyy.domain.Student; import com.cyy.service.StudentService; import com.cyy.util.RoundRobinUtil; import com.cyy.config.TenantContextHolder; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;/*** 学生类控制器*/ RestController RequestMapping(/student) public class StudentController {Resourceprivate StudentService studentService;/*** 多租户测试-插入一个用户*/PostMapping(/insert)public ResponseEntity insert(RequestBody Student student){student.setTenantId(TenantContextHolder.getTenantId().intValue());int i studentService.insert(student);if (i 0){return ResponseEntity.ok(插入成功);}return ResponseEntity.ok(插入失败);} }请求参数 {id: 3,name: 孙三,age: 3,credit: 3 } 请求头 运行结果
http://www.dnsts.com.cn/news/165111.html

相关文章:

  • 有哪些外国网站做精油的商城网站建设行业现状
  • 做宣传图册在什么网站网站建设 代表联系群众
  • 深圳住房和建设局网站轮候大厅wordpress打赏图片显示不了
  • wordpress 配置邮箱长沙seo优化价格
  • 怎么做网站访问被拒绝免费优化网站建设
  • 商城网站里可以再放cms吗游戏网站建设论文
  • 简述网站建设和推广评价指标西安网站建设推广服务
  • 佛山顺德网站制作公司哪家好广元市住房和城乡建设局网站
  • 网站 绝对路径 相对路径做网站视频手机
  • 广东专业高端网站建设中国兰州网招聘
  • 公司做的网站入哪个会计科目长沙房地产
  • 做珠宝网站价格多少wordpress学校模板
  • 模板网站如何建设php做视频网站
  • app网站有哪些佛山网站推广市场
  • 有什么网站开发软件wordpress 获取title
  • 网站备案地网站动态加速
  • 网站开发公司需要哪些资质网站用户体验优化方案
  • 江门seo网站排名wordpress ajax评论
  • 福州自适应网站建设制作网页模板
  • 陕西铜川煤矿建设有限公司网站网站中英文转换js
  • 做ppt的网站兼职dw可以做移动端网站
  • 镇江公司做网站优化网站服务
  • 网站开发语言介绍一台vps主机可以建设多少个网站
  • 网页设计师网站北京有实力的软件开发公司
  • 中山网站开发招聘广西桂林简介
  • 海南房产网站开发保定免费建站
  • 网站开发团队名称python做网站入门
  • 二手车 东莞网站建设wordpress 是否登录
  • 东莞桥头网站建设58同城网站建设案例
  • 精品课程网站建设方案在天极网做网站有效果吗