日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql商城热销榜怎么实现_Redis实现商品热卖榜

發布時間:2024/3/12 数据库 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql商城热销榜怎么实现_Redis实现商品热卖榜 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Redis系列

redis相關介紹

redis是一個key-value存儲系統。和Memcached類似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set?--有序集合)和hash(哈希類型)。這些數據類型都支持push/pop、add/remove及取交集并集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎上,redis支持各種不同方式的排序。與memcached一樣,為了保證效率,數據都是緩存在內存中。區別的是redis會周期性的把更新的數據寫入磁盤或者把修改操作寫入追加的記錄文件,并且在此基礎上實現了master-slave(主從)同步。

Redis?是一個高性能的key-value數據庫。?redis的出現,很大程度補償了memcached這類key/value存儲的不足,在部 分場合可以對關系數據庫起到很好的補充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客戶端,使用很方便.

今天我們來利用Redis來實現一個大家在工作中都可能遇到的需求,熱賣排行榜

話不多說開干!!!!!

需求說明

1、本次我們實現一個每日熱賣商品排行榜的需求

2、簡單的設計倆張表:goods(商品表)、sell(銷售記錄表)

3、主要是將當日熱賣的商品查詢出來,利用Redis的有序集合進行大到小排序顯示在前端頁面

技術列表

Springboot 2.1.2.RELEASE

Redis

freemarker

mybatis-plus 3.2.0

hutool-all

搭建項目基礎環境

首先我們來創建一個springboot項目,并且引入需要的依賴,后續需要的依賴后面用到在引入

所有的依賴如下:

org.springframework.boot

spring-boot-starter-data-redis

org.springframework.boot

spring-boot-starter-freemarker

org.springframework.boot

spring-boot-starter-web

mysql

mysql-connector-java

runtime

org.projectlombok

lombok

true

com.baomidou

mybatis-plus-boot-starter

3.2.0

com.baomidou

mybatis-plus-generator

3.2.0

p6spy

p6spy

3.8.6

org.apache.commons

commons-lang3

3.9

cn.hutool

hutool-all

4.1.17

由于我們項目用到的模本引擎是freemarker下面簡單的介紹一下這個模版引擎

FreeMarker是一款模板引擎:即一種基于模板和要改變的數據, 并用來生成輸出文本(HTML網頁、配置文件、源代碼等)的通用工具。它不是面向最終用戶的,而是一個Java類庫,是一款程序員可以嵌入他們所開發產品的組件.

能夠很方便的對后端的數據進行渲染

敲黑板重點!!FreeMarker的宏:宏是在模板中使用macro指令定義

宏是和某個變量關聯的模板片斷,以便在模板中通過用戶定義指令使用該變量。

大白話:就是提高前端的代碼的重用

如下是本項目中用到的FreeMarker的宏

${title}

layui.cache.page = '';

layui.cache.user = {

username: '游客'

,uid: -1

,avatar: '../res/images/avatar/00.jpg'

,experience: 83

,sex: '男'

};

layui.config({

version: "3.0.0"

,base: '../res/mods/' //這里實際使用時,建議改成絕對路徑

}).extend({

fly: 'index'

}).use('fly');

#macro>

由于選擇的是mybatis-plus開發所以我們將代碼進行生成

參考官網:mybatis-plus官網

找到代碼生成器將代碼拷貝到你的項目下進行必要的配置執行main方法,生成代碼。如下:

代碼如下:

