牛客项目

项目-2

1. 搭建开发环境

1.1 Apache Maven

• 可以帮助我们构建项目、管理项目中的jar包

• Maven仓库:存放构件的位置

- 本地仓库:默认是 ~/.m2/repository

- 远程仓库:中央仓库、镜像仓库、私服仓库

• 示例:安装、配置、常用命令

http://maven.apache.org

项目构建的总体思路是:先编写数据库(SQL,实体类),dao层(mapper接口,mapper.xml),service层

数据库创建的细节在项目总结-1

2. 编写对应的实体类

package com.think.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;

//实体类:讨论帖
@Data
@AllArgsConstructor
@NoArgsConstructor
public class DiscussPost {
    private int id;
    private String userId;
    private String title;
    private String context;
    private int type;
    private int status;
    private Date createTime;
    private int commentCount;
    private Double score;
}
public class User {
    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 String headerUrl;
    private Date createTime;
}

3.编写mapper接口

@Mapper
@Repository
public interface DiscussPostMapper {

    /**
     * 查询用户的帖子:支持分页查询
     * @param userId 当userId = 0,查询所有人发布的帖子;当userId != 0,根据userId查询帖子
     * @param offset  每页起始行的行号
     * @param limit 每页最多显示多少的帖子
     * @return 返回值即用户发布的帖子
     */
    List<DiscussPost> selectDiscussPosts(int userId, int offset, int limit);

    /**
     * 为了实现分页查询,获取全部帖子的数量
     * @param userId 当userId = 0,查询所有人发布的帖子;当userId != 0,根据userId查询帖子
     * @return 全部帖子的数量
     */
    //@Param 注解用于给参数起别名
    //如果只有一个参数,并且会在里使用[即动态SQL],则必须添加别名
    int selectDiscussPostRows(@Param("userId") int userId);

}
package com.think.dao;

import com.think.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

@Mapper
@Repository
public interface UserMapper {

    User selectById(int id);

    User selectByName(String username);

    User selectByEmail(String email);

    int insertUser(User user);

    int updateStatus(int id, int status);

    int updateHeader(int id, String headerUrl);

    int updatePassword(int id, String password);

}

4.discusspost-mapper.xml




<mapper namespace="com.think.dao.DiscussPostMapper">

    
    <sql id="selectFields">
        id,user_id,title,context,type,status,create_time,comment_count,score
    sql>

    

    
    <select id="selectDiscussPosts" resultType="DiscussPost">
        select <include refid="selectFields"/>
        from discuss_post
        where status != 2  /*status为帖子的状态,当status=2时,表示该帖已经被拉黑*/
        <if test="userId != 0"> /*动态SQL,当userId != 0需要根据userId查询帖子;userId=0时,查询全部的帖子*/
            and user_id = #{userId}
        if>
        order by type desc,create_time desc /*type为帖子类型,type=0表示置顶。因此首先根据type降序排序,再根据create_time排序*/
        limit #{offset},#{limit} /*利用SQL的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>



<mapper namespace="com.nowcoder.community.dao.UserMapper">

    <sql id="insertFields">
        username, password, salt, email, type, status, activation_code, header_url, create_time
    sql>

    <sql id="selectFields">
        id, username, password, salt, email, type, status, activation_code, header_url, create_time
    sql>

    <select id="selectById" resultType="User">
        select <include refid="selectFields">include>
        from user
        where id = #{id}
    select>

    <select id="selectByName" resultType="User">
        select <include refid="selectFields">include>
        from user
        where username = #{username}
    select>

    <select id="selectByEmail" resultType="User">
        select <include refid="selectFields">include>
        from user
        where email = #{email}
    select>

    <insert id="insertUser" parameterType="User" keyProperty="id">
        insert into user (<include refid="insertFields">include>)
        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>

5. service

package com.think.service;

import com.think.dao.DiscussPostMapper;
import com.think.entity.DiscussPost;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service //注入spring容器
public class DiscussPostService {
    //service需要调用dao,因此将DiscussPostMapper导入
    @Autowired(required = false)
    private DiscussPostMapper discussPostMapper;

    //service层的方法
    //当业务比较简单时,service与mapper类似,只需要调用dao的方法
    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);
    }
}

package com.think.service;

import com.think.dao.UserMapper;
import com.think.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    //根据userId查询用户
    public User fingUserById(int id){
        return userMapper.selectById(id);
    }
}

6.拷贝资源

