Redis数据库zset实现简单排行榜功能

功能介绍:在数据库存对应的国家和score,可以在前端页面±奖牌数,然后实现排名
redis数据库:
Redis数据库zset实现简单排行榜功能

需要的依赖
pop

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- spring mybatis -->
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.1.0</version>
    </dependency>
    <!-- mysql 驱动-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    <!-- druid 数据源连接池 -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
        <version>1.1.10</version>
    </dependency>

    <!-- 热部署 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <optional>true</optional>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>

    <!-- thymeleaf -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <!-- 支持非严格语法的neko -->
    <dependency>
        <groupId>net.sourceforge.nekohtml</groupId>
        <artifactId>nekohtml</artifactId>
        <version>1.9.22</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <!--默认是lettuce客户端-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>

    <!-- redis依赖commons-pool 这个依赖一定要添加 -->
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-pool2</artifactId>
    </dependency>
    <!-- 测试库依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

1.前端代码(index.html)

<!DOCTYPE html>
<html  xmlns:th="http://www.thymeleaf.org">

<head>
  <meta charset="UTF-8" >
  <title>奖牌排行榜</title>
  <style>
    table tr th{
      text-align: center;
    }
  </style>
</head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css">
<script type="text/javascript" src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"></script>
<body>


<div >
  <table class="table table-hover" style="text-align: center">
    <tr>
      <th>排序</th>
      <th>国家</th>
      <th>金牌</th>
      <th>银牌</th>
      <th>铜牌</th>
      <th>奖牌总数</th>
      <th width="200px">操作</th>
    </tr>
    <tr th:each="r:${rankList}">
      <td th:text="${rStat.count}">序号</td>
      <td th:text="${r.country}">国家</td>
      <td th:text="${r.gold}">金牌</td>
      <td th:text="${r.silver}">银牌</td>
      <td th:text="${r.copper}">铜牌</td>
      <td th:text="${r.total}">奖牌总数</td>
      <td>金:<a href="javascript:goldin()" th:href="|javascript:goldin('${r.country}')|" class="glyphicon glyphicon-plus"></a><a href="javascript:goldin2()" th:href="|javascript:goldin2('${r.country}')|" class="	glyphicon glyphicon-minus"></a>&ensp;&ensp;银:<a href="javascript:silverin()" th:href="|javascript:silverin('${r.country}')|" class="glyphicon glyphicon-plus"></a><a href="javascript:silverin2()" th:href="|javascript:silverin2('${r.country}')|" class="glyphicon glyphicon-minus"></a>&ensp;&ensp;铜:<a href="javascript:copperin()" th:href="|javascript:copperin('${r.country}')|" class="glyphicon glyphicon-plus"></a><a href="javascript:copperin2()" th:href="|javascript:copperin2('${r.country}')|" class="	glyphicon glyphicon-minus"></a></td>
    </tr>


  </table>
</div>



</body>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/bootstrap.min.js"></script>
<script type="text/javascript">

  function goldin(country) {
    var score=10000.0;
    $.ajax({
      type:"post",
      url:"ranking",
      data:{"country":country,"score":score},
      success:function () {
        location.href="ranking"
      }
    })
  }
  function silverin(country) {
    var score=100.0;
    $.ajax({
      type:"post",
      url:"ranking",
      data:{"country":country,"score":score},
      success:function () {
        location.href="ranking"
      }
    })
  }
  function copperin(country) {
    var score=1.0;
    $.ajax({
      type:"post",
      url:"ranking",
      data:{"country":country,"score":score},
      success:function () {
        location.href="ranking"
      }
    })
  }
  function goldin2(country) {
    var score=10000.0;
    $.ajax({
      type:"post",
      url:"ranking2",
      data:{"country":country,"score":score},
      success:function () {
        location.href="ranking2"
      }
    })
  }
  function silverin2(country) {
    var score=100.0;
    $.ajax({
      type:"post",
      url:"ranking2",
      data:{"country":country,"score":score},
      success:function () {
        location.href="ranking2"
      }
    })
  }
  function copperin2(country) {
    var score=1.0;
    $.ajax({
      type:"post",
      url:"ranking2",
      data:{"country":country,"score":score},
      success:function () {
        location.href="ranking2"
      }
    })
  }

</script>
</html>

2.后端代码
controller层


