闲杂小记(三)

广告弹窗后台管理bug修改,定时任务编写:


任务:

广告弹窗bug修改:

改:修改页面广告位置回显

定时任务编写:

(1)发布精选:

需求:

一个小时执行一次:将精选表album_top中发布时间publish_time在当前时间之前一个小时到当前时间内的记录的status改成已发布状态,并且进行小米消息推送

(2)用户积分核查:

需求:

每天执行一次:查找前一天用户做每日任务超过了最大次数的错误记录,并记录下来

问题:

1:考虑到服务器重启的话,lastTime会为null

解决方案:在京台代码块中做判断,如果lastTime为null,就把lastTime设为当天零点

static {
    if (lastTime == null) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.HOUR, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.MILLISECOND, 0);
        lastTime = cal.getTime();
    }
}
此方法是十二小时制的,如果当前时间是0-12点时lastTime则为当天零点,如果时12-24点时lastTime则为当天12:00


2:properties取值取不到,配置文件问题

解决方案:修改spring-common配置文件


收获:

1.方法名要取得有标示度,Mapper中的id取名尽量规范:取一条的时候用get开头,取list的时候用find开头

2.Dto和Vo中的属性取名尽量规范,is开头的一般是boolean型,有多个值的一般用Integer类型

3.定时任务配置文件spring-quartz

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
   http://www.springframework.org/schema/aop
   http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
   http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- 定时任务的配置文件 -->
    <!-- 第1步和第4步公用,2、3步需要自定义 -->

    <!-- 第一步:启动定时任务 -->
    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="triggers">
            <list>
                <!-- 这里可以定义多个定时任务的Bean,每一个定时任务配置一个bean -->
                <ref bean="albumTopPublishActJobTask"/>
                <!-- 预存话费的定时任务 -->
                <!-- <ref bean="prestoreTask"/> -->
                <ref bean="userScoreCheckActJobTask"/>
            </list>
        </property>
    </bean>

    <!-- 第二步 调度act定时任务,每1分钟轮询一次,这里的id属性就是第一步定义的bean属性 -->
    <bean id="albumTopPublishActJobTask" class="org.springframework.scheduling.quartz.CronTriggerBean">
        <property name="jobDetail" ref="albumTopPublishActJobMethod"/>
        <!--<property name="cronExpression" value="0/5 * * * * ?"/>-->
        <property name="cronExpression" value="0 0 * * * ?"></property><!--每小时执行一次-->
    </bean>
    <bean id="userScoreCheckActJobTask" class="org.springframework.scheduling.quartz.CronTriggerBean">
        <property name="jobDetail" ref="userScoreCheckActJobMethod"/>
        <property name="cronExpression" value="0/5 * * * * ?"/>
        <!--<property name="cronExpression" value="0 0 0 * * ?"></property>&lt;!&ndash;每天执行一次&ndash;&gt;-->
    </bean>

    <!-- 第三步 配置act定时任务所引用的Bean和方法名,这里的id即为第二步的返回ref属性-->
    <!--<bean id="actJobMethod" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
        <property name="jobClass" value="com.ibbpp.business.job.AlbumTopUpdateJob" />

    </bean> -->
    <bean name="albumTopPublishActJobMethod"
          class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject">
            <ref bean="albumTopPublishQuartzTask"/>
        </property>
        <!-- 调用类中的方法 -->
        <property name="targetMethod">
            <value>execute</value>
        </property>
        <property name="concurrent" value="false"/>
    </bean>
    <bean name="userScoreCheckActJobMethod"
          class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <property name="targetObject">
            <ref bean="userScoreCheckQuartzTask"/>
        </property>
        <!-- 调用类中的方法 -->
        <property name="targetMethod">
            <value>execute</value>
        </property>
        <property name="concurrent" value="false"/>
    </bean>

    <!--第四步 处理定时任务的Bean-->
    <bean id="albumTopPublishQuartzTask" class="com.ibbpp.business.job.AlbumTopPublishJob">
    </bean>
    <bean id="userScoreCheckQuartzTask" class="com.ibbpp.business.job.UserScoreCheckJob">
    </bean>

</beans>
4.定时任务执行类

package com.ibbpp.business.job;

/*import com.nicemother.sns.common.Constant;
import com.nicemother.sns.persistence.AnswerMapper;
import com.nicemother.sns.persistence.BatchProcessDao;*/

import com.alibaba.fastjson.JSONObject;
import com.ibbpp.base.commons.Constants;
import com.ibbpp.business.dao.AlbumTopDao;
import com.ibbpp.business.entity.AlbumTop;
import com.ibbpp.business.entity.PushMsg;
import com.ibbpp.business.service.MsgPushService;
import org.json.simple.parser.ParseException;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

//import org.json.simple.JSONObject;

public class AlbumTopPublishJob {//todo
    private static Logger logger = LoggerFactory.getLogger(AlbumTopPublishJob.class);
    private static Date lastTime;
    private static boolean done = true;

