3.开发社区首页
1.建数据表
MySQL字符集和排序规则详解2.写Dao
(1)实体类DiscussPost
@Data : 注解的目标是类上 提供类的get、set、equals、hashCode、canEqual、toString方法 加入依赖包lombok才可导入
(2)mapper(声明sql方法)
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; @Mapper public interface DiscussPostMapper { //参数userId:我的帖子 分页:offset起始行号 limit查多少 List<DiscussPost> selectDiacussPosts(int userId,int offset,int limit); //@Param注解用于给参数取别名 //如果只有一个参数,并且在<if>中使用,必须加别名 int selectDiscussPostRows(@Param("userId") int userId);//查到的行数 }
(3)xml(写sql语句)
<?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"> #test属性指定了条件表达式,成立才添加到sql语句 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>
(4)可以通过MySQL数据查询或者test类对sql进行测试
@SpringBootTest @ContextConfiguration(classes=CommunityApplication.class) public class MapperTest { @Autowired private DiscussPostMapper discussPostMapper; @Test public void testSelectPosts(){ List<DiscussPost> list=discussPostMapper.selectDiacussPosts(0,0,10); for(DiscussPost post:list){ System.out.println(post); } int rows=discussPostMapper.selectDiscussPostRows(0); System.out.println(rows); } }
3.写Service
@Service public class DiscussPostService { @Autowired private DiscussPostMapper discussPostMapper; public List<DiscussPost> findDiscussPosts(int userId,int offset,int limit){ return discussPostMapper.selectDiscussPosts(userId,offset,limit); } private int findDiscussPostRows(int userId){ return discussPostMapper.selectDiscussPostRows(userId); } }
4.准备页面
<!-- 帖子列表 --> <ul class="list-unstyled">
<li class="media pb-3 pt-3 mb-3 border-bottom" th:each="map:${discussPosts}"> #循环布局
<a href="site/profile.html">
<img th:src="${map.user.headerUrl}" class="mr-4 rounded-circle" alt="用户头像" style="width:50px;height:50px;">
</a>
<div class="media-body">
<h6 class="mt-0 mb-3">
<a href="#" th:utext="${map.post.title}">备战春招,面试刷题跟他复习,一个月全搞定!</a>
<span class="badge badge-secondary bg-primary" th:if="${map.post.type==1}">置顶</span>
<span class="badge badge-secondary bg-danger" th:if="${map.post.status==1}">精华</span>
</h6>
<div class="text-muted font-size-12">
<u class="mr-3" th:utext="${map.user.username}">寒江雪</u> 发布于 <b th:text="${#dates.format(map.post.createTime,'yyyy-MM-dd HH:mm:ss')}">2019-04-15 15:32:18</b>
<ul class="d-inline float-right">
<li class="d-inline ml-2">赞 11</li>
<li class="d-inline ml-2">|</li>
<li class="d-inline ml-2">回帖 7</li>
</ul>
</div>
</div>
</li>
</ul>
5.写Controller
@RequestMapping(path = "/index",method = RequestMethod.GET) public String getIndexPage(Model model){//获取首页 List<DiscussPost> list=discussPostService.findDiscussPosts(0,0,10); //用于封装帖子列表和相应用户信息 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"; }
6.分页
@Getter public class Page { private int current=1;//当前页码 private int limit=10;//显示上限 private int rows;//数据总数(用于计算总页数) private String path;//查询路径(用于复用分页链接) public void setCurrent(int current) { if (current >= 1) { this.current = current; } } public void setLimit(int limit) { if (limit >= 1 && limit <= 100) { this.limit = limit; } } public void setRows(int rows) { if (rows >= 0) { this.rows = rows; } } public void setPath(String path) { this.path = path; } //获取当前页的起始行 public int getOffset(){ return (current-1)*limit; } //获取总页数:总行数除以每一页行数 public int getTotal(){ return rows%limit==0?rows/limit:rows/limit+1; } //页面显示五个页码:current-2...current...current+2 //获取起始页码 public int getFrom(){ return current-2<1?1:current-2; } //获取结束页码 public int getTo(){ int total=getTotal(); return current+2>total?total:current+2; } } //controller里加两行即可 public String getIndexPage(Model model, Page page){//获取首页 // 方法调用前,SpringMVC会自动实例化Model和Page,并将Page注入Model. // 所以,在thymeleaf中可以直接访问Page对象中的数据. page.setRows(discussPostService.findDiscussPostRows(0));//获取总行数,以求总页数等 page.setPath("/index");//不同页复用链接 }
有一些分页的注意点:
<!-- 分页 -->
<nav class="mt-5" th:if="${page.rows>0}"> <!--如果rows为0,则没查到结果,无需分页--> <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> <!--'active' 高亮当前页码--> <li th:class="|page-item ${i==page.current?'active':''}|" th:each="i:${#numbers.sequence(page.from,page.to)}"> <a class="page-link" th:href="@{${page.path}(current=${i})}" 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>
<!--点击页码,这就是要跳转的链接--> th:href="@{${page.path}(current=${i})}"
---> 访问http://localhost:8080/community/index?current=2
--->后端public String getIndexPage(Model model, Page page){}