" />

欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java數(shù)據(jù)隨機(jī)分頁實(shí)現(xiàn)方案

 更新時(shí)間:2023年06月16日 08:35:09   作者:壹米飯  
本文主要介紹了java數(shù)據(jù)隨機(jī)分頁實(shí)現(xiàn)方案,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

導(dǎo)語 | 網(wǎng)上搜到的方法,是使用數(shù)據(jù)庫的隨機(jī)排序ORDER BY RAND()進(jìn)行的,較大數(shù)據(jù)的時(shí)候,顯然就不好使了,而且在數(shù)據(jù)庫層面進(jìn)行隨機(jī)分頁就比較困難,無法保證基礎(chǔ)的有序性,因此需要考慮其他方法來進(jìn)行實(shí)現(xiàn):數(shù)據(jù)庫+redis+List洗牌的方式就孕育而生。

問題產(chǎn)生

公司業(yè)務(wù)遇到此場景:在前端分頁展示數(shù)據(jù)時(shí),為了讓每個(gè)數(shù)據(jù)都有相同的幾率被展示,每次分頁展示數(shù)據(jù)時(shí),都是隨機(jī)展示的,并要求每一頁之間數(shù)據(jù)不能重復(fù);而且,優(yōu)先展示最近三天的上傳的數(shù)據(jù),用戶看完數(shù)據(jù)后,繼續(xù)加載三天前又三天的數(shù)據(jù)。

此時(shí)大概率會(huì)有一會(huì)有以下痛點(diǎn):

  • 有用戶一直傳數(shù)據(jù),就會(huì)出現(xiàn)這個(gè)用戶數(shù)據(jù)占滿一頁;
  • 越晚上傳的數(shù)據(jù)曝光量會(huì)越好,越早上傳的數(shù)據(jù)曝光量越差;
  • 類似這種3天又3天數(shù)據(jù)如何加載?;

因此提出這個(gè)需求;數(shù)據(jù)需要隨機(jī)分頁出現(xiàn)。

問題分析與解決

分析一

遇到這種問題,單純的使用數(shù)據(jù)庫就不好使了,況且數(shù)據(jù)庫本身就比較脆弱;因此,我想到引入第三方工具:redis,而其我們軟件本身就使用redis;使用redis性能也會(huì)得到極大提升,主要用到redis list 的方法;

分析二

針對(duì)問題一,同一用戶數(shù)據(jù)占滿一頁,以及問題二的解決辦法;大腦跳出來的方法就是數(shù)據(jù)隨機(jī)選擇,這時(shí)我想到通過list洗牌的方法。

分析三

問題三,用戶看完數(shù)據(jù)后繼續(xù)加載后面的數(shù)據(jù),類似【懶加載】;解決辦法:當(dāng)用戶刷數(shù)據(jù)到最后一頁的時(shí)候,就觸發(fā)【懶加載】,數(shù)據(jù)追加到redis list里面。
實(shí)現(xiàn)步驟與部分代碼

1. 查詢?nèi)斓臄?shù)據(jù),把主鍵id list 洗牌放入redis list;

// 使用 package java.util.Collections;
    /**
     * Randomly permutes the specified list using a default source of
     * randomness.  All permutations occur with approximately equal
     * likelihood.
     */
    public static void shuffle(List<?> list) {
        Random rnd = r;
        if (rnd == null)
            r = rnd = new Random(); // harmless race.
        shuffle(list, rnd);
    }
 /**
     * 追加Lisit
     *
     * @param key 關(guān)鍵字
     * @param list 列表
     * @param expireTime 有效期
     * @return boolean
     */
    public Boolean addAll(String key, List list, Long expireTime) {
        try {
            redisTemplate.opsForList().rightPushAll(key, list);
            redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
            return true;
        } catch (JedisException e) {
            handleJedisException(e);
            throw e;
        } finally {
            RedisConnectionUtils.unbindConnection(Objects.requireNonNull(redisTemplate.getConnectionFactory()));
        }
    }

這里需要注意,設(shè)置key的有效期;否則,你懂的!??!

2.  觸發(fā)數(shù)據(jù)【懶加載】

/**
     * 構(gòu)建分頁數(shù)據(jù)
     * @param so 入?yún)?
     * @param key redis key
     * @param dayKey 天數(shù)區(qū)間的key
     * @return page
     */
    private IPage<PictureAlbumForUserDTO> buildPage(PublishedPictureAlbumSO so, String key, String dayKey) {
        Long total = redisUtil.listSize(key);
        long toIndex = so.getSize() * so.getPage();
        if (toIndex > total) { // 用戶加載到最后一頁,觸發(fā)【懶加載】
            // 發(fā)現(xiàn)池,加載更多數(shù)據(jù)
            String dayValue = redisUtil.get(dayKey);
            String[] dayValueArray = dayValue.split("#");
            long start = Long.parseLong(dayValueArray[0]) - rangeDay;
            long end = Long.parseLong(dayValueArray[1]) - rangeDay;
            if (appendList(key, dayKey, start, end)) {
                // 遞歸調(diào)用;遞歸后,數(shù)據(jù)追加到redis
                return buildPage(so, key, dayKey);
            } else {
                toIndex = total;
            }
        }
        // 根據(jù)下標(biāo)獲取redis里面分頁數(shù)據(jù)
        List list = redisUtil.listRange(key, so.getSize() * (so.getPage() - 1), toIndex);
        if (CollectionUtil.isEmpty(list)) {
            return null;
        }
        so.setAlbumIdList(list);
        // 因?yàn)檫M(jìn)行l(wèi)ist id 分頁,這里默認(rèn)去數(shù)據(jù)庫里查詢第一頁就行了
        so.setPage(1);
        Page<PictureAlbumForUserDTO> pageData = new Page<>(so.getPage(), so.getSize());
        IPage<PictureAlbumForUserDTO> iPage = baseMapper.findAllActive(pageData, so);
        List<PictureAlbumForUserDTO> dtoList = iPage.getRecords();
        Collections.shuffle(dtoList);
        iPage.setRecords(dtoList);
        iPage.setTotal(total);
        iPage.setSize(so.getSize());
        iPage.setCurrent(so.getPage());
        iPage.setPages((total + so.getSize() - 1) / so.getSize());
        return iPage;
    }
 /**
     * 讀取redis lisit 區(qū)間數(shù)據(jù)
     *
     * @param key 關(guān)鍵字
     * @param start 開始下標(biāo)
     * @param end 結(jié)束下標(biāo)
     * @return boolean
     */
    public List listRange(String key, long start, long end) {
        try {
            return redisTemplate.opsForList().range(key, start, end);
        } catch (JedisException e) {
            handleJedisException(e);
            throw e;
        } finally {
            RedisConnectionUtils.unbindConnection(Objects.requireNonNull(redisTemplate.getConnectionFactory()));
        }
    }

