牛客项目

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

项目-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 注解用于给参数起别名
    //如果只有一个参数,并且会在<if>里使用[即动态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
<?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">
<!--namespace为该配置文件对应的mapper接口的全限定名-->
<mapper namespace="com.think.dao.DiscussPostMapper">

    <!--将discuss_post表中的属性单独抽离,便于代码的复用-->
    <sql id="selectFields">
        id,user_id,title,context,type,status,create_time,comment_count,score
    </sql>

    <!--编写DiscussPostMapper对应的SQL语句-->

    <!--id就是方法名称;resultType是返回值类型-->
    <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>

<?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.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

<!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>
<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">
					<!-- logo -->
					<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">12</span></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">nowcoder</span>
								</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">&times;</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: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>
				<!-- 分页 -->

			</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(电话)&nbsp;&nbsp;&nbsp;&nbsp;admin@nowcoder.com
									</li>
									<li class="nav-item text-white-50">
										牛客科技©2018 All rights reserved
									</li>
									<li class="nav-item text-white-50">
										京ICP备14055008号-4 &nbsp;&nbsp;&nbsp;&nbsp;
										<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

首页已经有雏形

Java网社区项目——知识点&面试题 有很多模块组成,利用这些模块可以方便开发工作。这些模块是:核心容器(spring core)/数据访问和集成(Spring JDBC)/Web(Spring Web/MVC)/AOP(Spring Aop)/消息模块/测试模块(Spring Test)等。data access object,存放数据库访问对象。包括Spring + Spring MVC(和Spring天生集成) + MyBatis(帮你和数据库打交道的框架,简单的设置,你就可以像Java一样,操作数据库了) 阅读详情

相关推荐

论坛项目

1.只要是一个实体类型(javabean)都会自动封装到model2.把验证码放在session中,因为在另一个请求中需要用到,并且若在浏览器中存放有安全问题。3.为了实现用户可以在多个请求间,服务器可以记住浏览器的用户信息,创建LoginTicket表,用户登录后,服务器生成一个ticket凭据,同时保存用户的user_id,通过user_id可以进一步查询到用户的详细信息。服务器把ticket凭据用cookie返回给浏览器,浏览器下次请求时就会带上ticket。

weixin_47171905的博客 1207

WebServer项目配置文件

webServer,自己开发的服务器配置文件,用于一些基本的配置

论坛项目:置顶、加精、删除

增加了取消置顶,取消加精,其它部分和老师视频讲的一样,下面是需要修改的部分。 discuss-detail.html 省略… <div class="float-right"> <input type="hidden" id="postId" th:value="${post.id}"> <button type="button" class="btn btn-danger btn-sm" id="topBtn" sec:authorize="hasAnyAuthor

布布汪的博客 771

Vue.js安装

一独立安装 我们可以在 Vue.js 的官网上直接下载 vue.min.js 并用 <script> 标签引入。 Vue.js下载位置:https://vuejs.org/js/vue.min.js 二使用CDN方法 1 CDN介绍 CDN的全称是Content Delivery Network,即内容分发网络。CDN是构建在现有网络基础之上的智能虚拟网络,依靠部署在各地...

实践求真知 538

项目——项目开发(三):开发登录模块

文章目录1. 发送邮件1.1 邮箱设置1.2 Spring Email 1. 发送邮件 1.1 邮箱设置 打开邮箱POP3/SMTP服务 1.2 Spring Email 导入spring mail相关依赖jar包 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId&gt

平什么阿的博客 5478

论坛项目总结

huahuahuaz的博客 1万+

项目——项目开发(一):搭建环境

文章目录1. 配置环境2. 自动下包3. 项目建立4. Spring 1. 配置环境 maven idea 2. 自动下包 3. 项目建立 4. Spring package com.psynowcoder.community.community; import org.junit.jupiter.api.Test; import org.springframework.beans.BeansException; import org.springframework.boot.test.context.S

平什么阿的博客 1738

高级项目课之讨论区——项目总结