Index.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>
<body>	
	<div class="nk-container">
		
		<header class="bg-dark sticky-top" th:fragment="header">
			<div class="container">
				
				<nav class="navbar navbar-expand-lg navbar-dark">
					
					<a class="navbar-brand" href="#">a>
					<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
						<span class="navbar-toggler-icon">span>
					button>
					
					<div class="collapse navbar-collapse" id="navbarSupportedContent">
						<ul class="navbar-nav mr-auto">
							<li class="nav-item ml-3 btn-group-vertical">
								<a class="nav-link" th:href="@{/index}">首页a>
							li>
							<li class="nav-item ml-3 btn-group-vertical">
								<a class="nav-link position-relative" href="site/letter.html">消息<span class="badge badge-danger">12span>a>
							li>
							<li class="nav-item ml-3 btn-group-vertical">
								<a class="nav-link" th:href="@{/register}">注册a>
							li>
							<li class="nav-item ml-3 btn-group-vertical">
								<a class="nav-link" th:href="@{/login}">登录a>
							li>
							<li class="nav-item ml-3 btn-group-vertical dropdown">
								<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
									<img src="http://images.nowcoder.com/head/1t.png" class="rounded-circle" style="width:30px;"/>
								a>
								<div class="dropdown-menu" aria-labelledby="navbarDropdown">
									<a class="dropdown-item text-center" href="site/profile.html">个人主页a>
									<a class="dropdown-item text-center" href="site/setting.html">账号设置a>
									<a class="dropdown-item text-center" href="site/login.html">退出登录a>
									<div class="dropdown-divider">div>
									<span class="dropdown-item text-center text-secondary">nowcoderspan>
								div>
							li>
						ul>
						
						<form class="form-inline my-2 my-lg-0" action="site/search.html">
							<input class="form-control mr-sm-2" type="search" aria-label="Search" />
							<button class="btn btn-outline-light my-2 my-sm-0" type="submit">搜索button>
						form>
					div>
				nav>
			div>
		header>

		
		<div class="main">
			<div class="container">
				<div class="position-relative">
					
					<ul class="nav nav-tabs mb-3">
						<li class="nav-item">
							<a class="nav-link active" href="#">最新a>
						li>
						<li class="nav-item">
							<a class="nav-link" href="#">最热a>
						li>
					ul>
					<button type="button" class="btn btn-primary btn-sm position-absolute rt-0" data-toggle="modal" data-target="#publishModal">我要发布button>
				div>
				
				<div class="modal fade" id="publishModal" tabindex="-1" role="dialog" aria-labelledby="publishModalLabel" aria-hidden="true">
					<div class="modal-dialog modal-lg" role="document">
						<div class="modal-content">
							<div class="modal-header">
								<h5 class="modal-title" id="publishModalLabel">新帖发布h5>
								<button type="button" class="close" data-dismiss="modal" aria-label="Close">
									<span aria-hidden="true">×span>
								button>
							div>
							<div class="modal-body">
								<form>
									<div class="form-group">
										<label for="recipient-name" class="col-form-label">标题:label>
										<input type="text" class="form-control" id="recipient-name">
									div>
									<div class="form-group">
										<label for="message-text" class="col-form-label">正文:label>
										<textarea class="form-control" id="message-text" rows="15">textarea>
									div>
								form>
							div>
							<div class="modal-footer">
								<button type="button" class="btn btn-secondary" data-dismiss="modal">取消button>
								<button type="button" class="btn btn-primary" id="publishBtn">发布button>
							div>
						div>
					div>
				div>
				
				<div class="modal fade" id="hintModal" tabindex="-1" role="dialog" aria-labelledby="hintModalLabel" aria-hidden="true">
					<div class="modal-dialog modal-lg" role="document">
						<div class="modal-content">
							<div class="modal-header">
								<h5 class="modal-title" id="hintModalLabel">提示h5>
							div>
							<div class="modal-body" id="hintBody">
								发布完毕!
							div>
						div>
					div>
				div>
				
				
				<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:18b>
								<ul class="d-inline float-right">
									<li class="d-inline ml-2">赞 11li>
									<li class="d-inline ml-2">|li>
									<li class="d-inline ml-2">回帖 7li>
								ul>
							div>
						div>						
					li>
				ul>
				

			div>
		div>

		
		<footer class="bg-dark">
			<div class="container">
				<div class="row">
					
					<div class="col-4 qrcode">
						<img src="https://uploadfiles.nowcoder.com/app/app_download.png" class="img-thumbnail" style="width:136px;" />
					div>
					
					<div class="col-8 detail-info">
						<div class="row">
							<div class="col">
								<ul class="nav">
									<li class="nav-item">
										<a class="nav-link text-light" href="#">关于我们a>
									li>
									<li class="nav-item">
										<a class="nav-link text-light" href="#">加入我们a>
									li>
									<li class="nav-item">
										<a class="nav-link text-light" href="#">意见反馈a>
									li>
									<li class="nav-item">
										<a class="nav-link text-light" href="#">企业服务a>
									li>
									<li class="nav-item">
										<a class="nav-link text-light" href="#">联系我们a>
									li>
									<li class="nav-item">
										<a class="nav-link text-light" href="#">免责声明a>
									li>
									<li class="nav-item">
										<a class="nav-link text-light" href="#">友情链接a>
									li>
								ul>
							div>
						div>
						<div class="row">
							<div class="col">
								<ul class="nav btn-group-vertical company-info">
									<li class="nav-item text-white-50">
										公司地址:北京市朝阳区大屯路东金泉时代3-2708北京牛客科技有限公司
									li>
									<li class="nav-item text-white-50">
										联系方式:010-60728802(电话)    [email protected]
									li>
									<li class="nav-item text-white-50">
										牛客科技©2018 All rights reserved
									li>
									<li class="nav-item text-white-50">
										京ICP备14055008号-4     
										<img src="http://static.nowcoder.com/company/images/res/ghs.png" style="width:18px;" />
										京公网安备 11010502036488号
									li>
								ul>
							div>
						div>
					div>
				div>
			div>
		footer>
	div>

	<script src="https://code.jquery.com/jquery-3.3.1.min.js" crossorigin="anonymous">script>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" crossorigin="anonymous">script>
	<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" crossorigin="anonymous">script>
	<script th:src="@{/js/global.js}">script>
	<script th:src="@{js/index.js}">script>
body>
html>

7.Controller

编写首页controller,返回首页

package com.guo.controller;


import com.guo.entity.DiscussPost;
import com.guo.entity.User;
import com.guo.service.DiscussPostService;
import com.guo.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) {

        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";
    }

}

此时访问http://localhost:8080/community/index

首页已经有雏形

你可能感兴趣的:(项目管理)