实现会员交互功能

阅读状态变更

首先,在com.ql.reader.entity包下创建阅读状态实体类

package com.ql.reader.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;

import java.util.Date;

/**
 * 会员阅读状态实体
 */
@TableName("member_read_state")
public class MemberReadState {
    @TableId(type = IdType.AUTO)
    private Long rsId;
    private Long bookId;
    private Long memberId;
    private Integer readState;
    private Date createTime;

    public Long getRsId() {
        return rsId;
    }

    public void setRsId(Long rsId) {
        this.rsId = rsId;
    }

    public Long getBookId() {
        return bookId;
    }

    public void setBookId(Long bookId) {
        this.bookId = bookId;
    }

    public Long getMemberId() {
        return memberId;
    }

    public void setMemberId(Long memberId) {
        this.memberId = memberId;
    }

    public Integer getReadState() {
        return readState;
    }

    public void setReadState(Integer readState) {
        this.readState = readState;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }
}

然后在com.ql.reader.mapper包下创建mapper接口

package com.ql.reader.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ql.reader.entity.Category;
import com.ql.reader.entity.MemberReadState;

public interface MemberReadStateMapper extends BaseMapper<MemberReadState> {
}

在src/main/resources/mappers目录下创建member_read_state.xml映射文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ql.reader.mapper.MemberReadStateMapper">

</mapper>

然后打开MemberService.java添加获得阅读状态方法,并在MemberServiceImpl.java添加相应方法实现。

/**
     * 获得阅读状态
     * @param memberId 会员编号
     * @param bookId 图书编号
     * @return 阅读状态对象
     */
    public MemberReadState selectMemberReadState(Long memberId, Long bookId);
/**
     * 获得阅读状态
     *
     * @param memberId 会员编号
     * @param bookId   图书编号
     * @return 阅读状态对象
     */
    public MemberReadState selectMemberReadState(Long memberId, Long bookId) {
        QueryWrapper<MemberReadState> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("book_id", bookId);
        queryWrapper.eq("member_id", memberId);
        MemberReadState memberReadState = memberReadStateMapper.selectOne(queryWrapper);
        return memberReadState;
    }

打开BookController.java,在展示图书细节方法里添加获取会员阅读状态的代码逻辑

@GetMapping("/book/{id}")
    public ModelAndView showDetail(@PathVariable("id") Long id, HttpSession session){
        Book book = bookService.selectById(id);
        List<Evaluation> evaluationList = evaluationService.selectByBookId(id);
        Member member = (Member) session.getAttribute("loginMember");
        ModelAndView mav = new ModelAndView("/detail");
        if(member!=null){
            //获取会员阅读状态
            MemberReadState memberReadState = memberService.selectMemberReadState(member.getMemberId(), id);
            mav.addObject("memberReadState", memberReadState);
        }
        mav.addObject("book", book);
        mav.addObject("evaluationList", evaluationList);
        return mav;
    }

运行项目测试。

java 会员ID java添加会员信息_servlet


java 会员ID java添加会员信息_java 会员ID_02

更新会员阅读状态

打开MemberService.java添加更新阅读状态方法,并在MemberServiceImpl.java添加相应方法实现。

/**
     * 更新阅读状态
     * @param memberId 会员编号
     * @param bookId 图书编号
     * @param readState 阅读状态
     * @return 阅读状态对象
     */
    public MemberReadState updateMemberReadState(Long memberId, Long bookId, Integer readState);
/**
     * 更新阅读状态
     *
     * @param memberId  会员编号
     * @param bookId    图书编号
     * @param readState 阅读状态
     * @return 阅读状态对象
     */
    public MemberReadState updateMemberReadState(Long memberId, Long bookId, Integer readState) {
        QueryWrapper<MemberReadState> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("book_id", bookId);
        queryWrapper.eq("member_id", memberId);
        MemberReadState memberReadState = memberReadStateMapper.selectOne(queryWrapper);
        //无则新增,有则更新
        if(memberReadState==null){
            memberReadState = new MemberReadState();
            memberReadState.setMemberId(memberId);
            memberReadState.setBookId(bookId);
            memberReadState.setReadState(readState);
            memberReadState.setCreateTime(new Date());
            memberReadStateMapper.insert(memberReadState);
        }else{
            memberReadState.setReadState(readState);
            memberReadStateMapper.updateById(memberReadState);
        }
        return memberReadState;
    }