    //如果lastTime为null时,把lastTime设为当天零点
    static {
        if (lastTime == null) {
            Calendar cal = Calendar.getInstance();
            cal.set(Calendar.HOUR, 0);
            cal.set(Calendar.SECOND, 0);
            cal.set(Calendar.MINUTE, 0);
            cal.set(Calendar.MILLISECOND, 0);
            lastTime = cal.getTime();
        }
    }

    @Autowired
    private AlbumTopDao albumTopDao;

    @Autowired
    private MsgPushService msgPushService;


    public void execute() throws JobExecutionException {
        logger.info("AlbumTopPublishJob start! lastTime={}" + lastTime);

        if (!done) {
            logger.info("AlbumTopPublishJob skip!");
            return;
        }
        done = false;

        try {
            Date curDate = new Date();  //保证任务执行期间的数据,在下一次执行时被处理。

            albumTopPublishAndPush(curDate);
            lastTime = curDate;
        } catch (Exception e) {
            logger.error("AlbumTopPublishJob fail! errorMsg={}" + e.getMessage(), e);
        }

        done = true;

        logger.info("AlbumTopPublishJob end! lastTime={}" + lastTime);
    }

    private void albumTopPublishAndPush(Date curDate) throws IOException, ParseException { TODO: 16/7/26

        albumTopDao.updateStatus(curDate, lastTime);
        AlbumTop albumTop = albumTopDao.getAlbumTop(curDate, lastTime);
        albumTopPush(albumTop);

    }

    private void albumTopPush(AlbumTop albumTop) throws IOException, ParseException {
        if (albumTop == null) {
            return;
        }

        PushMsg pushMsg = new PushMsg();
        pushMsg.setTitle(Constants.PUSH_MSG_TITLE);
        pushMsg.setContent(albumTop.getDescription());
        pushMsg.setTargetType(Constants.PUSH_MSG_TATGET_TYPE);
        Map targetExtraMap = new HashMap();
        targetExtraMap.put("albumId", albumTop.getAlbumId());
        String targetExtra = JSONObject.toJSONString(targetExtraMap); //将字符串{“id”:1}
        pushMsg.setTargetExtra(targetExtra);
        msgPushService.broadcast(pushMsg,Constants.PUSH_TOPIC);
    }

}
done的默认值为true

进入方法先做判断:如果done不为true,就跳出任务

if (!done) {
            logger.info("AlbumTopPublishJob skip!");
            return;
        }
如果done为true,则在执行任务前将其设为false

done = false;
然后执行任务,如果成功之行则将lastTime设为当前时间再将done设为true,此处的lastTime放在try里面,这样是为了保证lastTime只在任务成功之行时才能被赋值为当前时间,若放在try外面,则如果任务抛出异常,lastTime也会被赋值为当前时间,这样是错误的

try {
    Date curDate = new Date();  //保证任务执行期间的数据,在下一次执行时被处理。

    albumTopPublishAndPush(curDate);
    lastTime = curDate;
} catch (Exception e) {
    logger.error("AlbumTopPublishJob fail! errorMsg={}" + e.getMessage(), e);
}

done = true;
5.sql语句收获

left jion效率较低,一千条以内的记录可以考虑使用,但不建议,毕竟记录会越来越多,所有连接查询都能拆,通常是以遍历的方式再查询一次,group by使用

private void userScoreCheck(Date curDate) {
    List<ScoreTask> scoreTaskList = scoreTaskDao.queryByLimitScope(Constants.SCORE_CHECK_TASK_LIMITSCOPR);    TODO: 16/7/30
    if (scoreTaskList == null || scoreTaskList.isEmpty()) {
        return;
    }
    for (ScoreTask scoreTask : scoreTaskList) {
        Long taskId = scoreTask.getId();
        int limitMax = scoreTask.getLimitMax();

        List<UserScoreDto> userScoreDtoList = userScoreDao.queryForCheck(curDate, lastTime, taskId, limitMax);
        if (null == userScoreDtoList || userScoreDtoList.isEmpty()) {
            return;
        }
        for (UserScoreDto userScoreDto : userScoreDtoList) {
            if (userScoreDto == null) {
                return;
            }
            UserScoreCheck userScoreCheck = transform(curDate, userScoreDto);
            userScoreCheckDao.add(userScoreCheck);
        }

    }

}

<select id="queryForCheck" resultMap="BaseResultMap">
    SELECT
    us.user_id,us.task_id,count(us.id) as record_count
    FROM  user_score us
    <where>

            create_time &gt; #{lastTime,jdbcType=TIMESTAMP}

        and  create_time &lt;= #{curDate,jdbcType=TIMESTAMP}

        <if test="taskId != null ">
            and task_id=#{taskId,jdbcType=BIGINT}
        </if>

    </where>
    group by user_id
    <if test="limitMax!=null">
        HAVING count(id)>#{limitMax,jdbcType=BIGINT}
    </if>
</select>



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值