①在开发数据访问层DAO之前,先在eneity包下写一个实体类DisussPost,用来封装表里的数据。
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;
②在DAO包下编写DiscussPostMapper接口,提供两个方法
@Mapper
public interface DicussPostMapper {
List<DiscussPost> selectDiscussPosts(int userId, int offset, int limit);
//@Param注解用于给参数取别名
//如果只有一个参数,并且在<if>里使用,则必须加别名
int selectDiscussPostRows(@Param("userId") int userId);
}
③在mapper文件夹下新建一个DiscussPostMapper的配置文件discusspost-mapper.xml,建立DiscussPostMapper与数据库之间的连接
<?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.DicussPostMapper">
<sql id="selectField">
id,user_id,title,content,type,status,create_time,comment_count,score
</sql>
<select id="selectDiscussPosts" resultType="DiscussPost">
select <include refid="selectField"></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>
配置好之后就可以在测试类中进行测试了
@Test
public void testSelectPosts(){
List<DiscussPost> list=discussPostMapper.selectDiscussPosts(149,0,10);
for(DiscussPost post:list){
System.out.println(post);
}
int rows=discussPostMapper.selectDiscussPostRows(149);
System.out.println(rows);
}
到这里,数据访问层(DAO)的开发工作就完成了,接下来是业务层(service)的开发
③在service目录下新建一个DiscussPostService类,将DAO包下对应的Mapper注入,并定义业务层中用到的方法
@Service
public class DiscussPostService {
@Autowired(required = false)
private DicussPostMapper dicussPostMapper;
public List<DiscussPost> findDiscussPosts(int userId, int offset, int limit ){
return dicussPostMapper.selectDiscussPosts(userId, offset, limit);
}
public int findDiscussPostRows(int userId){
return dicussPostMapper.selectDiscussPostRows(userId);
}
}
findDiscussPosts()方法中返回的是帖子(DiscussPost)当中虽然包含了用户信息(userId),但我们希望返回的内容当中包含完整的用户信息(User类的对象),在service包下新建一个UserService类,提供根据userId获取User对象的服务
@Service
public class UserService {
@Autowired(required = false)
private UserMapper userMapper;
public User findUserById(int id){
return userMapper.selectById(id);
}
}
视图层(controller)需要用到一些页面,以及页面所依赖的样式文件,将准备好的页面及静态文件拷贝进来
④在controller包下新建一个HomeController类,注入相关的service,并增加一个处理请求的方法(注意声明方法的访问路径)
@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());
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";
}
}
⑤接下来配置controller中用到的网页模板**.html**文件,部分代码如下
<!doctype html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="icon" href="https://static.nowcoder.com/images/logo_87_87.png"/>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" crossorigin="anonymous">
<link rel="stylesheet" th:href="@{/css/global.css}" />
<title>牛客网-首页</title>
</head>
配置好之后的效果图如下
⑥在开发分页功能,在entity包下新建一个Page类,封装相关的功能属性
/**
* 封装分页相关的信息
*/
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;
}
/**
* 获取当前页的起始行
*/
public int getOffset(){
return (current-1)*limit;
}
/**
* 获取总页数
*/
public int getTotal(){
if(rows % limit == 0){
return rows/limit;
}else{
return rows/limit+1;
}
}
/**
* 获取起始页码
*/
public int getFrom(){
int from=current-2;
return from<1 ? 1 : from;
}
/**
* 获取结束页码
*/
public int getTo(){
int to=current+2;
int total = getTotal();
return to>total ? total : to;
}
}
⑦最后回到HomeController中改造相关方法,使其能够支持分页功能,回到**.html**修改分页逻辑
版权声明:本文为zhangdaliya原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。