3. 每頁數(shù)據(jù)隨機(jī)展示

如何想讓用戶每一頁看到的數(shù)據(jù)不一樣;分頁的數(shù)據(jù)可以再進(jìn)行洗牌,而且不會(huì)打亂數(shù)據(jù)池整體的數(shù)據(jù)排列,有種【千人千面】的錯(cuò)覺;缺點(diǎn)就是用戶可能會(huì)覺得,你的分頁數(shù)據(jù)存在問題。

總結(jié)

介紹了一種實(shí)現(xiàn)隨機(jī)分頁的方案,關(guān)鍵在與數(shù)據(jù)庫結(jié)合redis的使用和list的洗牌,這種方法從效率和使用性性都比較高的;對(duì)付萬級(jí)核心數(shù)據(jù)的隨機(jī)分頁,應(yīng)該是沒有問題的。

到此這篇關(guān)于java數(shù)據(jù)隨機(jī)分頁實(shí)現(xiàn)方案的文章就介紹到這了,更多相關(guān)java數(shù)據(jù)隨機(jī)分頁內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 在idea2023中使用SpringBoot整合Lombok全過程及詳細(xì)用法

    在idea2023中使用SpringBoot整合Lombok全過程及詳細(xì)用法

    Lombok項(xiàng)目是一個(gè)java庫,它可以自動(dòng)插入到編輯器和構(gòu)建工具中,增強(qiáng)java的性能,本文詳細(xì)給大家介紹了在idea2023中使用SpringBoot整合Lombok全過程及詳細(xì)用法,需要的朋友可以參考下
    2023-09-09
  • 處理java異步事件的阻塞和非阻塞方法分析

    處理java異步事件的阻塞和非阻塞方法分析

    這篇文章主要介紹了處理java異步事件的阻塞和非阻塞方法分析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,阻塞與非阻塞關(guān)注的是交互雙方是否可以彈性工作。,需要的朋友可以參考下
    2019-06-06
  • SpringBoot整合Elasticsearch實(shí)現(xiàn)索引和文檔的操作方法

    SpringBoot整合Elasticsearch實(shí)現(xiàn)索引和文檔的操作方法

    Elasticsearch 基于 Apache Lucene 構(gòu)建,采用 Java 編寫,并使用 Lucene 構(gòu)建索引、提供搜索功能,本文分步驟通過綜合案例給大家分享SpringBoot整合Elasticsearch的相關(guān)知識(shí),感興趣的朋友跟隨小編一起看看吧
    2021-05-05
  • Spring?Boot中使用Spring?Retry重試框架的操作方法

    Spring?Boot中使用Spring?Retry重試框架的操作方法

    這篇文章主要介紹了Spring?Retry?在SpringBoot?中的應(yīng)用,介紹了RetryTemplate配置的時(shí)候,需要設(shè)置的重試策略和退避策略,需要的朋友可以參考下
    2022-04-04
  • Spring Boot高級(jí)教程之使用Redis實(shí)現(xiàn)session共享

    Spring Boot高級(jí)教程之使用Redis實(shí)現(xiàn)session共享

    這篇文章主要為大家詳細(xì)介紹了Spring Boot高級(jí)教程之使用Redis實(shí)現(xiàn)session共享,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • Java中Stream流中map和forEach的區(qū)別詳解

    Java中Stream流中map和forEach的區(qū)別詳解

    本文主要介紹了Java中Stream流中map和forEach的區(qū)別詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • java分布式事務(wù)seata的使用方式

    java分布式事務(wù)seata的使用方式

    這篇文章主要介紹了java分布式事務(wù)seata的使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • 解決springboot整合druid遇到的坑

    解決springboot整合druid遇到的坑

    這篇文章主要介紹了解決springboot整合druid遇到的坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java?C++題解leetcode字符串輪轉(zhuǎn)KMP算法詳解

    Java?C++題解leetcode字符串輪轉(zhuǎn)KMP算法詳解

    這篇文章主要為大家介紹了Java?C++題解leetcode字符串輪轉(zhuǎn)KMP算法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • Spring RestTemplate具體使用詳解

    Spring RestTemplate具體使用詳解

    這篇文章主要介紹了Spring RestTemplate具體使用詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-04-04

最新評(píng)論