中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

網(wǎng)站代碼怎么改/個(gè)人在線做網(wǎng)站免費(fèi)

網(wǎng)站代碼怎么改,個(gè)人在線做網(wǎng)站免費(fèi),西寧吧 百度貼吧,企業(yè)官方網(wǎng)站制作推廣軟件學(xué)習(xí)目標(biāo): 提示:學(xué)習(xí)如何利用Redisson實(shí)現(xiàn)點(diǎn)贊排行榜功能,按照時(shí)間順序 當(dāng)用戶給某一篇文章點(diǎn)贊后,會(huì)再數(shù)據(jù)庫(kù)中存儲(chǔ)一條數(shù)據(jù),并且在Redis中存儲(chǔ)一條數(shù)據(jù)為當(dāng)前博客的點(diǎn)贊用戶標(biāo)識(shí),來區(qū)分哪個(gè)用戶對(duì)文章進(jìn)…

學(xué)習(xí)目標(biāo):

提示:學(xué)習(xí)如何利用Redisson實(shí)現(xiàn)點(diǎn)贊排行榜功能,按照時(shí)間順序
當(dāng)用戶給某一篇文章點(diǎn)贊后,會(huì)再數(shù)據(jù)庫(kù)中存儲(chǔ)一條數(shù)據(jù),并且在Redis中存儲(chǔ)一條數(shù)據(jù)為當(dāng)前博客的點(diǎn)贊用戶標(biāo)識(shí),來區(qū)分哪個(gè)用戶對(duì)文章進(jìn)行了點(diǎn)贊,使用ZSet數(shù)據(jù)結(jié)構(gòu)對(duì)點(diǎn)贊用戶進(jìn)行排序來實(shí)現(xiàn)排行榜功能


學(xué)習(xí)產(chǎn)出:

解決方案:

  1. 點(diǎn)贊后的用戶記錄在Redis的set數(shù)據(jù)類型中

1. 準(zhǔn)備pom環(huán)境

		<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope><version>5.1.47</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.3</version></dependency><!--hutool--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.17</version></dependency><dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.23.1</version></dependency>

2. 配置ThreadLocal和過濾器

public class UserHolder {private static final ThreadLocal<UserDTO> tl = new ThreadLocal<>();public static void saveUser(UserDTO user){tl.set(user);}public static UserDTO getUser(){return tl.get();}public static void removeUser(){tl.remove();}
}
@Configuration
public class MvcConfig implements WebMvcConfigurer {@Autowiredprivate StringRedisTemplate redis;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LoginInterceptor()).excludePathPatterns("/user/code","/user/login","/blog/hot","/shop/**","/shop-type/**","/voucher/**").order(2);registry.addInterceptor(new RefreshTokenInterceptor(redis)).addPathPatterns("/**").order(1);}
}
---------------------------------------------
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {//controller執(zhí)行之前@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//1.判斷是否需要攔截ThreadLocalif (UserHolder.getUser()==null) {response.setStatus(401);return false;}//7.放行return true;}//渲染后返回給前臺(tái)數(shù)據(jù)前@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {//移除用戶,避免內(nèi)存泄露UserHolder.removeUser();}
}
---------------------------------------------------
@Slf4j
public class RefreshTokenInterceptor implements HandlerInterceptor {//這個(gè)對(duì)象不是由spring管理的所以不能用注解自動(dòng)注入private StringRedisTemplate redis;public RefreshTokenInterceptor(StringRedisTemplate redis) {this.redis = redis;}//controller執(zhí)行之前@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//1.獲取請(qǐng)求頭中的tokenString token = request.getHeader("authorization");if (StrUtil.isBlank(token)) {return true;}//2.基于token獲取redis中的用戶//通過key取到hash中的map集合數(shù)據(jù)Map<Object, Object> userMap = redis.opsForHash().entries("login:token:" + token);//3.判斷用戶是否存在if (userMap.isEmpty()) {return true;}//5.將查詢到的hash數(shù)據(jù)轉(zhuǎn)為userDto對(duì)象UserDTO userDTO = BeanUtil.fillBeanWithMap(userMap, new UserDTO(), false);//6.存在,保存用戶信息到ThreadLocal中UserHolder.saveUser(userDTO);//7.刷新token有效期redis.expire(LOGIN_USER_KEY + token, 30, TimeUnit.MINUTES);log.info("我是第一個(gè)攔截器當(dāng)前攔截所有請(qǐng)求的用戶為,線程為{},{}",UserHolder.getUser(),Thread.currentThread());//8.放行return true;}

3. Controller層:負(fù)責(zé)接收請(qǐng)求和向下分配

@RestController
@RequestMapping("/blog")
public class BlogController{@Resourceprivate IBlogService blogService;@PutMapping("/like/{id}")public Result likeBlog(@PathVariable("id") Long id) {return blogService.likeBlog(id);}
}

4. Service層:負(fù)責(zé)業(yè)務(wù)的處理邏輯點(diǎn)贊功能,將文章的點(diǎn)贊用戶以時(shí)間戳為分?jǐn)?shù)存入Redis

