需求介绍—社区首页

根据之前的学习,我们一般都是先按照DAO->Service->Controller这个顺序去开发

分布实现:

开发社区首页,显示前十个帖子。

开发分页组件,分页显示所有的帖子

代码实现

首先我们要知道贴子我们是放在discuss_post这个表里面,所以我们的操作都是根据这个表来操作。

那第一步来写一下DiscussPost实体类对应这个表里面的字段。

package com.nowcoder.community.entity;

import java.util.Date;

public class DiscussPost {
private int id; private int userId; private String title; private String content; private int type; private int status; private Date createTime; private int commentCount; private double score; public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public int getUserId() {
return userId;
} public void setUserId(int userId) {
this.userId = userId;
} public String getTitle() {
return title;
} public void setTitle(String title) {
this.title = title;
} public String getContent() {
return content;
} public void setContent(String content) {
this.content = content;
} public int getType() {
return type;
} public void setType(int type) {
this.type = type;
} public int getStatus() {
return status;
} public void setStatus(int status) {
this.status = status;
} public Date getCreateTime() {
return createTime;
} public void setCreateTime(Date createTime) {
this.createTime = createTime;
} public int getCommentCount() {
return commentCount;
} public void setCommentCount(int commentCount) {
this.commentCount = commentCount;
} public double getScore() {
return score;
} public void setScore(double score) {
this.score = score;
} @Override
public String toString() {
return "DiscussPost{" +
"id=" + id +
", userId=" + userId +
", title='" + title + '\'' +
", content='" + content + '\'' +
", type=" + type +
", status=" + status +
", createTime=" + createTime +
", commentCount=" + commentCount +
", score=" + score +
'}';
}
}

  那么我们对应去开发DiscussPostMapper,完成对应对于这个数据库操作的函数声明。

package com.nowcoder.community.dao;