打开BookController.java,添加更新想看/看过阅读状态方法

/**
     * 更新想看/看过阅读状态
     * @param memberId 会员id
     * @param bookId 图书id
     * @param readState 阅读状态
     * @return 处理结果
     */
    @PostMapping("/update_read_state")
    @ResponseBody
    public Map updateReadState(Long memberId, Long bookId, Integer readState){
        Map result = new HashMap();
        try {
            memberService.updateMemberReadState(memberId, bookId, readState);
            result.put("code", "0");
            result.put("msg", "success");
        }catch (BussinessException e){
            e.printStackTrace();
            result.put("code", e.getCode());
            result.put("msg", e.getMsg());
        }
        return result;
    }

运行项目测试

java 会员ID java添加会员信息_servlet_03


java 会员ID java添加会员信息_servlet_04

写短评

首先打开MemberService.java添加新增短评方法,并在MemberServiceImpl.java里添加相应方法实现。

/**
     * 发布新的短评
     * @param memberId 会员编号
     * @param bookId 图书编号
     * @param score 评分
     * @param content 短评内容
     * @return 短评对象
     */
    public Evaluation evaluate(Long memberId, Long bookId, Integer score, String content);
/**
     * 发布新的短评
     *
     * @param memberId 会员编号
     * @param bookId   图书编号
     * @param score    评分
     * @param content  短评内容
     * @return 短评对象
     */
    public Evaluation evaluate(Long memberId, Long bookId, Integer score, String content) {
        Evaluation evaluation = new Evaluation();
        evaluation.setMemberId(memberId);
        evaluation.setBookId(bookId);
        evaluation.setScore(score);
        evaluation.setContent(content);
        evaluation.setState("enable");
        evaluation.setEnjoy(0);
        evaluation.setCreateTime(new Date());
        evaluationMapper.insert(evaluation);
        return evaluation;
    }

然后打开MemberController.java添加新增短评调用方法

@PostMapping("/evaluate")
    @ResponseBody
    public Map evaluate(Long memberId, Long bookId, Integer score, String content){
        Map result = new HashMap();
        try {
            memberService.evaluate(memberId, bookId, score, content);
            result.put("code", "0");
            result.put("msg", "success");
        }catch (BussinessException e){
            e.printStackTrace();
            result.put("code", e.getCode());
            result.put("msg", e.getMsg());
        }
        return result;
    }

前端代码为detail.ftl中短评代码部分

<script>
    ...
    $(function () {
    <#if !loginMember ??>
		...
            $("#btnEvaluation").click(function(){
                // 转换为星型组件
                $("#score").raty({});
                // 显示短评对话框
                $("#dlgEvaluation").modal("show");
            })
            // 评论对话框提交数据
            $("#btnSubmit").click(function(){
                // 获取评分
                var score = $("#score").raty("score");
                var content = $("#content").val();
                if(score == 0 || $.trim(content) == ""){
                    return;
                }
                $.post("/evaluate" , {
                    score : score,
                    bookId : ${book.bookId},
                    memberId : ${loginMember.memberId},
                    content : content
                },function(json){
                    if(json.code == "0"){
                        // 刷新当前页面
                        window.location.reload();
                    }
                },"json")
            })
			
            </#if>
        })
    </script>

运行项目测试

java 会员ID java添加会员信息_开发语言_05


java 会员ID java添加会员信息_lua_06

短评点赞

首先打开MemberService.java添加新增短评点赞方法,并在MemberServiceImpl.java里添加相应方法实现。

/**
     * 短评点赞
     * @param evaluationId 短评编号
     * @return 短评对象
     */
    public Evaluation enjoy(Long evaluationId);