#讨论区项目总结 本项目是基于高级课的关于讨论区的项目项目的技术栈以及框架都是比较新的,是一个基于SpringBoot的Java Web项目,框架使用了SSM,数据库采用了Mysql和Redis,使用Kafka作为消息队列,以及Elastic Search作为搜索引擎。 项目代码github地址:newcommunity 项目准备 准备工作就是一些工作环境的配置,IDE使用Intel...

weixin_41927235的博客 2万+

论坛项目使用新版ElasticSearch

测试类 @Test public void testSearchByTemplate() { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(QueryBuilders.multiMatchQuery("互联网寒冬", "title", "content")) .withSort(SortBuilders.fieldSor

布布汪的博客 818

秒杀项目---5.1 项目开篇

秒杀项目笔记

weixin_41961688的博客 1039

社区项目总结

第一章、主页功能 分页实现,按页码搜索10条帖子信息以及对应的用户信息返回给模板。 第二章、 1.任务:注册用户,给注册邮箱发送激活邮件,点击邮件的激活链接进行激活。 核心实现:mysql用户表存放用户激活情况,用户激活码,盐,md5加密的密码。注册时生成随机盐(随机数都是用的uuid)并且对密码用md5加密,这时发送激活邮件,随机字符串激活码也是uuid生成,并且激活链接必须包含用户以及激活码信息(这里用pathvariable),判断这个路径和mysql里面数据是否对应。 2.任务:登录功能。 核心实现

weixin_44320074的博客 6940

社区论坛项目(一)

环境搭建与技术栈

fjyjhhh的博客 880

将《高薪项目求职课》部署到阿里云centos服务器

历时1个半月的高薪项目求职课总算是做完了,今天跟着视频把项目部署到了阿里云上,为了便于以后复习,所以记录了部署过程,通过这个部署线上过程,确实学到了很多,对Linux也没有这么恐惧了 总共的过程为: 一、安装PuTTY二、安装unzip工具三、下载Jre四、安装Maven五、安装MySQL六、安装Redis七、安装kafka八、安装elasticSearch和中文分词插件...

Lucky小黄人的博客 868

Java项目课_仿网讨论区_运行讨论区项目要做的

运行讨论区项目要做的。 把项目从Windows上部署到Linux上。 把Linux上能跑的项目改为能在Windows上运行。 项目日志在Linux下的位置。

夜中听雪的博客 966

社区项目

社区实战项目

yahid的博客 869

社区项目笔记1

社区项目笔记 SpringMVC入门 1、开发的时候,关闭themleaf缓存,改页面之后不显示有延迟。上线后开启缓存,降低服务器的压力。 2、获得请求的消息头 请求方式和获取 get请求传参两种方式,问号拼接和直接作为地址拼接,两种获取数值的方法不一样。 url地址栏参数传值 1)带名称的传值 @RequestParam,name是url中的参数名称,是否必须,不传的话,默认值是多少 2)不带名称的传值(数值作为url的一部分传递) path中用{}括起来参数名称,@PathVariable获取参数

qq_43430343的博客 2452

#问答项目总结

登录和注册 1.1 登录功能: (1) 校验密码时取出该用户对应的密码和盐进行md5加密后与数据库的密码(密文)进行校对。讲讲md5:md5算法是一种不可逆的算法,使用的是hash算法,只有加密过程没有解密过程,但因为存在彩虹表(黑将常用的密码通过md5加密后存储到表中,将用户密码进行暴力破解),因此需要加盐,即给每一个用户密码后面添加一个随机的字符串再进行加密。 (2) 校验密码成功后,向...

weixin_44020556的博客 901

上的小项目

虽然不是做出来的,但是敲完也挺费事的。 public class BirdGame extends JPanel { // 背景图片 BufferedImage background; // 开始图片 BufferedImage startImage; // 结束图片 BufferedImage gameOverImage; // 地面...

weixin_43651992的博客 334
上一篇: 项目总结
下一篇: 简历应该这样写
Guo_Chuang
博客等级 码龄6年 9粉丝 61原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值