@Service
public class BlogServiceImpl extends ServiceImpl<BlogMapper, Blog> implements IBlogService {@Autowiredprivate IUserService userService;@Resourceprivate StringRedisTemplate redis;@Overridepublic Result likeBlog(Long id) {//1.獲取登錄用戶Long userId = UserHolder.getUser().getId();//2.判斷當(dāng)前用戶是否已經(jīng)點(diǎn)贊String key = "blog:liked:" + id;//獲取當(dāng)前登錄用戶的分?jǐn)?shù),若文章中的用戶id分?jǐn)?shù)為null說明未點(diǎn)贊Double score = redis.opsForZSet().score(key, userId.toString());if (score == null) {//3.如果未點(diǎn)贊,可以點(diǎn)贊//3.1 點(diǎn)贊+1boolean isSuccess = update().setSql("liked= liked +1").eq("id", id).update();//3.2保存當(dāng)前點(diǎn)贊用戶到Redis的文章set集合中,文章set集合中記錄的是點(diǎn)贊用戶的id,//分?jǐn)?shù)是時(shí)間戳,可以進(jìn)行排序if (isSuccess) {//存入Redis的分?jǐn)?shù)值以當(dāng)前時(shí)間戳存入redis.opsForZSet().add(key, userId.toString(), System.currentTimeMillis());}} else {//4.如果已點(diǎn)贊,取消點(diǎn)贊//4.1點(diǎn)贊-1boolean isSuccess = update().setSql("liked = liked -1").eq("id", id).update();//4.2把用戶從Redis的set集合移除if (isSuccess) {redis.opsForZSet().remove(key, userId.toString());}}return null;}
}

5. 上述為下面的排行榜做鋪墊
查詢當(dāng)前文章的點(diǎn)贊排行榜,id是文章id號(hào)

	@PutMapping("/likes/{id}")public Result likesBlog(@PathVariable("id") Long id) {return blogService.queryBlogLikes(id);}
@Overridepublic Result queryBlogLikes(Long id) {String key="blog:liked:" + id;//取出前五條數(shù)據(jù)Set<String> rangeData = redis.opsForZSet().range(key, 0, 4);if (rangeData==null) {return Result.ok(Collections.emptyList());}//將文章點(diǎn)贊的前五條用戶id轉(zhuǎn)換為L(zhǎng)ong類型List<Long> ids = rangeData.stream().map(Long::valueOf).collect(Collectors.toList());String idStr = StrUtil.join(",", ids);//去數(shù)據(jù)庫(kù)把這些用戶查詢出來,并且數(shù)據(jù)脫敏返回給前端List<User> users = userService.query().in("id",ids).last("order by field(id,"+idStr+")").list();UserDTO userData = BeanUtil.copyProperties(users, UserDTO.class);return Result.ok(userData);}
http://www.risenshineclean.com/news/78.html

相關(guān)文章:

  • 網(wǎng)站首頁(yè)html/怎樣打百度人工客服熱線
  • 深圳市企業(yè)網(wǎng)站建設(shè)價(jià)格/整合營(yíng)銷理論主要是指
  • 個(gè)人主頁(yè)頁(yè)面/seo優(yōu)化招商
  • 工信部網(wǎng)站備案查詢步驟詳解/公司網(wǎng)站
  • 做航模的網(wǎng)站/網(wǎng)銷怎么做
  • 網(wǎng)站pv統(tǒng)計(jì)方法/推廣策劃方案
  • tornado 做網(wǎng)站/seo刷詞工具在線
  • 網(wǎng)站建設(shè)和維護(hù)合同/湖南seo優(yōu)化首選
  • 淘寶網(wǎng)站建設(shè)哪個(gè)類目/seo公司
  • 做網(wǎng)站怎么偷源碼做網(wǎng)站/阿里seo排名優(yōu)化軟件
  • 電商網(wǎng)站建設(shè)與運(yùn)營(yíng)/網(wǎng)站管理
  • 文學(xué)投稿網(wǎng)站平臺(tái)建設(shè)/好f123網(wǎng)站
  • 做網(wǎng)站策劃需要用什么軟件/bt磁力搜索引擎在線
  • 沈陽(yáng)網(wǎng)站建設(shè)制作公司/友情鏈接怎么設(shè)置
  • 學(xué)校資源網(wǎng)站的建設(shè)方案/東莞seo推廣機(jī)構(gòu)帖子
  • 建設(shè)部資質(zhì)上報(bào)系統(tǒng)網(wǎng)站/重慶百度推廣優(yōu)化
  • 南昌網(wǎng)站建設(shè)哪家好/什么軟件可以推廣自己的產(chǎn)品
  • 個(gè)人網(wǎng)站 作品/站長(zhǎng)之家工具
  • 吳謹(jǐn)含廠家不愿做網(wǎng)站/平臺(tái)網(wǎng)站開發(fā)公司
  • 網(wǎng)站項(xiàng)目策劃書實(shí)例/網(wǎng)絡(luò)推廣深圳有效渠道
  • wordpress 支持html5/網(wǎng)站標(biāo)題算關(guān)鍵詞優(yōu)化嗎
  • 在京東上怎樣做網(wǎng)站/免費(fèi)平臺(tái)推廣
  • 阿里自助建站平臺(tái)/網(wǎng)站優(yōu)化公司收費(fèi)
  • 如何建立一個(gè)網(wǎng)站分享教程/推廣賺傭金的軟件排名
  • 網(wǎng)站設(shè)計(jì)寬屏/品牌策略有哪些
  • 網(wǎng)站建設(shè)系統(tǒng)哪個(gè)好/seo點(diǎn)擊排名軟件營(yíng)銷工具
  • 建設(shè)文明網(wǎng) 聯(lián)盟網(wǎng)站的/學(xué)seo推廣
  • 武漢網(wǎng)站建設(shè) loongnet/百度云官網(wǎng)
  • 如何建設(shè)一個(gè)屬于自己的網(wǎng)站/引擎優(yōu)化seo
  • 南寧做網(wǎng)站外包/品牌宣傳策略有哪些