/**
     * 短评点赞
     *
     * @param evaluationId 短评编号
     * @return 短评对象
     */
    public Evaluation enjoy(Long evaluationId) {
        Evaluation evaluation = evaluationMapper.selectById(evaluationId);
        evaluation.setEnjoy(evaluation.getEnjoy()+1);
        evaluationMapper.updateById(evaluation);
        return evaluation;
    }

然后打开MemberController.java添加新增短评点赞调用方法

@PostMapping("/enjoy")
    @ResponseBody
    public Map enjoy(Long evaluationId){
        Map result = new HashMap();
        try {
            Evaluation evaluation = memberService.enjoy(evaluationId);
            result.put("code", "0");
            result.put("msg", "success");
            result.put("evaluation", evaluation);
        }catch (BussinessException e){
            e.printStackTrace();
            result.put("code", e.getCode());
            result.put("msg", e.getMsg());
        }
        return result;
    }

前端代码为detail.ftl中短评点赞代码部分

<script>
...
   // 评论点赞
   $("*[data-evaluation-id]").click(function(){
       debugger
       var evaluationId = $(this).data("evaluation-id");
       $.post("/enjoy",{evaluationId:evaluationId},function(json){
           if(json.code == "0"){
               $("*[data-evaluation-id='" + evaluationId + "'] span").text(json.evaluation.enjoy);
           }
       },"json")
   })
   ...
</script>

运行项目测试

java 会员ID java添加会员信息_java 会员ID_07

Spring Task定时任务

Spring Task是Spring 3.0后推出的定时任务模块。
Spring Task的职责是按周期后台自动执行任务。
Spring Task可利用Cron表达式实现灵活的定时处理。

Cron表达式实例

java 会员ID java添加会员信息_lua_08


第一行为每分钟的0秒执行任务。

第二行为2000年的每小时的前五分钟每0秒和30秒执行任务。

第三行为每周三的9点到18点的每个小时的整点执行任务。

利用Spring-Task自动计算图书评分

打开book.xml文件添加更新图书评分的sql语句

<update id="updateEvaluation">
        update book b set evaluation_score = (
            select ifnull(avg(score), 0) from evaluation where book_id = b.book_id and state = 'enable'
            ),evaluation_quantity = (
            select ifnull(count(*), 0) from evaluation where book_id = b.book_id and state = 'enable'
            )
    </update>

然后打开BookMapper.java添加对应的方法

public interface BookMapper extends BaseMapper<Book> {
    /**
     * 更新图书评分、评价数量
     */
    public void updateEvaluation();
}

然后打开BookService.java添加更新图书评分、评价数量方法,并在在BookServiceImpl.java添加方法实现

/**
     * 更新图书评分、评价数量
     */
    public void updateEvaluation();
/**
     * 更新图书评分、评价数量
     */
    @Transactional
    public void updateEvaluation() {
        bookMapper.updateEvaluation();
    }

Spring Task底层依赖包含在spring-context依赖里,所以不需要额外引入依赖。
打开applicationContext.xml添加Spring Task配置

<!--开启Spring Task定时任务的注解模式-->
    <task:annotation-driven/>

然后在com.ql.reader.task包下创建ComputeTask.java编写自动计算任务代码

package com.ql.reader.task;

import com.ql.reader.service.BookService;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * 完成自动计算任务
 */
@Component
public class ComputeTask {
    @Resource
    private BookService bookService;
    //任务调度
    @Scheduled(cron = "0 * * * * ?")
    public void updateEvaluation(){
        bookService.updateEvaluation();
        System.out.println("已更新所有图书评分");
    }
}

运行项目,登录并打开一个书籍评分为:

java 会员ID java添加会员信息_java_09


添加评分为:

java 会员ID java添加会员信息_java 会员ID_10


添加完等下一分钟看到调度任务已执行,刷新页面,此时该书评分已变。

java 会员ID java添加会员信息_lua_11


java 会员ID java添加会员信息_开发语言_12