仿牛客网项目(二)

1、社区首页

1.1、功能分析

社区首页显示前10个帖子、支持内容分页、显示登录注册按钮。

1.2、功能实现

开发思路按照数据库-Dao-Service-Controller思路,首先新建数据库community,新建用户表user和帖子表discusspost;
前端页面展示采用thymeleaf模版引擎,实现将逻辑注入模板文件。具体sql文件和前端文件详见文章底部:源代码;
在community目录下创建entity包和dao包,entity包下编写User类和DiscussPost类,Page类用于控制页面分页显示。

@Data
public class User {

    /**用户ID*/
    private int id;
    /**用户名称*/
    private String username;
    /**用户密码*/
    private String password;
    /**密码加盐*/
    private String salt;
    /**用户邮箱*/
    private String email;
    /**用户类型*/
    private int type;
    /**用户状态*/
    private int status;
    /**激活码*/
    private String activationCode;
    /**账号创建时间*/
    private Date createTime;
    /**用户头像路径ß*/
    private String headerUrl;
    
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", salt='" + salt + '\'' +
                ", email='" + email + '\'' +
                ", type=" + type +
                ", status=" + status +
                ", activationCode='" + activationCode + '\'' +
                ", createTime=" + createTime +
                ", headerUrl='" + headerUrl + '\'' +
                '}';
    }
}
@Data
public class DiscussPost {

    /**评论ID*/
    private int id;
    /**用户id*/
    private int userId;
    /**评论ID*/
    private String title;
    /**评论内容*/
    private String content;
    /**评论类型*/
    private int type;
    /**评论状态*/
    private int status;
    /**评论创建时间*/
    private Date createTime;
    /**评论分数*/
    private double score;
    /**评论数*/
    private int commentCount;

    @Override
    public String toString() {
        return "DiscussPost{" +
                "id=" + id +
                ", userId=" + userId +
                ", title='" + title + '\'' +
                ", content='" + content + '\'' +
                ", type=" + type +
                ", status=" + status +
                ", createTime=" + createTime +
                ", score=" + score +
                ", commentCount=" + commentCount +
                '}';
    }
}
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() {
        // current*limit - limit
        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;
    }
}

dao包下分别创建UseMapper接口和DiscussPostMapper接口文件

@Mapper
public interface UserMapper{
    /**根据id查询用户*/
    User selectById(int id);
    /**根据用户名查询用户*/
    User selectByName(String username);
    /**根据邮箱查询用户*/
    User selectByEmail(String email);
    /**插入新用户*/
    int insertUser(User user);
    /**根据id修改状态*/
    int updateStatus(int id, int status);
    /**更新对应id的头像*/
    int updateHeader(int id, String headerUrl);
    /**更新用户密码*/
    int updatePassword(int id, String password);
}
@Mapper
public interface DiscussPostMapper{

    /**
     * 根据用户id查询评论集合;或者查询所有评论集合
     * @param userId 用户id
     * @param offset 起始行行号
     * @param limit 每页最多显示数量
     * @return
     */
    List<DiscussPost> selectDiscussPosts(int userId,int offset, int limit);
    /**
     * 查询总的评论数; @Param注释的作用给参数起别名; 当需要动态的拼接参数,并且参数只有一个的时候,必须有@Param注释
     * 只有一个参数,并且在<if>里使用,则必须加别名
     * @param userId
     * @return
     */
    int selectDiscussPostRows(@Param("userId") int userId);
}

在resources包下新建mapper包,在mapper包下新建UserMapper.xml文件和DiscussPostMapper.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.ahtoh.community.dao.UserMapper">

   <select id="selectById" resultType="com.ahtoh.community.entity.User">
       select *
       from USER
       where id = #{id};
   </select>

    <select id="selectByName" resultType="com.ahtoh.community.entity.User">
       select *
       from USER
       where username = #{username};
   </select>

    <select id="selectByEmail" resultType="com.ahtoh.community.entity.User">
       select *
       from USER
       where email = #{email};
   </select>

    <insert id="insertUser" parameterType="com.ahtoh.community.entity.User" keyProperty="id">
        insert into user(username, password, salt, email, type, status, activation_code, header_url, create_time)
        values(#{username}, #{password}, #{salt}, #{email}, #{type}, #{status}, #{activationCode}, #{headerUrl}, #{createTime})
    </insert>

    <update id = "updateStatus">
        update user set status = #{status} where id = #{id}
    </update>

    <update id = "updateHeader">
        update user set header_url = #{headerUrl} where id = #{id}
    </update>

    <update id = "updatePassword">
        update user set password = #{password} where id = #{id}
    </update>
</mapper>
<?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.ahtoh.community.dao.DiscussPostMapper">

    <sql id="selectFields">
        id,user_id,title,content,type,status,create_time,comment_count,score
    </sql>
    <select id="selectDiscussPosts" resultType="com.ahtoh.community.entity.DiscussPost">
        select * 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>

在community包下创建service包controller包,service包下新建UserService和DiscussPostService文件。

@Service
public class UserService{
    @Autowired
    private UserMapper userMapper;
    /**
     * 根据用户id查询用户
     * @param userId
     * @return
     */
    public User findUserById(int userId){
        return userMapper.selectById(userId);
    }
    /**
     * 根据用户名称查询用户
     * @param name
     * @return
     */
    public User findUserByName(String name){
        return userMapper.selectByName(name);
    }
}
@Service
public class DiscussPostService{

    @Autowired
    private DiscussPostMapper discussPostMapper;
    /**
     * 查询对应用户的所有评论
     * @param userId 用户id
     * @param offset 起始行数
     * @param limit 最大显示数
     * @return
     */
    public List<DiscussPost> findDiscussPosts(int userId, int offset, int limit){
        return discussPostMapper.selectDiscussPosts(userId,offset,limit);
    }
    /**
     * 查询对应用户评论数
     * @param userId 用户id
     * @return
     */
    public int findDiscussPostRows(int userId){
        return discussPostMapper.selectDiscussPostRows(userId);
    }
}

controller是负责业务调度的,所以在这一层应写一些业务的调度代码,是连接前端和后端的纽带。UserController 在本章需要实现的功能是接受浏览器发送过来的请求,然后去响应 thymeleaf 的模板页面 index.html。首页页面controller创建HomeController文件

@Controller
public class HomeController{
    @Autowired
    private UserService userService;
    @Autowired
    private DiscussPostService discussPostService;
    /**
     * 获取用户名和对应的评论
     * @param model 前端返回模型
     * @return
     */
    @GetMapping("/index")
    public String getIndexPages(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());
        /**创建用于存储用户对象和对应评论map*/
        List<Map<String, Object>> discussPosts = new ArrayList<>();
        /**判断查询是否为空*/
        if(list != null) {
            /**遍历查询到的评论对象*/
            for (DiscussPost post : list) {
                Map<String, Object> map = new HashMap<>();
                /**根据用户id查询用户对象*/
                User user = userService.findUserById(post.getUserId());
                map.put("post",post);
                map.put("user",user);
                /**封存用户和对应的评论*/
                discussPosts.add(map);
            }
        }
        /**返回前端对象*/
        model.addAttribute("discussPosts",discussPosts);
        return "/index";
    }
}

1.3、功能测试

启动 CommunityApplication类,在浏览器中输入地址http://localhost:8080/community/index

此时显示的是前端的首页:
在这里插入图片描述
注意:直接导入前端文件,可能会报属性不存在或者为空的错误,原因是后端没有传对应的属性,需要先注释掉前端对应报错的属性,即可正常测试。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值