```java
@Controller
public class ModelController {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private ModelServiceImpl modelService;

    /**
     * 加奖牌,返回所有结果
     * @param country
     * @param score
     * @param request
     * @return
     */
    @RequestMapping("ranking")
    public String ranking(@Param("country") String country, @Param("score")  Double score, HttpServletRequest request){
        List<Model> rankList = modelService.ranking(country, score);
        request.setAttribute("rankList",rankList);

        return "index";
    }
/**
 * 加奖牌,返回所有结果
 * @param country
 * @param score
 * @param request
 * @return
 */
@RequestMapping("ranking2")
public String ranking2(@Param("country") String country, @Param("score")  Double score, HttpServletRequest request){
    List<Model> rankList = modelService.ranking2(country, score);
    request.setAttribute("rankList",rankList);
    return "index";
}

}


service层

```java
@Service
public class ModelServiceImpl {
    /**
     * country 前端传过来的国家
     * score 前端定好了金牌10000  银牌100 铜牌1
     */
    @Autowired
    private RedisTemplate<String,String> redisTemplate;
    //加号和返回数据
    public List<Model> ranking(String country, Double score) {

        if(country==null||country.equals("")){
        }else{
            //修改对应的score,前端传过来了一个金牌金牌score+10000  银牌+100 铜牌+1
            redisTemplate.opsForZSet().incrementScore("model",country,score);
        }

        /**
         * 索引倒序排列指定区间元素。
         * @param key 键
         * @param start 开始位置
         * @param end 结束位置
         * @return 返回倒排后的结果
         */
        Set<String> set = redisTemplate.opsForZSet().reverseRange("model", 0, -1);
        List<Model> list=new ArrayList<>();
        //遍历区间元素,区间中全是国家名称
        for (String s : set) {
            Model model=new Model();
            //获取对应value(国家)的score的值
            Double rank = redisTemplate.opsForZSet().score("model", s);
            //金牌数
            int gold= (int) (rank/10000);
            //银牌数
            int silver= (int) (rank/100%100);
            //铜牌数
            int copper= (int) (rank%100);
            //总量
            int count=gold+silver+copper;
            //获得所有数据存入model中
            model.setCountry(s);
            model.setGold(gold);
            model.setSilver(silver);
            model.setCopper(copper);
            model.setTotal(count);
            //放在集合中
            list.add(model);
        }
        return list;
    }
    //减号和返回数据
    public List<Model> ranking2(String country, Double score) {

        if(country==null||country.equals("")){
        }else{
            //修改对应的score,前端传过来了一个金牌金牌score+10000  银牌+100 铜牌+1
            redisTemplate.opsForZSet().incrementScore("model",country,-score);
        }

        /**
         * 索引倒序排列指定区间元素。
         * @param key 键
         * @param start 开始位置
         * @param end 结束位置
         * @return 返回倒排后的结果
         */
        Set<String> set = redisTemplate.opsForZSet().reverseRange("model", 0, -1);
        List<Model> list=new ArrayList<>();
        //遍历区间元素,区间中全是国家名称
        for (String s : set) {
            Model model=new Model();
            //获取对应value(国家)的score的值
            Double rank = redisTemplate.opsForZSet().score("model", s);
            //金牌数
            int gold= (int) (rank/10000);
            //银牌数
            int silver= (int) (rank/100%100);
            //铜牌数
            int copper= (int) (rank%100);
            //总量
            int count=gold+silver+copper;
            //获得所有数据存入model中
            model.setCountry(s);
            model.setGold(gold);
            model.setSilver(silver);
            model.setCopper(copper);
            model.setTotal(count);
            //放在集合中
            list.add(model);
        }
        return list;
    }
}

pojo层

import lombok.Data;

@Data
public class Model {
    private String country;
    private int gold;
    private int silver;
    private int copper;
    private int total;
}

config层:

/**
 * @ClassName RedisConfig
 * @Description TODO
 * @Author guoweixin
 * @Version 1.0
 */
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
    @Bean
    public RedisTemplate<String,Object> redisTemplate(LettuceConnectionFactory factory){
        RedisTemplate<String,Object> template = new RedisTemplate <>();
        template.setConnectionFactory(factory);

        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();

        // 在使用注解@Bean返回RedisTemplate的时候,同时配置hashKey与hashValue的序列化方式。
        // key采用String的序列化方式
        template.setKeySerializer(stringRedisSerializer);
        // value序列化方式采用jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);

        // hash的key也采用String的序列化方式
        template.setHashKeySerializer(stringRedisSerializer);
        // hash的value序列化方式采用jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }
}

效果图:
Redis数据库zset实现简单排行榜功能
3.application.yml文件

server:
port: 8081
servlet:
encoding:
charset: UTF-8

spring:

thymeleaf:
encoding: UTF-8
cache: false
prefix: classpath:/templates/
suffix: .html
mode: LEGACYHTML5
servlet:
content-type: text/html

resources:
static-locations: classpath:/templates/

redis:
port: 6379
password: root
host: 192.168.245.128
lettuce:
pool:
max-active: 8
max-idle: 8
min-idle: 0
max-wait: 1000
shutdown-timeout: 100

mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.qf.pojo
需要改自己的redis host以及密码

4.可能出现的情况
如果进页面没有数据,点击第一行的金后的+按钮
如果直接访问进来没有数据,只有第一行表头,就访问localhost:8081/ranking

上一篇:SpringCloud SpringBoot uniapp vue b2b2c 微服务 多商家入驻直播带货商城 分销商城 秒杀 高并发电商之MySQL UNION 操作符


下一篇:SQL UNION 运算符