public class CodeGenerator {

/**

*

* 讀取控制臺內容

*

*/

public static String scanner(String tip) {

Scanner scanner = new Scanner(System.in);

StringBuilder help = new StringBuilder();

help.append("請輸入" + tip + ":");

System.out.println(help.toString());

if (scanner.hasNext()) {

String ipt = scanner.next();

if (StringUtils.isNotEmpty(ipt)) {

return ipt;

}

}

throw new MybatisPlusException("請輸入正確的" + tip + "!");

}

public static void main(String[] args) {

// 代碼生成器

AutoGenerator mpg = new AutoGenerator();

// 全局配置

GlobalConfig gc = new GlobalConfig();

String projectPath = System.getProperty("user.dir");

gc.setOutputDir(projectPath + "/src/main/java");

// gc.setOutputDir("D:\\test");

gc.setAuthor("公眾號:北漂碼農有話說");

gc.setOpen(false);

// gc.setSwagger2(true); 實體屬性 Swagger2 注解

gc.setServiceName("%sService");

mpg.setGlobalConfig(gc);

// 數據源配置

DataSourceConfig dsc = new DataSourceConfig();

dsc.setUrl("jdbc:mysql://localhost:3306/triumphxxtop?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=UTC");

// dsc.setSchemaName("public");

dsc.setDriverName("com.mysql.cj.jdbc.Driver");

dsc.setUsername("root");

dsc.setPassword("root");

mpg.setDataSource(dsc);

// 包配置

PackageConfig pc = new PackageConfig();

pc.setModuleName(null);

pc.setParent("com.triumphxx");

mpg.setPackageInfo(pc);

// 自定義配置

InjectionConfig cfg = new InjectionConfig() {

@Override

public void initMap() {

// to do nothing

}

};

// 如果模板引擎是 freemarker

String templatePath = "/templates/mapper.xml.ftl";

// 如果模板引擎是 velocity

// String templatePath = "/templates/mapper.xml.vm";

// 自定義輸出配置

List focList = new ArrayList<>();

// 自定義配置會被優先輸出

focList.add(new FileOutConfig(templatePath) {

@Override

public String outputFile(TableInfo tableInfo) {

// 自定義輸出文件名 , 如果你 Entity 設置了前后綴、此處注意 xml 的名稱會跟著發生變化!!

return projectPath + "/src/main/resources/mapper/"

+ "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;

}

});

cfg.setFileOutConfigList(focList);

mpg.setCfg(cfg);

// 配置模板

TemplateConfig templateConfig = new TemplateConfig();

// 配置自定義輸出模板

//指定自定義模板路徑,注意不要帶上.ftl/.vm, 會根據使用的模板引擎自動識別

// templateConfig.setEntity("templates/entity2.java");

// templateConfig.setService();

// templateConfig.setController();

templateConfig.setXml(null);

mpg.setTemplate(templateConfig);

// 策略配置

StrategyConfig strategy = new StrategyConfig();

strategy.setNaming(NamingStrategy.underline_to_camel);

strategy.setColumnNaming(NamingStrategy.underline_to_camel);

strategy.setSuperEntityClass("com.triumphxx.entity.BaseEntity");

strategy.setEntityLombokModel(true);

strategy.setRestControllerStyle(true);

strategy.setSuperControllerClass("com.triumphxx.controller.BaseController");

strategy.setInclude(scanner("表名,多個英文逗號分割").split(","));

strategy.setSuperEntityColumns("id", "created", "modified", "status");

strategy.setControllerMappingHyphenStyle(true);

strategy.setTablePrefix(pc.getModuleName() + "_");

mpg.setStrategy(strategy);

mpg.setTemplateEngine(new FreemarkerTemplateEngine());

mpg.execute();

}

}

執行main方法,如下,輸入你的表名,生成你的代碼

生成代碼

由于我們使用的是mp所以需要配置sql分析器,將sql打印出來,便于分析,當然配置sql分析器是有一定的性能損耗,所以不建議在產線上配置,配置如下:

首先添加依賴

p6spy

p6spy

3.8.6

修改數據庫配置信息,driver-class-name:com.p6spy.engine.spy.P6SpyDriver,jdbc后邊加上p6spy

spring:

datasource:

driver-class-name: com.p6spy.engine.spy.P6SpyDriver

url: jdbc:p6spy:mysql://localhost:3306/triumphxxtop?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=UTC

username: root

password: root

引入配置文件

項目設計思路,在項目啟動的時候,將今日的熱賣商品數據緩存到redis中,代碼如下:

/**

* @author:triumphxx

* @Date:2020/5/16

* @Time:7:40 上午

* @微信公眾號:北漂碼農有話說

* @desc:系統啟動加載類

**/

@Component

public class ContextStartUp implements ApplicationRunner {

@Autowired

SellService sellService;

/**

* 服務啟動是加載執行的的方法

* 將每天熱賣的商品進行展示

* @param args

* @throws Exception

*/

@Override

public void run(ApplicationArguments args) throws Exception {

sellService.initGoodsSellTop();

}

}

核心代碼如下,每一步都有詳細的說明。

@Autowired

GoodsService goodsService;

@Autowired

RedisUtil redisUtil;

@Autowired

