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

如何提高网站点击率做网站横幅 的网站推荐几个

如何提高网站点击率,做网站横幅 的网站推荐几个,浦东区网站建设,安康那个公司做网站好前言 在没有使用ETL工具且不考虑多数据源的情况下#xff0c;我们需要从别的系统获取数据时#xff0c;一般会选择分页接口查询并存储。本文算是我对类似场景代码的提炼#xff0c;旨在总结相关套路#xff0c;提升自我对数据库和模块的设计能力。 ETL(英文 Extract-Trans…前言 在没有使用ETL工具且不考虑多数据源的情况下我们需要从别的系统获取数据时一般会选择分页接口查询并存储。本文算是我对类似场景代码的提炼旨在总结相关套路提升自我对数据库和模块的设计能力。 ETL(英文 Extract-Transform-Load 的缩写用来描述将数据从来源端经过抽取extract、转换transform、加载load至目的端的过程。数据仓库结构通俗的说法就是从数据源抽取数据出来进行清洗加工转换然后加载到定义好的数据仓库模型中去) 常规接口对接 接口对接推荐使用Feign常规写法如下 import org.springframework.cloud.openfeign.FeignClient; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody;/*** Author WangZY* Date 2021/8/10 10:51* Description 获取订单数据**/ Component FeignClient(name ${spring.application.name}GateWayApi, url ${gateway.url}) public interface GateWayFeign {PostMapping(value /ds-data-service/xxx, headers {API-TOKENxxxx})OrderLineResDTO getOrderLineToSmbgj(RequestBody OrderLineQueryDTO query); }生成对应的查询参数及结果类 NoArgsConstructor Data public class OrderLineResDTO {JsonProperty(data)private ListDataDTO data;JsonProperty(success)private Boolean success;JsonProperty(affectedRow)private String affectedRow;JsonProperty(errorCode)private Integer errorCode;JsonProperty(errorInfo)...... NoArgsConstructor Data public class OrderLineQueryDTO {...... 对应依赖及配置文件 dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-openfeign/artifactIdversionxxxx/version /dependency # 外部链接 gateway.urlhttp://service-gw.xxx.com.cn/api # 日志打印 logging.level.com.xxx.forecastdata.apidebug需求分类 全量翻新类–订单全流程定时项目已采用此方案并上线稳定运行 详细信息 数据定时任务通过接口接收或者翻新数据库全量数据逻辑删除以前的历史数据保留固定次数的历史数据 操作步骤 前提条件 项目使用Mybatis-Plus如果不是的话请自行替换对应SQL操作语句。该方案默认已提供MP的service层对接系统提供分页查询接口分布式调度(定时任务)采用elastic-job框架请自行替换对应组件 定时任务 import com.alibaba.fastjson.JSON; import com.dangdang.ddframe.job.api.ShardingContext; import com.dangdang.ddframe.job.api.simple.SimpleJob; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.springframework.stereotype.Component; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Date; import java.util.List;Component Slf4j public class OrderLineSchedule implements SimpleJob {//引入接口类以及对应实体ServiceImpl类或者将批量插入方法放到service层private final GateWayFeign gateWayFeign;private final SellOrderListServiceImpl sellOrderListService;public OrderLineSchedule(GateWayFeign gateWayFeign, SellOrderListServiceImpl sellOrderListService) {this.gateWayFeign gateWayFeign;this.sellOrderListService sellOrderListService;}//创建日期格式转换器这里按需使用即可提供了两种一种对应普通java.util.Date一种对应JDK8及以上提供的java.time.LocalDateTimeprivate final SimpleDateFormat sdf new SimpleDateFormat(yyyyMMdd HH:mm:ss);private final DateTimeFormatter dtf DateTimeFormatter.ofPattern(yyyyMMdd HH:mm:ss);Overridepublic void execute(ShardingContext shardingContext) {log.info(开始定时查询数仓-销售订单表数据);executeRun();log.info(查询数仓-销售订单表数据结束);}//这里单独把操作类拿出来是为了方便在Controller层通过接口调用留一个手动操作的口子public void executeRun() {//updateOverDaily获取当前批次queue解释详见后续service类int queue sellOrderListService.updateOverDaily();try {cycleExecute(1, queue);//每次定时删除多余的历史数据log.info(数仓-销售订单表数据删除批次号为[{}], queue);CompletableFuture.runAsync(sellOrderListService::deletePre);} catch (Exception e) {//这里不使用事务而是采用手动回滚的原因是由于定时任务一般时间较长必然导致大事务问题因此采用手动方式去规避问题log.error(查询数仓-销售订单表数据报错回滚至上一版数据, e);sellOrderListService.updateRe(queue);}}/*** 该方法使用递归分页获取接口参数结束条件是接口没有数据注意递归次数不宜过多过多会导致栈溢出 * param pageNum 接口分页参数--没有可删除* param queue 当前批次*/ public void cycleExecute(int pageNum, int queue) {//调用接口这里分页查询 OrderLineQueryDTO query new OrderLineQueryDTO();query.setPageNo(pageNum);query.setPageSize(1000);query.setInFields(new OrderLineQueryDTO.InFieldsDTO(19900101 00:00:00, 20230101 00:00:00));log.info(开始调用数仓-销售订单表接口查询参数{}, JSON.toJSONString(query));OrderLineResDTO res gateWayFeign.getOrderLineToSmbgj(query);log.info(结束调用数仓-销售订单表接口返回结果{}, res);//判断接口是否返回值如果没有返回值结束递归 if (CollectionUtils.isNotEmpty(res.getData())) {ListSellOrderList sellOrderLists new ArrayList(1024);for (OrderLineResDTO.DataDTO datum : res.getData()) {//数据转换谨慎使用BeanUtils.copy()SellOrderList orderAdd new SellOrderList();orderAdd.setCustomerName(datum.getPartyName());orderAdd.setItemCode(datum.getItemCode());orderAdd.setItemDesc(datum.getItemDesc());orderAdd.setFirstIntegratorSystem(datum.getFirstIntegratorSystem());orderAdd.setFinalCustomerName(datum.getFinalCustomerName());orderAdd.setOrderNum(datum.getOrderNumber());orderAdd.setOrderBelong(datum.getOrderBelongTypeName());orderAdd.setOrderType(datum.getOrderTypeNew());orderAdd.setLineNumber(datum.getOrderNumber());orderAdd.setContract(datum.getCustPoNumber());Date format null;try {format sdf.parse(datum.getCreationDate());} catch (ParseException e) {log.error(无法解析时间 datum.getCreationDate());}orderAdd.setOrderCreateDate(format);orderAdd.setProductDescription(datum.getProductDescription());orderAdd.setOrderQty(datum.getOrderQty());orderAdd.setSoldToCountries(datum.getCountryName());orderAdd.setDataUpdateDate(datum.getLastUpdateDate());orderAdd.setCreateTime(new Date());orderAdd.setIsDelete(0);//批次判断如果-1说明第一次给默认值0如果不是填入当前批次即可orderAdd.setQueue(queue -1 ? 0 : queue);sellOrderLists.add(orderAdd);}//推荐自己写批量插入SQLMP提供的速度不够快默认批次1000条sellOrderListService.getBaseMapper().batchSchdule(sellOrderLists);//开启递归分页1cycleExecute(pageNum 1, queue, startTime);}} }service层 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import java.util.Comparator; import java.util.Date; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors;/*** p* 数仓-销售订单表 服务实现类* /p** author WangZY* since 2022-06-01*/ Service Slf4j public class SellOrderListServiceImpl extends ServiceImplSellOrderListMapper, SellOrderList implements ISellOrderListService {/*** author WangZY* date 2022/6/1 16:09* description 逻辑删除上一版数据**/Overridepublic int updateOverDaily() {ListSellOrderList list lambdaQuery().eq(SellOrderList::getIsDelete, 0).select(SellOrderList::getQueue).list();if (CollectionUtils.isEmpty(list)) {//没有说明第一次全量返回标识量-1return -1;} else {//逻辑删除上一版数据并生成下一批次号即1Integer queue list.get(0).getQueue();SellOrderList delivery new SellOrderList();delivery.setIsDelete(1);lambdaUpdate().eq(SellOrderList::getIsDelete, 0).update(delivery);return queue 1;}}/*** author WangZY* date 2022/6/1 16:09* description 删除历史数据**/Overridepublic void deletePre() {QueryWrapperSellOrderList qw new QueryWrapper();qw.select(distinct queue);ListSellOrderList queueNumberList list(qw);ListInteger queueDistinct queueNumberList.parallelStream().map(SellOrderList::getQueue).sorted(Comparator.comparingInt(o - o)).collect(Collectors.toList());//删除30个批次之前的数据这里可以调整保留多少版数据if (queueDistinct.size() 30) {for (int i 0; i queueDistinct.size() - 30; i) {remove(new QueryWrapperSellOrderList().eq(queue, queueDistinct.get(i)));}}}/*** author WangZY* date 2022/6/1 16:09* description 恢复指定版本数据并删除该版本的下一版数据**/Overridepublic void updateRe(int queue) {SellOrderList deliveryPre new SellOrderList();deliveryPre.setUpdateTime(new Date());deliveryPre.setIsDelete(1);lambdaUpdate().eq(SellOrderList::getQueue, queue 1).update(deliveryPre);SellOrderList deliveryAfter new SellOrderList();deliveryAfter.setUpdateTime(new Date());deliveryAfter.setIsDelete(0);lambdaUpdate().eq(SellOrderList::getQueue, queue).update(deliveryAfter);} }数据库需要字段 每日更新类–物料基础信息及SMB海外预测项目已上线并稳定运行 详细信息 数据每日通过接口接收增量数据增量数据通过数据中的唯一值进行新增和更新的判断 操作步骤 前提条件 同全量翻新类 定时任务 import com.alibaba.fastjson.JSON; import com.dangdang.ddframe.job.api.ShardingContext; import com.dangdang.ddframe.job.api.simple.SimpleJob; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.springframework.stereotype.Component; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors;/*** author WangZY* date 2022/6/2 11:51* description SMB国际获取订单行定时任务**/ Component Slf4j public class OrderLineSchedule implements SimpleJob {//引入接口类以及对应实体ServiceImpl类或者将批量插入方法放到service层private final GateWayFeign gateWayFeign;private final SellOrderListServiceImpl sellOrderListService;public OrderLineSchedule(GateWayFeign gateWayFeign, SellOrderListServiceImpl sellOrderListService) {this.gateWayFeign gateWayFeign;this.sellOrderListService sellOrderListService;}private final SimpleDateFormat sdf new SimpleDateFormat(yyyyMMdd HH:mm:ss);private final DateTimeFormatter dtf DateTimeFormatter.ofPattern(yyyyMMdd HH:mm:ss);Overridepublic void execute(ShardingContext shardingContext) {log.info(开始定时查询数仓-SMB国际获取订单行数据);executeRun();log.info(查询数仓-SMB国际获取订单行数据结束);}public void executeRun() {//查询出当前数据库里所有数据的ID以及唯一条件切勿全字段容易触发OOMListSellOrderList list sellOrderListService.lambdaQuery().eq(SellOrderList::getIsDelete, 0).select(SellOrderList::getId, SellOrderList::getLineId).list();if (CollectionUtils.isEmpty(list)) {//空的就全量新增即可cycleExecute(1, new HashMap(8), 20000101 00:00:00, 20500101 00:00:00);} else {//不为空说明是增量更新这里创建MAPkey为唯一条件value为实体类其实这个实体最主要的就是要个ID方便批量更新MapInteger, SellOrderList judgeMap list.stream().filter(e - e.getLineId() ! null).collect(Collectors.toMap(SellOrderList::getLineId, Function.identity()));//每日更新这里取昨天时间顺便冗余一小时LocalDateTime time LocalDateTime.now().minusDays(1).minusHours(1);cycleExecute(1, judgeMap, time.format(dtf), LocalDateTime.now().format(dtf));}}public void cycleExecute(int pageNum, MapInteger, SellOrderList judgeMap, String startTime, String endTime) {//正常分页调接口即可OrderLineQueryDTO query new OrderLineQueryDTO();query.setPageNo(pageNum);query.setPageSize(1000);query.setInFields(new OrderLineQueryDTO.InFieldsDTO(startTime, endTime));log.info(开始调用数仓-SMB国际获取订单行接口查询参数{}, JSON.toJSONString(query));OrderLineResDTO res gateWayFeign.getOrderLineToSmbgj(query);log.info(结束调用数仓-SMB国际获取订单行接口返回结果{}, JSON.toJSONString(res));if (CollectionUtils.isNotEmpty(res.getData())) {if (judgeMap.isEmpty()) {//map为空说明全量新增直接批量新增即可ListSellOrderList sellOrderLists new ArrayList(1024);for (OrderLineResDTO.DataDTO datum : res.getData()) {SellOrderList orderAdd new SellOrderList();orderAdd.setLineId(datum.getLineId());paddingParam(datum, orderAdd);orderAdd.setCreateTime(new Date());orderAdd.setIsDelete(0);sellOrderLists.add(orderAdd);}sellOrderListService.getBaseMapper().batchSchdule(sellOrderLists);cycleExecute(pageNum 1, judgeMap, startTime, endTime);} else { ListSellOrderList sellOrderListAdd new ArrayList(1024);ListSellOrderList sellOrderListUpdate new ArrayList(1024);for (OrderLineResDTO.DataDTO datum : res.getData()) {SellOrderList existOrder judgeMap.get(datum.getLineId());if (existOrder null) {//map中没有数据直接新增SellOrderList orderAdd new SellOrderList();orderAdd.setLineId(datum.getLineId());paddingParam(datum, orderAdd);orderAdd.setCreateTime(new Date());orderAdd.setIsDelete(0);sellOrderListAdd.add(orderAdd);} else {//map中有数据说明该实体类以及初始化了需要更新这里把主键放入该修改的实体类中SellOrderList orderUpdate new SellOrderList();orderUpdate.setId(existOrder.getId());paddingParam(datum, orderUpdate);orderUpdate.setUpdateTime(new Date());sellOrderListUpdate.add(orderUpdate);}}if (CollectionUtils.isNotEmpty(sellOrderListAdd)) {sellOrderListService.getBaseMapper().batchSchdule(sellOrderListAdd);}if (CollectionUtils.isNotEmpty(sellOrderListUpdate)) {sellOrderListService.updateBatchById(sellOrderListUpdate);}cycleExecute(pageNum 1, judgeMap, startTime, endTime);}}}private void paddingParam(OrderLineResDTO.DataDTO datum, SellOrderList orderAdd) {orderAdd.setCustomerName(datum.getPartyName());orderAdd.setItemCode(datum.getItemCode());orderAdd.setItemDesc(datum.getItemDesc());orderAdd.setFirstIntegratorSystem(datum.getFirstIntegratorSystem());orderAdd.setFinalCustomerName(datum.getFinalCustomerName());orderAdd.setOrderNum(datum.getOrderNumber());orderAdd.setOrderBelong(datum.getOrderBelongTypeName());orderAdd.setOrderType(datum.getOrderTypeNew());orderAdd.setContract(datum.getCustPoNumber());Date format null;try {format sdf.parse(datum.getCreationDate());} catch (ParseException e) {log.error(无法解析时间 datum.getCreationDate());}orderAdd.setOrderCreateDate(format);orderAdd.setProductDescription(datum.getProductDescription());orderAdd.setOrderQty(datum.getOrderQty());orderAdd.setSoldToCountries(datum.getCountryName());orderAdd.setDataUpdateDate(datum.getLastUpdateDate());} }优化要点 代码部分其实已经相当完善了来说点代码之外的东西例如大家喜闻乐见的优化。 减少大对象 大批量的数据必然会带来大对象大对象的堆积则必然会导致OOM–java heap space即堆内存溢出。减少数据的传输必然是重中之重可通过如下方向优化 接口的数据能精简的精简SQL的查询参数尽量减少并且使用尽量少字段的结果类去接收(即使字段没有值但是序列化的时候依然会有key) 减少循环 大多数同事可能用惯了stream流所以会嫌弃使用for。但其实得根据情况因为stream流本身就是循环的语法糖多个stream流不方便合并的时候用一个for循环就好了。增量的时候我们需要对比从数据库里拿到的原数据这个时候就不要循环里面套循环去contains。建议提前一次循环做个map以唯一值为key对象为value会快很多唯一不足的是用空间换时间要注意OOM问题。 多线程优化 熟练使用CompletableFuture.allOf以及parallelStream流会大大提升效率。该部分留待后续文章性能优化-如何爽玩多线程来开发分析坑很多知识点也很多。 批量插入 MP为了通用性终究是相对保守了点可尝试修改批量插入甚至是加上多线程事务。多线程事务实际上通常采用2PC的思想实现这部分也留待后续文章分析。 写在最后 设计方案系列来自我对场景代码的总结日常工作中会有很多这样的场景我就想着要把这些套路代码留存下来方便下次使用。本次套路包含了数据库设计、代码案例、优化思想三块基本上都点到了希望对读者的工作有所帮助。优化这块算是通用的思考吧说白了性能优化就是围绕硬件和软件进行开源节流堆硬件和提升软件效率。 最近一直在写一些多线程代码尝试去总结套路下一篇会是ComplatableFutrue的实战多线程操作以及简易的2PC实现干货很多敬请期待。
http://www.pierceye.com/news/289056/