import com.nowcoder.community.entity.DiscussPost;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param; import java.util.List; @Mapper
public interface DiscussPostMapper { /* 查到的事多个帖子,所以是集合,这个userId是为了开发我的主页的时候才需要,但是首页的时候就不传,
得到的是0,那么对应的就是一个动态的sql*/
List<DiscussPost> selectDiscussPosts(int userId, int offset, int limit);
// @Param 用来为参数取别名
//如果需要动态的拼一个条件,在<if>里面使用,并且这个方法有且只有一个参数,这个参数前面必须取别名
// 这个userId和上面是一样的功能
int selectDiscussPostRows(@Param("userId") int userId); // int insertDiscussPost(DiscussPost discussPost); }

  

那么函数声明了,就要去discusspost-mapper.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.nowcoder.community.dao.DiscussPostMapper"> <sql id="selectFields">
id, user_id, title, content, type, status, create_time, comment_count, score
</sql> <select id="selectDiscussPosts" resultType="DiscussPost">
select <include refid="selectFields"></include>
from discuss_post
where status != 2
<if test="userId!=0">
and user_id = #{userId}
</if>
order by type desc, create_time desc
limit #{offset}, #{limit}
</select> <select id="selectDiscussPostRows" resultType="int">
select count(id)
from discuss_post
where status != 2
<if test="userId!=0">
and user_id = #{userId}
</if>
</select> </mapper>

  

至此数据访问层就开发完了,那么要继续开发业务组件DiscussPostService。

package com.nowcoder.community.service;

import com.nowcoder.community.dao.DiscussPostMapper;
import com.nowcoder.community.entity.DiscussPost;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import java.util.List; @Service
public class DiscussPostService { @Autowired
private DiscussPostMapper discussPostMapper; public List<DiscussPost> findDiscussPosts(int userId, int offset, int limit) {
return discussPostMapper.selectDiscussPosts(userId, offset, limit);
} public int findDiscussPostRows(int userId) {
return discussPostMapper.selectDiscussPostRows(userId);
} }

  

但是现在有个问题就是在平时的时候我们在页面上显示的肯定都是显示username而不是userId所以我们需要写个方法把两者关联起来,因为这个只涉及到User那么我们可以对写UserService对其进行操作

package com.nowcoder.community.service;

import com.nowcoder.community.dao.UserMapper;
import com.nowcoder.community.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; @Service
public class UserService { @Autowired
private UserMapper userMapper; public User findUserById(int id) {
return userMapper.selectById(id);
}
}

  

那么至此业务层的逻辑我们就写完了,现在就开始写表现层DiscussController:

我们先查前10条的帖子

package com.nowcoder.community.controller;

import com.nowcoder.community.entity.DiscussPost;
import com.nowcoder.community.entity.Page;
import com.nowcoder.community.entity.User;
import com.nowcoder.community.service.DiscussPostService;
import com.nowcoder.community.service.LikeService;
import com.nowcoder.community.service.UserService;
import com.nowcoder.community.util.CommunityConstant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; // 初始化界面以及分页功能点实现
@Controller
public class HomeController implements CommunityConstant { @Autowired
private DiscussPostService discussPostService; @Autowired
private UserService userService; @RequestMapping(path = "/index", method = RequestMethod.GET)
public String getIndexPage(Model model) {
// 方法调用之前,SpringMVC会自动实例化Model和Page,并将Page注入到Model中
// 所以,在thymeleaf中可以直接访问Page对象中的数据。
List<DiscussPost> list = discussPostService.findDiscussPosts(0,0,10);
// 把上面这个集合遍历一遍,但是它们的数据是不完整的,比方说我们查到的只是id不是userId
List<Map<String, Object>> discussPosts = new ArrayList<>();
if (list != null) {
for(DiscussPost post : list) {
Map<String, Object> map = new HashMap<>();
map.put("post", post);
User user = userService.findUserById(post.getUserId());
map.put("user", user); discussPosts.add(map);
}
}
// 把值传到这个模板里面
model.addAttribute("discussPosts", discussPosts);
return "/index";
}
}

  

然后就是处理对应的页面,我这里就不写了,基本的功能点在这了,运行之后可以查到表里面的前十条数据如下图所示:

现在就继续完善分页的功能,那么现在客户端要给服务端除了之前传递的数据还要传递现在是第几页这些其他的信息,服务端也需要根据传来的信息确定这个页码是否超过了能有的最大的页码(可以根据数据库中帖子的数量很分页每页显示多少条来计算得到),因为这个数据传递的很频繁所以我们单独写个组件来实现。

那么我们先实现Page来确定分页的一些条件

package com.nowcoder.community.entity;

/**
* 封装分页相关信息
*/
public class Page { // 页面传给服务端的数据
// 当前页码
private int current = 1; // 显示上限
private int limit = 10; // 服务端查到的
// 数据总数(用于计算总页数)
private int rows; // 查询路径(用于复用分页链接)
private String path; public int getCurrent() {
return current;
} public void setCurrent(int current) {
if (current >= 1) {
this.current = current;
}
} public int getLimit() {
return limit;
} public void setLimit(int limit) {
if (limit >= 1 && limit <= 100) {
this.limit = limit;
}
} public int getRows() {
return rows;
} public void setRows(int rows) {
if (rows >= 0) {
this.rows = rows;
}
} public String getPath() {
return path;
} public void setPath(String path) {
this.path = path;
} /**
* 获取当前页的起始行
*
* @return
*/
public int getOffset() {
// current * limit - limit
return (current - 1) * limit;
} /**
* 获取总页数
*
* @return
*/
public int getTotal() {
// rows / limit
if (rows % limit == 0) {
return rows / limit;
} else {
return rows / limit + 1;
}
} /**
* 获取起始页码
*/
public int getFrom() {
int from = current - 2;
return from < 1 ? 1 : from;
} /**
* 获取结束页码
*
* @return
*/
public int getTo() {
int to = current + 2;
return to > getTotal() ? getTotal() : to;
}
}

  

那么要改造HomeController来实现分页:

package com.nowcoder.community.controller;

import com.nowcoder.community.entity.DiscussPost;
import com.nowcoder.community.entity.Page;
import com.nowcoder.community.entity.User;
import com.nowcoder.community.service.DiscussPostService;
import com.nowcoder.community.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; @Controller
public class HomeController {
@Autowired
private DiscussPostService discussPostService; @Autowired
private UserService userService; @RequestMapping(path = "/index", method = RequestMethod.GET)
public String getIndexPage(Model model, Page page) {
// 方法调用之前,SpringMVC会自动实例化Model和Page,并将Page注入到Model中
// 所以,在thymeleaf中可以直接访问Page对象中的数据。
page.setRows(discussPostService.findDiscussPostRows(0));
page.setPath("/index");
List<DiscussPost> list = discussPostService.findDiscussPosts(0,page.getOffset(),page.getLimit());
// 把上面这个集合遍历一遍,但是它们的数据是不完整的,比方说我们查到的只是id不是userId
List<Map<String, Object>> discussPosts = new ArrayList<>();
if (list != null) {
for(DiscussPost post : list) {
Map<String, Object> map = new HashMap<>();
map.put("post", post);
User user = userService.findUserById(post.getUserId());
map.put("user", user); discussPosts.add(map);
}
}
// 把值传到这个模板里面
model.addAttribute("discussPosts", discussPosts);
return "/index";
} }

  

那么还要在页面上动态的配置好对应的链接

<nav class="mt-5" th:if="${page.rows>0}" th:fragment="pagination">
<ul class="pagination justify-content-center">
<li class="page-item">
<a class="page-link" th:href="@{${page.path}(current=1)}">首页</a>
</li>
<li th:class="|page-item ${page.current==1?'disabled':''}|">
<a class="page-link" th:href="@{${page.path}(current=${page.current-1})}">上一页</a></li>
<li th:class="|page-item ${i==page.current?'active':''}|" th:each="i:${#numbers.sequence(page.from,page.to)}">
<a class="page-link" href="#" th:text="${i}">1</a>
</li>
<li th:class="|page-item ${page.current==page.total?'disabled':''}|">
<a class="page-link" th:href="@{${page.path}(current=${page.current+1})}">下一页</a>
</li>
<li class="page-item">
<a class="page-link" th:href="@{${page.path}(current=${page.total})}">末页</a>
</li>
</ul>
</nav>

 

SpringBoot开发五-社区首页开发的更多相关文章

