10-2-文章分页展示

本文详细介绍了如何实现数据访问层的ArticleMapper与StatisticMapper接口,以及业务处理层的ArticleService接口。涵盖了文章查询、统计、分页、增删改查和热度分析等功能。
摘要由CSDN通过智能技术生成

一、数据访问层实现

需要同时实现文章查询和文章统计数据查询

1.创建子包dao

2.创建ArticleMapper接口

@Mapper
public interface ArticleMapper {

    // 根据id查询文章信息
    @Select("SELECT * FROM t_article WHERE id=#{id}")
    public Article selectArticleWithId(Integer id);

    // 发表文章,同时使用@Options注解获取自动生成的主键id
    @Insert("INSERT INTO t_article (title,created,modified,tags,categories," +
" allow_comment, thumbnail, content)" +
" VALUES (#{title},#{created}, #{modified}, #{tags}, #{categories}," +
" #{allowComment}, #{thumbnail}, #{content})")
    @Options(useGeneratedKeys=true, keyProperty="id", keyColumn="id")
    public Integer publishArticle(Article article);

    // 文章分页查询
    @Select("SELECT * FROM t_article ORDER BY id DESC")
    public List<Article> selectArticleWithPage();

    // 通过id删除文章
    @Delete("DELETE FROM t_article WHERE id=#{id}")
    public void deleteArticleWithId(int id);

    // 站点服务统计,统计文章数量
    @Select("SELECT COUNT(1) FROM t_article")
    public Integer countArticle();

    // 通过id更新文章
    public Integer updateArticleWithId(Article article);
}

3.创建StatisticMapper接口

@Mapper
public interface StatisticMapper {

    // 新增文章对应的统计信息
    @Insert("INSERT INTO t_statistic(article_id,hits,comments_num) values (#{id},0,0)")
    public void addStatistic(Article article);

    // 根据文章id查询点击量和评论量相关信息
    @Select("SELECT * FROM t_statistic WHERE article_id=#{articleId}")
    public Statistic selectStatisticWithArticleId(Integer articleId);

    // 通过文章id更新点击量
    @Update("UPDATE t_statistic SET hits=#{hits} " +
"WHERE article_id=#{articleId}")
    public void updateArticleHitsWithId(Statistic statistic);

    // 通过文章id更新评论量
    @Update("UPDATE t_statistic SET comments_num=#{commentsNum} " +
"WHERE article_id=#{articleId}")
    public void updateArticleCommentsWithId(Statistic statistic);

    // 根据文章id删除统计数据
    @Delete("DELETE FROM t_statistic WHERE article_id=#{aid}")
    public void deleteStatisticWithId(int aid);

    // 统计文章热度信息
    @Select("SELECT * FROM t_statistic WHERE hits !='0' " +
"ORDER BY hits DESC, comments_num DESC")
    public List<Statistic> getStatistic();

    // 统计博客文章总访问量
    @Select("SELECT SUM(hits) FROM t_statistic")
    public long getTotalVisit();

    // 统计博客文章总评论量
    @Select("SELECT SUM(comments_num) FROM t_statistic")
    public long getTotalComment();
}

4、创建映射文件ArticleMapper.xml

因为使用注解方式动态拼接更新文章的sql语句十分不便,所以使用xml方式动态拼接sql。

于是在resources目录下创建mapper文件夹,并创建映射文件ArticleMapper.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.itheima.dao.ArticleMapper">
    <update id="updateArticleWithId" parameterType="Article">
        update t_article
        <set>
            <if test="title != null">
                title = #{title},
            </if>
            <if test="created != null">
                created = #{created},
            </if>
            <if test="modified != null">
                modified = #{modified},
            </if>
            <if test="tags != null">
                tags = #{tags},
            </if>
            <if test="categories != null">
                categories = #{categories},
            </if>
            <if test="hits != null">
                hits = #{hits},
            </if>
            <if test="commentsNum != null">
                comments_num = #{commentsNum},
            </if>
            <if test="allowComment != null">
                allow_comment = #{allowComment},
            </if>
            <if test="thumbnail != null">
                thumbnail = #{thumbnail},
            </if>
            <if test="content != null">
                content = #{content},
            </if>
        </set>
        where id = #{id}
    </update>
</mapper>

二、实现文章业务处理层

1.创建service子包

2.创建IArticleService接口