相关文章:

  • 建设银行网上银行网站可以开通网银wordpress 种子插件
  • 一般网站图标是用什么做的网件路由器无线中继
  • 手机 网站 开发淘宝店铺网站策划书
  • 网站建设规划方案书滨州网站建设 中企动力
  • 网站建设品牌推荐做网站必须要公网ip
  • 做网站卖东西赚钱wordpress微信网站
  • 商丘网站建设有限公司店面设计费用
  • 张店学校网站建设公司合肥有哪些seo网络公司
  • 做博客网站的空间容量需要多少北京简盟产品设计有限公司
  • 哪些网站怎么进定制开发平台
  • 【郑州网站建设】wordpress自定义后台单页模板
  • 铭誉摄影网站北京网站建设开发
  • 单位还能建设网站吗做网站的程序员留备份
  • 松江团购做网站产品开发的基本流程
  • 织梦后台网站栏目空白小广告制作
  • 钦州建设局网站云南网站建设招商
  • 韩国风格网站php源码网站怎么放到服务器上
  • 网站调优yandex搜索引擎入口
  • 医院网站建设具体内容商丘网站制作电话
  • 别人做的网站直播网站
  • 足球梦网站建设的基本思路沧州做企业网站
  • 招标建设网站什么是微信wordpress
  • 建设银行网站连不上成都网站快照优化公司
  • 网站 永久关停 请示广州网站建设骏域网站
  • 个人建站模板外国网站翻墙怎么做
  • 保定网站设计制作公司有经验的中山网站建设
  • 免费网站建设那个好wordpress本地怎么上传服务器
  • 自己做的网站加载慢WordPress模板首页文件是啥
  • 教学网站建设网站建设岗位有哪些
  • 网站建设合同的验收表网页网站的区别是什么