美文网首页Spring Boot
仿微信运动排行榜的定时任务练习

仿微信运动排行榜的定时任务练习

作者: 飞逝1 | 来源:发表于2018-10-23 15:51 被阅读0次

    首先,我们先看一下微信运动排行榜的页面以及大致的工作原理。

    timg.jpg

    微信排行榜的每天定时刷新就是定时任务最常用的场景,像我们的微信运动每天晚上大约都是在10点多定时刷新数据。

    下面,我将写一个模仿这样的定时任务的例子。

    目录结构

    目录结构(定时任务).png

    在Config包下新建QuartzConfig,SporterJob,SportJobFactory类

    • QuartzConfig类
    public class QuartzConfig {
        @Autowired
        private SpringJobFactory springJobFactory;
    
        @Bean
        public SchedulerFactoryBean schedulerFactoryBean(){
            SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
            schedulerFactoryBean.setJobFactory(springJobFactory);
            return schedulerFactoryBean;
        }
    
        @Bean
        public Scheduler scheduler() {
            return schedulerFactoryBean().getScheduler();
        }
    }
    
    • SporterJob类
    @Component
    public class SporterJob {
    
        @Resource
        private UpdateService updateService;
    
        @Scheduled(cron = "0 26 22 * * ?")
        public void updateTodayWalks() throws Exception {
            updateService.updateWalks();
        }
    }
    

    corn里设置刷新时间,corn的用法见我之前的文章。

    • SporterJobFactory类
    @Component
    public class SpringJobFactory extends AdaptableJobFactory {
        @Autowired
        private AutowireCapableBeanFactory capableBeanFactory;
    
        @Override
        protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
            Object jobInstance = super.createJobInstance(bundle);
            capableBeanFactory.autowireBean(jobInstance);
            return jobInstance;
        }
    }
    

    实体类

    • 运动者(Walker)
    @Entity
    @Data
    public class Walker implements Serializable {
        @Id
        @GeneratedValue
        private Integer id;
        private String account;
        private String password;
        private String nickname;
        private String avatar;
    
    
        @OneToMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
        @JoinColumn(name = "account",referencedColumnName = "account")
        private List<SportData> sportDataList;
    
        public Walker(String account, String password, String nickname, String avatar, List<SportData> sportDataList) {
            this.account = account;
            this.password = password;
            this.nickname = nickname;
            this.avatar = avatar;
            this.sportDataList = sportDataList;
        }
    }
    
    • 运动数据(SportData)
    @Entity
    @Data
    public class SportData implements Serializable {
        @Id
        @GeneratedValue
        private Integer id;
        private Integer steps;
        private String evaluate;
        private Date date;
    
        public SportData(Integer steps, String evaluate, Date date) {
            this.steps = steps;
            this.evaluate = evaluate;
            this.date = date;
        }
    }
    
    • UpdateService类
    public interface UpdateService {
        void updateWalks();
    }
    
    • SportDataRepositry接口
    
    public interface SportDataRepositry extends JpaRepository<SportData,Integer> {
    }
    
    • 实现类(UpdateServiceImpl)
    @Service
    public class UpdateServiceImpl implements UpdateService {
        @Resource
        private SportDataRepositry sportDataRepositry;
    
        @Override
        public void updateWalks() {
            List<SportData> list = sportDataRepositry.findAll();
            Random random = new Random();
            for (int i=0;i <list.size();i++) {
                SportData sportData = list.get(i);
                sportData.setSteps(random.nextInt(2000)+2000);
                sportData.setDate(new Date());
                sportDataRepositry.saveAndFlush(sportData);
            }
        }
    }
    

    页面代码

    • 登录界面
    <html xmlns:th="http://www.thymeleaf.org">
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <!--<link rel="stylesheet" href="/webjars/bootstrap/3.3.7-1/css/bootstrap.min.css"/>-->
        <!--<link type="text/css" rel="stylesheet" href="login.css"/>-->
        <title>Title</title>
        <style>
            *{padding: 0;margin: 0;} /* 清除浮动 */
            body {
                font-family:"Microsoft YaHei";
                background:#EBEBEB;
                font-weight: 300;
                font-size: 15px;
                color: #333;
                overflow: hidden;
            }
            a {text-decoration: none; color:#000;}
            a:hover{color:#F87982;} /*home*/
            #home { /*logint界面*/
                padding-top:100px;
            }
            #login{
                padding:20px 30px 30px;
                width:300px;
                background:#FFF;
                margin:auto;
                border-radius: 3px;
                box-shadow: 0 3px 3px rgba(0, 0, 0, 0.3);
            }
            #login h3{
                font-size:18px;
                line-height:25px;
                font-weight:300;
                letter-spacing:3px;
                margin-bottom:20px;
                color:#C8C8C8;
                text-align:center;}
            #login label{
                color:#C8C8C8;
                display:block;
                height:35px;
                padding:0 10px;
                font-size:12px;
                line-height:35px;
                background:#EBEBEB;
                margin-bottom:10px;
                position:relative;}
            #login label input{
                font:13px/20px "Microsoft YaHei";
                background:none;  height:20px;
                border:none; margin:7px 0 0 10px;
                width:245px;outline:none ;
                letter-spacing:normal;
                z-index:1; position:relative;
            }
            #login label  span{
                display:block;
                height:35px;
                color:#F30;
                width:100px;
                position:absolute;
                top:0;
                left:190px;
                text-align:right;
                padding:0 10px 0 0;
                z-index:0;
                display:none;
            }
            #login #button{
                font-family:"Microsoft YaHei";
                cursor:pointer;
                width:300px;
                height:35px;
                background:#FE4E5B;
                border:none;
                font-size:14px;
                line-height:30px;
                letter-spacing:3px;
                color:#FFF;
                position:relative;
                margin-top:10px;
                -moz-transition: all 0.2s ease-in;
                -webkit-transition: all 0.2s ease-in;
                -o-transition: all 0.2s ease-in;
                transition: all 0.2s ease-in;}
            #login #button:hover{ background:#F87982; color:#000;}
            .avator{
                display:block;
                margin:0 auto 20px;
                border-radius:50%;
            }
        </style>
    </head>
    <body>
    <div id="home">
        <form id="login" action="/sporter/list" method="get" class="current1">
            <h3>用户登入</h3>
            <img class="avator" src="img/avatar.jpg" width="96" height="96"/>
            <label>账号<input type="text" name="account" style="width:215px;" />
                <span>账号为空</span></label>
            <label>密码<input type="password" name="password"  />
                <span>密码为空</span></label>
            <input type="submit" id="button"></input>
        </form>
    </div>
    </body>
    </html>
    
    • 运动数据界面
    <html xmlns:th="http://www.thymeleaf.org">
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <link rel="stylesheet" href="/webjars/bootstrap/3.3.7-1/css/bootstrap.min.css"/>
        <title>SporterList</title>
        <style>
            .top-nav {
                height: 60px;
            }
            .top-img {
                height: 36px;
            }
            .top-title {
                font-size: 20px;
                color: black;
                line-height: 60px;
            }
            p {
                margin: 0;
                padding: 0;
            }
            .icon1 {
                margin-right: 20px;
                line-height: 60px;
            }
            .icon2 {
                margin-right: 20px;
                line-height: 60px;
            }
            .center-nav {
                width: 100%;
                /*margin-top: 60px;*/
                height: 40px;
                border-bottom: solid #E0E0E0 2px;
                margin-top: -20px;
            }
            .center-nav .col-md-2 {
                border: solid #E0E0E0 1px;
            }
            .center-container{
                margin: 0 180px;
                height: 40px;
            }
            .center-list{
                text-align: center;
                line-height: 37px;
                font-size: 16px;
                font-weight: bold;
                /*border: solid #E0E0E0 1px;*/
            }
            .main{
                margin-top: 40px;
            }
            .main .center-img {
                width: 200px;
                height: 140px;
            }
            .article-div {
                width: 100%;
                height: 300px;
                padding: 20px;
                margin-bottom: 20px;
                border: solid #E0E0E0 1px;
            }
            .article-div .bottom-info {
                margin-top: 20px;
            }
            .article-div .avatar-img{
                width: 40px;
                height: 40px;
                border-radius: 50%;
            }
            .bottom-info-right {
                display: inline-block;
                width: 40px;
                height: 40px;
                float: right;
                padding-right: 30px;
            }
            #person_avatar {
                border-radius: 50px;
                width: 40px;
                height: 40px;
            }
        </style>
    </head>
    <body>
    <nav class="navbar navbar-default navbar-static-top">
        <div class="container top-nav">
            <div class="col-md-4">
            </div>
            <div class="col-md-4">
                <p class="top-title text-center ">步数排行榜</p>
            </div>
            <div class="col-md-4 text-right">
                <a><span class="glyphicon glyphicon-pencil icon1"></span></a>
                <a><span class="glyphicon glyphicon-search icon2"></span></a>
                <a class="navbar-brand navbar-right" href="#">
                    <img id="person_avatar" th:src="@{${person.avatar}}">
                </a>
            </div>
        </div>
    </nav>
    <div class="container">
        <div class="col-md-4">
    
        </div>
        <div class="col-md-4">
            <div class="thumbnail" th:each="sport:${list}">
                <img th:src="@{${sport.avatar}}">
                <div class="caption">
                    <h3 th:text="${sport.nickname}"></h3>
                    <div th:each="walk:${sport.sportDataList}">
                        <h4 th:text="${walk.steps}"></h4>
                    </div>
                </div>
            </div>
        </div>
        <div class="col-md-4">
    
        </div>
    </div>
    </body>
    </html>
    

    数据库截图

    SportData.png Walker.png

    最终展示

    login.png 刷新前数据.png 刷新后数据.png

    相关文章

      网友评论

        本文标题:仿微信运动排行榜的定时任务练习

        本文链接:https://www.haomeiwen.com/subject/petazftx.html