com.triumphxx.util.DateUtil dateUtil;

@Override

public void initGoodsSellTop() {

//獲取當天內銷售量大于80的商品id和銷售記錄id

List sells = this.list(new QueryWrapper()

.ge("sell_num",80)

.ge("sell_date", DateUtil.format(new Date(),"yyyy-MM-dd"))

.select("goods_id","sell_num")

);

List goodsVos = new ArrayList<>();

for (Sell sell : sells) {

//1、根據銷售量大于80的銷售記錄查詢出貨物的信息

GoodsVo goods = goodsService.selectSellTop(new QueryWrapper().eq("g.goods_id",sell.getGoodsId())

.eq("s.sell_date",DateUtil.format(new Date(),"yyyy-MM-dd")));

//2、將銷售貨物一天的銷售的數量進行數據緩存

redisUtil.zSet(Constants.REDIS_KEY.GOODS_TOP_KEY+goods.getGoodsId(),goods.getGoodsId(),goods.getSellNum());

//設置過期時間 當天有效

//0點的時間減去現在的時間換算層毫秒數

Long expireTime = dateUtil.initDateByDay()-DateUtil.currentSeconds();

redisUtil.expire(Constants.REDIS_KEY.GOODS_TOP_KEY+goods.getGoodsId(),expireTime);

//同時緩存一下貨物的基本信息 貨物id 貨物名稱 銷售貨物數量

this.hasCacheGoods(goods,expireTime);

goodsVos.add(goods);

}

//做并集

this.zuionOneDayTop(goodsVos);

}

/**

*合并當天熱賣榜

*/

private void zuionOneDayTop(List goodsVos) {

List otherKeys = new ArrayList<>();

for (GoodsVo goodsVo : goodsVos) {

String temp = Constants.REDIS_KEY.GOODS_TOP_KEY +goodsVo.getGoodsId();

otherKeys.add(temp);

}

redisUtil.zUnionAndStore(Constants.REDIS_KEY.GOODS_TOP_KEY,

otherKeys,Constants.REDIS_KEY.GOODS_ONE_DAY_RANK);

}

/**

* 緩存貨物的基本信息

* @param goods

* @param expireTime

*/

private void hasCacheGoods(GoodsVo goods, Long expireTime) {

//構造貨物基本信息key

String goodsKey =Constants.REDIS_KEY.GOODS_KEY+goods.getGoodsId();

boolean isKey = redisUtil.hasKey(goodsKey);

if (!isKey){

redisUtil.hset(goodsKey,Constants.REDIS_KEY.GOODS_KEY_ID,goods.getGoodsId(),expireTime);

redisUtil.hset(goodsKey,Constants.REDIS_KEY.GOODS_KEY_NAME,goods.getGoodsName(),expireTime);

redisUtil.hset(goodsKey,Constants.REDIS_KEY.GOODS_KEY_SELL_NUM,goods.getSellNum(),expireTime);

}

}

代碼中設計的常量類如下

/**

* @author:triumphxx

* @Date:2020/5/16

* @Time:9:43 上午

* @微信公眾號:北漂碼農有話說

* @desc:常量類

**/

public class Constants {

public static class REDIS_KEY {

/**

* 貨物銷量key 每天某一個貨物的銷售量

*/

public static final String GOODS_TOP_KEY= "goods:rank:";

/**

* 貨物的基本信息key

*/

public static final String GOODS_KEY= "goods:";

/**

* 貨物id

*/

public static final String GOODS_KEY_ID= "goods:id:";

/**

* 貨物名稱

*/

public static final String GOODS_KEY_NAME= "goods:name:";

/**

* 貨物銷售數量

*/

public static final String GOODS_KEY_SELL_NUM= "goods:sellnum:";

/**

* 每日銷售并集后的key

*/

public static final String GOODS_ONE_DAY_RANK= "oneday:rank";

}

}

項目中涉及的其他技術點比如:自定義標簽等有機會專題討論

項目中的具體細節請移步GitHub分析相關源碼

項目最終效果如圖

本文的案例,本被人已經上傳到 GitHub上了,地址:https://github.com/triumphxx/triumphxxtop

如果覺得筆者的內容對你有用,請關注微信公眾號,歡迎點贊評論。

總結

以上是生活随笔為你收集整理的mysql商城热销榜怎么实现_Redis实现商品热卖榜的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。