public interface IArticleService {
    // 分页查询文章列表,第一页page=1
    public PageInfo<Article> selectArticleWithPage(Integer page, Integer count);
    // 统计前10的热度文章信息
    public List<Article> getHeatArticles();
}

3.创建service.impl子包

4.创建文章服务实现类ArticleServiceImpl

@Service
@Transactional
public class ArticleServiceImpl implements IArticleService {

    @Autowired
    private ArticleMapper articleMapper;
    @Autowired
    private StatisticMapper statisticMapper;

    // 分页查询文章列表
    @Override
    public PageInfo<Article> selectArticleWithPage(Integer page, Integer count) {
        //第一页page=1
        PageHelper.startPage(page, count);
        List<Article> articleList = articleMapper.selectArticleWithPage();
        // 封装文章统计数据
        for (int i = 0; i < articleList.size(); i++) {
            Article article = articleList.get(i);
            Statistic statistic = statisticMapper.selectStatisticWithArticleId(article.getId());
            article.setHits(statistic.getHits());
            article.setCommentsNum(statistic.getCommentsNum());
        }
        PageInfo<Article> pageInfo=new PageInfo<>(articleList);
        return pageInfo;
    }

    // 统计前10的热度文章信息
    @Override
    public List<Article> getHeatArticles( ) {
        List<Statistic> list = statisticMapper.getStatistic();
        List<Article> articlelist=new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            Article article = articleMapper.selectArticleWithId(list.get(i).getArticleId());
            article.setHits(list.get(i).getHits());
            article.setCommentsNum(list.get(i).getCommentsNum());
            articlelist.add(article);
            if(i>=9){
                break;
            }
        }
        return articlelist;
    }
}

三、处理获取首页的请求

1.创建子web.client

2.创建博客首页处理类IndexController

编写文章分页查询和热度统计的方法,同时进行路径映射。

另外,对查询出的文章信息articles和热度文章articleList都向Request域中进行了存储,

并跳转到项目类目录下client目录中的index.html文件,这样在该前端页面上就可以直接取用。

@Controller
public class IndexController {

    private static final Logger logger = LoggerFactory.getLogger(IndexController.class);
    @Autowired
    private IArticleService articleServiceImpl;
    
    // 博客首页,会自动跳转到文章页
    @GetMapping(value = "/")
    private String index(HttpServletRequest request) {
        return this.index(request, 1, 5);
    }

    // 文章页
    @GetMapping(value = "/page/{p}")
    public String index(HttpServletRequest request, @PathVariable("p") int page, @RequestParam(value = "count", defaultValue = "5") int count) {
        PageInfo<Article> articles = articleServiceImpl.selectArticleWithPage(page, count);
        // 获取文章热度统计信息
        List<Article> articleList = articleServiceImpl.getHeatArticles();
        request.setAttribute("articles", articles);
        request.setAttribute("articleList", articleList);
        logger.info("分页获取文章信息: 页码 "+page+",条数 "+count);
        return "client/index";
    }
}

3.创建子web.interceptor

4.自定义拦截器BaseInterceptor

前端页面需要转换数据、日期、图片等,我们可以把转换数据的工具类放到request域中,所以需要拦截器拦截请求,把工具放进request域中。

/**
 * 自定义的Interceptor拦截器类,用于封装Commons工具类到request域中,供html页面使用
 * 注意:自定义Mvc的Interceptor拦截器类
 *  1、使用@Configuration注解声明
 *  2、自定义注册类将自定义的Interceptor拦截器类进行注册使用
 */

@Configuration
public class BaseInterceptor implements HandlerInterceptor {

    @Autowired
    private Commons commons;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 用户将封装的Commons工具返回页面
        request.setAttribute("commons",commons);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }

}

5.注册拦截器

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Autowired
    private BaseInterceptor baseInterceptor;

    @Override
    // 重写addInterceptors()方法,注册自定义拦截器
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(baseInterceptor);
    }
}

四、实现前端页面功能

打开项目类目录下client目录中的项目首页index.html

该博客客户端首页面主要包括文章列表展示、分页控制和阅读排行榜展示三部分。

其中,在页面首尾和分页部分,使用了th:replace属性引入外部模板文件;

在数据列表展示和阅读排行榜展示部分使用th:each属性对封装在Request域中的文章信息进行了遍历和展示。

五、效果展示

启动项目,项目启动成功后,使用首页映射路径“/”进行访问

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值