栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring Boot+MyBatis+MySQL+Spring MVC之论坛首页开发

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring Boot+MyBatis+MySQL+Spring MVC之论坛首页开发

1.项目概述

开发仿牛客网论坛首页。

2. Entity

① 表user包含字段:username, password, salt, email, type, status, activation_code, header_url, create_time
② 表discuss_post包含字段:
id, user_id, title, content, type, status, create_time, comment_count, score

实体类:DiscussPost.java

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 +
                '}';
    }
}

实体类:Page.java
该类用于封装分页相关的信息。

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;
    }
	
	// 当前页页码必须不小于1
    public void setCurrent(int current) {
        if (current >= 1) {
            this.current = current;
        }
    }

    public int getLimit() {
        return limit;
    }
	
	// 显示数据的下限为1,上限为100
    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() {
        // current * limit - limit
        return (current - 1) * limit;
    }

    
    public int getTotal() {
        // rows / limit [+1]
        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;
    }

}
3. DAO

接口:DiscussPostMapper.java

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 {

    List selectDiscussPosts(int userId, int offset, int limit);

    // @Param注解用于给参数取别名
    // 如果只有一个参数,并且在里使用,则必须加别名
    int selectDiscussPostRows(@Param("userId") int userId);

}

@Param注解用于给参数取别名,如果只有一个参数,并且在里使用,则必须加别名。

4. XML

discusspost-mapper.xml实现SQL与实体类DiscussPost的映射。





    
        id, user_id, title, content, type, status, create_time, comment_count, score
    

    
        select count(id)
        from discuss_post
        where status != 2
        
            and user_id = #{userId}
        
    


其中,第一个 select 语句相当于:

select id, user_id, title, content, type, status, create_time, comment_count, score 
from discuss_post 
where status != 2 
order by type desc, create_time desc 
limit ?, ?

第二个 select 语句相当于:

select count(id) 
from discuss_post 
where status != 2 
5. Service

业务组件:DiscussPortService.java

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 findDiscussPosts(int userId, int offset, int limit) {
        return discussPostMapper.selectDiscussPosts(userId, offset, limit);
    }

    public int findDiscussPostRows(int userId) {
        return discussPostMapper.selectDiscussPostRows(userId);
    }
}
6. Controller

控制组件:HomeController.java
注入Service组件:DiscussPostService、UserService
方法getIndexPage()中的参数 model 和 page均由前端控制器DispatcherServlet 自动创建。

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.GetMapping;

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;

    @GetMapping("/index")
    public String getIndexPage(Model model, Page page) {
        // 方法调用前,SpringMVC会自动实例化Model和Page,并将Page注入Model
        // 所以,在thymeleaf中可以直接访问Page对象中的数据
        page.setRows(discussPostService.findDiscussPostRows(0));
        page.setPath("/index");

        List list = discussPostService.findDiscussPosts(0,page.getOffset(),page.getLimit());
        List> discussPosts = new ArrayList<>();
        if (list != null) {
            for (DiscussPost post : list) {
                Map 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";
    }
}

① list 是封装了帖子 DiscussPost (包含多个字段的实体类)的List
② discussPosts 是封装了 map 的 List
③ map 中封装了 帖子 post 和对应的 用户实体类对象 user(通过 post 根据user_id 查询得到)

7. 前端网页

论坛首页index.html
① 帖子列表部分:



  • th:each="map:${discussPosts}"使用变量 map 遍历封装了帖子和对应用户实体类对象的集合构成的列表 discussPosts。
  • th:src="${map.user.headerUrl}"用于动态替换 map 中的 user 的用户头像存储链接。
  • th:utext="${map.post.title}"用于动态替换 map 中的 post 的帖子标题。
  • th:if="${map.post.type==1}"用于条件判断,动态替换帖子类型为 1,即置顶的帖子。
    -th:if="${map.post.status==1}"用于条件判断,动态替换帖子状态为 1,即精华帖。
  • th:utext="${map.user.username}"用于动态替换 map 中的用户的用户名。
  • th:text="${#dates.format(map.post.createTime,'yyyy-MM-dd HH:mm:ss')}"用于按照指定格式动态生成日期。

② 分页部分:


			
  • th:if="${page.rows>0}用于条件判断该页数据条数是否为正数。
  • th:href="@{${page.path}(current=1)}"首页
  • th:
    th:href="@{${page.path}(current=${page.current-1})}"上一页
  • th:
    th:each="i:${#numbers.sequence(page.from,page.to)}"
    th:href="@{${page.path}(current=${i})}"
    th:text="${i}"页码1
  • th:
    th:href="@{${page.path}(current=${page.current+1})}"下一页
  • th:href="@{${page.path}(current=${page.total})}"末页
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1020358.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号