  1. Swift3.0服务端开发(五) 记事本的开发(iOS端+服务端)

    前边以及陆陆续续的介绍了使用Swift3.0开发的服务端应用程序的Perfect框架.本篇博客就做一个阶段性的总结,做一个完整的实例,其实这个实例在<Swift3.0服务端开发(一)>这篇 ...

  2. 【SpringBoot】Spring Boot,开发社区讨论交流网站首页。

    初识Spring Boot,开发社区讨论交流网站首页. 文章目录 初识Spring Boot,开发社区讨论交流网站首页. 1.项目简介 2. 搭建开发环境 JDK Apache Maven Intel ...

  3. asp.net mvc开发的社区产品相关开发文档分享

    分享一款基于asp.net mvc框架开发的社区产品--近乎.目前可以在官网免费下载,下载地址:http://www.jinhusns.com/Products/Download?type=whp 1 ...

  4. springboot 使用webflux响应式开发教程(二)

    本篇是对springboot 使用webflux响应式开发教程(一)的进一步学习. 分三个部分: 数据库操作webservicewebsocket 创建项目,artifactId = trading- ...

  5. java web 学习五(servlet开发1)

    一.Servlet简介 Servlet是sun公司提供的一门用于开发动态web资源的技术. Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向 ...

  6. 使用hubuild,mui开发微信app—首页(一)

    写在前面 本系列文章我将介绍一下从零开始利用hubuild,mui实现微信app的开发,该系列是个人学习记录,所以在每篇文章中,都是从怎么去实现开始讲解,然后再把实例中涉及知识点做一个概述. 创建一个 ...

  7. Vue 旅游网首页开发2 - 首页编写

    Vue 旅游网首页开发2 - 首页编写 项目结构 首页开发 效果图 项目开发组件化 将页面的各个部分划分成不同的组件,有助于项目的开发和维护. 项目代码初始化 项目结构修改 1.删除整个 compin ...

  8. Springboot Application 集成 OSGI 框架开发

    内容来源:https://www.ibm.com/developerworks/cn/java/j-springboot-application-integrated-osgi-framework-d ...

  9. go语言,golang学习笔记1 官网下载安装,中文社区,开发工具LiteIDE

    go语言,golang学习笔记1 官网下载安装,中文社区,开发工具LiteIDE Go语言是谷歌2009发布的专门针对多处理器系统应用程序的编程进行了优化,使用Go编译的程序可以媲美C或C++代码的速 ...

随机推荐

  1. SpringCloud:eureka的'eurekaAutoServiceRegistration'报错解决方法

    报错信息如下: org.springframework.beans.factory.BeanCreationNotAllowedException: Error creating bean with ...

  2. php+redis+lua实现分布式锁(转载)

    以下是我在工作中用到的类,redis加锁两种方式,解锁为了保证原子性所以只用lua+redis的方式 缺陷:虽然死锁问题解决了,但业务执行时间超过锁有效期还是存在多客户端加锁问题.不过,这个类已经满足 ...

  3. XCTF crypto 不仅仅是Mors

    一. 题目暗示摩斯码,打开文件发现里面有反斜杠的.不管它直接拿来解密 二. 发现一句话是句英文,还有其他的加密方式,后面那串只有两种字符A和B,手抓饼A套餐,b套餐 培根加密,拿来解密后,得到flag

  4. buu 刮开有奖

    一.查壳, 二.拖入ida,分析 直接搜字符串完全没头绪,在看了大佬的wp才找到了,关键函数. 明显那个String就是我们要求的flag,要开始分析程序. 字符串长度为8,同时这个函数对字符串进行了 ...

  5. 64. Minimum Path Sum 动态规划

    description: Given a m x n grid filled with non-negative numbers, find a path from top left to botto ...

  6. QT从入门到入土(二)——对象模型(对象树)和窗口坐标体系

    摘要 我们使用的标准 C++,其设计的对象模型虽然已经提供了非常高效的 RTTI 支持,但是在某些方面还是不够灵活.比如在 GUI 编程方面,既需要高效的运行效率也需要强大的灵活性,诸如删除某窗口时可 ...

  7. python 图中找目标并截图

    import numpy as npdef sjjt(xha,sjh,beitu,jl,xx,yy): #检查目标,并将目标指定范围内截图 pull_screenshot(xha,sjh,xx) #p ...

  8. java使用IO读写文件

    https://www.cnblogs.com/qiaoyeye/p/5383723.html java读写文件的IO流分两大类,字节流和字符流,基类分别是字符:Reader和Writer:字节:In ...

  9. Docker与k8s的恩怨情仇(五)——Kubernetes的创新

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 上节中我们提到了社区生态的发展使得Kubernetes得到了良性的发展和传播.比起相对封闭的Docker社区 ...

  10. Quick BI的复杂系统为例:那些年,我们一起做过的性能优化

    背景 一直以来,性能都是技术层面不可避开的话题,尤其在中大型复杂项目中.犹如汽车整车性能,追求极速的同时,还要保障舒适性和实用性,而在汽车制造的每个环节.零件整合情况.发动机调校等等,都会最终影响用户 ...