项目简介
技术栈: Java + Mysql + Html +Ajax + Css + JS + Json
项目说明 :项目使用maven创建,使用MVC架构模式
- 表示层:通俗讲就是展现给用户的界面和控制器层Servlet,接受请求、封装数据、调用业务
逻辑层,响应数据。 - 业务逻辑层:针对具体问题的操作,也可以说是对数据层的操作,对数据业务逻辑处理。
- 数据访问层(持久层):该层所做事务直接操作数据库,针对数据的新增、删除、修改、查
找等每层之间是一种垂直的关系。
最后分出的项目包主体应该有(目前阶段): - utils:工具类
- dao:持久层(关于sql相关的操作)
- entity:实体类(数据库映射的JavaBean)
- service:业务层(用于处理具体业务)
- servlet/controller:控制器层(用于整合业务层与持久层)
图1 mvc架构模式流程
项目展示(部分)
项目架构
图2 项目架构
数据库—说明 :我的数据库版本是8.0.31
服务器—说明:我的tomcat是9.0.54
源码
myBlog
链接:https://pan.baidu.com/s/10oNwMx20WgPhzfUgKkoIjg?pwd=843m
提取码:843m
项目步骤
创建一个新的数据库 myBlogDB
建立表:
- 用户表:userTb
- 文章表:contextTb
sql脚本
create database myBlogdb character set utf8;
use myBlogdb;
create table userTb (
id int primary key auto_increment,
username varchar(20),
password varchar(20)
)charset=utf8;
insert into userTb(username,password) values('雾潋','123');
insert into userTb(username,password) values('张三','123');
create table contextTb (
id int primary key auto_increment,
title varchar(30),
createTime varchar(30),
context varchar(2000),
userId int
)charset=utf8;
数据库驱动配置
druid.properties文件
# 数据库连接信息 myblogdb是数据库名,别连错数据库
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/myblogdb?characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false
#用户名
username=root
#密码,自己的密码
password=root
# 连接池属性设置
# 连接池的初始化连接数(创建数据库连接池默认初始化的连接对象个数)
initialSize=10
# 连接池的最大连接数
maxActive=50
# 最小空闲连接数(当数据库使用率很低时,连接池中的连接会被释放一部分)
minIdle=5
# 超时等待时间(单位:ms)
maxWait=3000
项目依赖
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.wulian</groupId>
<artifactId>myBlog</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.31</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
</dependencies>
<build>
<finalName>myBlog</finalName>
</build>
</project>
entity实体类
User类
package entity;
/**
* usertb对应实体类
* 1. 属性 - 数据表对应
* 2. 构造方法(有参构造看需求)
* 3. Get and Set方法
* 4. toString
*/
public class User {
private Integer id;
private String username;
private String password;
public User() {
}
public User(Integer id, String username, String password) {
this.id = id;
this.username = username;
this.password = password;
}
public User(String username, String password) {
this.username = username;
this.password = password;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
Context类
package entity;
//博客实体类
public class Context {
private Integer id;
private String title;
private String createTime;
private String context;
private Integer userId;
public Context() {
}
public Context(Integer id, String title, String createTime, String context, Integer userId) {
this.id = id;
this.title = title;
this.createTime = createTime;
this.context = context;
this.userId = userId;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
public String getContext() {
return context;
}
public void setContext(String context) {
this.context = context;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
@Override
public String toString() {
return "Context{" +
"id=" + id +
", title='" + title + '\'' +
", createTime='" + createTime + '\'' +
", context='" + context + '\'' +
", userId=" + userId +
'}';
}
}
utils层
工具层 主要是提供一些工具比如数据库连接
数据库工具:
本次数据库采用druid连接
Druid数据库连接池工具类
package utils;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
/**
* Druid数据库连接池工具类
*/
public class DruidUtils {
//1. 定义DruidDateSource对象:表示Druid数据量连接池(数据源)
private static DruidDataSource druidDataSource;
//2. 定义静态代码块初始化DruidDateSource对象
static{
try {
//读取druid.propertis配置文件中的内容
// 此位置加上getClassLoader()类加载器的原因,在于我么你现在读取的配置文件在resource这个目录中
InputStream is = DruidUtils.class.getClassLoader().getResourceAsStream("druid.properties");
Properties properties = new Properties();
properties.load(is);
//使用属性文件初始化DruidDateSource对象
druidDataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
//3. 创建静态方法,从连接池中获取连接对象
public static Connection getConnection(){
Connection connection = null;
try {
connection = druidDataSource.getConnection();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return connection;
}
/**
* 关闭连接
* 多态的应用:使用Statement接口做从参数,既可以传递Statement接口对象,也可以传递
* PreparedStatement接口对象
*/
public static void close(Statement statement, Connection connection){
close(null,statement,connection);
}
/**
* 重载的方式如果存在ResultSet那么我们调用以下方法进行关闭,
* 如果没有调用上面的关闭方法
* 具体关闭方法
*/
public static void close(ResultSet resultSet, Statement statement, Connection connection){
try {
if(resultSet != null && !resultSet.isClosed()){
resultSet.close();
}
if(statement != null && !statement.isClosed()){
statement.close();
}
if(connection != null && !connection.isClosed()){
connection.close();
}
} catch (Exception throwables) {
throwables.printStackTrace();
System.out.println("-----关闭连接数据库失败!");
}
}
}
R层
R层通过此类型给前端发送JSON数据格式,此类型中的属性包含对应的状态码、消息、数据
package utils;
//通过此类型给前端发送JSON数据格式
//此类型中的属性包含对应的状态码、消息、数据
public class R<T> {
private int code;//状态码
private String message;//前端收到的消息
private T data;//前端请求的数据
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
/**
* 服务器成功返回用户请求的数据
* @param data 数据
* @return 具体JSON携带的数据
*/
public static R ok(Object data){
R r = new R();
r.setCode(200);
r.setMessage("ok");
r.setData(data);
return r;
}
/**
* 服务器成功返回用户请求的数据
* @param message 消息
* @return 具体返回的JSON数据
*/
public static R ok(String message){
R r = new R();
r.setCode(200);
r.setMessage(message);
return r;
}
/**
* 服务器返回错误消息方法
* @param message 错误消息
* @return 具体返回的JSON数据
*/
public static R error(String message){
R r = new R();
r.setCode(400);
r.setMessage(message);
return r;
}
}
dao层
主要是和数据库大打交道
userDao
package dao;
import entity.User;
import utils.DruidUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* usertb表相关的持久层操作
*/
public class UserDao {
//添加用户方法
public int addUser(User user){
//与数据库进行连接
Connection connection = DruidUtils.getConnection();
int i = 0;//返回值小于零说明加入失败,反之则成功
try {
//编写sql语句
String sql = "insert into usertb(username,password) values(?,?)";
//预执行
PreparedStatement ps = connection.prepareStatement(sql);
ps.setString(1,user.getUsername());
ps.setString(2,user.getPassword());
//执行更新user表
i = ps.executeUpdate();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return i;
}
//根据用户名查询数据方法
public User select(String username){
try {
//连接数据库
Connection connection = DruidUtils.getConnection();
//编写sql语句
String sql = "select id,username,password from usertb where username=?";
//预执行
PreparedStatement ps = connection.prepareStatement(sql);
ps.setString(1,username);
ResultSet rs = ps.executeQuery();
while(rs.next()){
User user = new User();
user.setId(rs.getInt(1));
user.setUsername(rs.getString(2));
user.setPassword(rs.getString(3));
//将读取出的用户数据变成user对象进行返回
return user;
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return null;
}
//根据用户名、密码来查找用户数据
public User select(String username,String password){
try {
//链接数据库
Connection connection = DruidUtils.getConnection();
//编写sql语句
String sql = "select id,username from usertb where username=? and password=?";
//预执行
PreparedStatement ps = connection.prepareStatement(sql);
//sql注入
ps.setString(1,username);
ps.setString(2,password);
ResultSet rs = ps.executeQuery();
while(rs.next()){
User user = new User();
user.setId(rs.getInt(1));
user.setUsername(rs.getString(2));
//将读取出的用户数据变成user对象进行返回
return user;
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return null;
}
}
contextDao
package dao;
import entity.Context;
import utils.DruidUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class ContextDao {
//获取当前用户的全部文章
public List<Context> select(Integer userId){
Connection connection = DruidUtils.getConnection();
//返回的List集合,包含当前用户的全部文章
ArrayList<Context> contexts = new ArrayList<Context>();
try {
String sql = "select id,title,createTime,context from contexttb where userId=?";
PreparedStatement ps = connection.prepareStatement(sql);
ps.setInt(1,userId);
ResultSet rs = ps.executeQuery();
while(rs.next()){
//每读出一篇文章就需要存入到Context实体类对象中
Context context = new Context();
context.setId(rs.getInt(1));
context.setTitle(rs.getString(2));
context.setCreateTime(rs.getString(3));
context.setContext(rs.getString(4));
//每一篇文章都是一个context对象,把所有的文章放入到List集合中
contexts.add(context);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return contexts;
}
//根据文章id获取文章详情
public Context selectContext(Integer id){
Connection connection = DruidUtils.getConnection();
try {
String sql = "select title,createTime,context from contexttb where id=?";
PreparedStatement ps = connection.prepareStatement(sql);
ps.setInt(1,id);
ResultSet rs = ps.executeQuery();
while(rs.next()){
//每读出一篇文章就需要存入到Context实体类对象中
Context context = new Context();
context.setTitle(rs.getString(1));
context.setCreateTime(rs.getString(2));
context.setContext(rs.getString(3));
return context;
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return null;
}
}
service层
service主要是处理具体的事务
userService
package service;
import dao.UserDao;
import entity.User;
//user相关的业务层
public class UserService {
//用户注册方法
public boolean register(String username,String password){
User user = new User(username,password);
//默认返回为true注册成功
boolean flag = true;
//调用Userdao层
UserDao userDao = new UserDao();
// 调用查询方法来查询用户名是否存在
User u = userDao.select(username);
//判断u类型是否为空,如果为空表示可以注册否则用户名重复
if(u == null){
//不存在注册
userDao.addUser(user);
return flag;
}else{
//表示用户已经注册过
flag = false;
return flag;
}
}
//用户登录方法
public User login(String username,String password){
//调用持久层
UserDao userDao = new UserDao();
User user = userDao.select(username,password);
if(user != null){
return user;
}
return null;
}
}
contextService
package service;
import dao.ContextDao;
import entity.Context;
import entity.User;
import java.util.List;
public class ContextService {
//获取当前用户全部文章
public List<Context> selectAll(User user){
List<Context> contexts;
//判断session中是否有数据(是否有用户登录)
if(user != null){
//从session中取出登录的用户id
Integer userId = user.getId();
//调用Dao层
ContextDao contextDao = new ContextDao();
//取出用户文章数据
contexts = contextDao.select(userId);
return contexts;
}
return null;
}
//根据文章id获取具体文章详情
public Context selectDetail(User user,Integer id){
//判断Session中是否有数据(用户是否登录)
if(user != null){
//调用dao层
ContextDao contextDao = new ContextDao();
Context detail = contextDao.selectContext(id);
return detail;
}
return null;
}
}
servlet(控制层)
主要对前端传来的数据做出反应,控制层的逻辑就是通过Session获取登录的用户信息。
注册
package servlet;
import com.alibaba.fastjson.JSON;
import service.UserService;
import utils.R;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/reg")
public class RegServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置字符集
request.setCharacterEncoding("utf-8");
// 获取用户参数
String username = request.getParameter("username");
String password = request.getParameter("password");
//调用service层
UserService service = new UserService();
//调用注册方法
boolean flag = service.register(username,password);
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
if(flag){
//改成为传递JSON数据
writer.print(JSON.toJSON(R.ok("注册成功!")));
}else{
//直接通过JSON数据输出对应内容
writer.print(JSON.toJSON(R.error("用户名已存在!")));
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request,response);
}
}
登录
package servlet;
import com.alibaba.fastjson.JSON;
import entity.User;
import service.UserService;
import utils.R;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置字符集
request.setCharacterEncoding("utf-8");
//设置响应头和数据格式
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
// 获取用户参数
String username = request.getParameter("username");
String password = request.getParameter("password");
// 获取'记住我'选框的值
String remember = request.getParameter("remember");
//调用service层
UserService service = new UserService();
//调用登录方法
User user = service.login(username,password);
if(user != null){
//判断用户是否勾选了记住我按钮
if("1".equals(remember)){
//勾选了,发送Cookie
Cookie c1 = new Cookie("username",username);
Cookie c2 = new Cookie("password",password);
//设置Cookie存活时间
c1.setMaxAge(60 * 60 * 24 * 7);
c2.setMaxAge(60 * 60 * 24 * 7);
//发送
response.addCookie(c1);
response.addCookie(c2);
}
//登录成功后通过Session保存用户信息
HttpSession session = request.getSession();
session.setAttribute("user",user);
writer.print(JSON.toJSON(R.ok("登录成功!")));
}else{
writer.print(JSON.toJSON(R.error("账号或者密码错误!")));
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request,response);
}
}
主页
package servlet;
import com.alibaba.fastjson.JSON;
import entity.User;
import service.UserService;
import utils.R;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/msg")
public class IndexServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置字符集
request.setCharacterEncoding("utf-8");
//设置响应头和数据格式
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
//判断session中是否有用户数据
//判断用户登录状态
HttpSession session = request.getSession();
User user = (User)session.getAttribute("user");
if(user != null){
String username = user.getUsername();
writer.print(JSON.toJSON(R.ok(username)));
}else{
writer.print(JSON.toJSON(R.error("未登录")));
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request,response);
}
}
文章处理
package servlet;
import com.alibaba.fastjson.JSON;
import entity.Context;
import entity.User;
import service.ContextService;
import utils.R;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
@WebServlet("/context")
public class ContextServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置字符集
request.setCharacterEncoding("utf-8");
//设置响应头和数据格式
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
//判断session中是否有用户数据
//判断用户登录状态
HttpSession session = request.getSession();
User user = (User)session.getAttribute("user");
//调用service层
ContextService contextService = new ContextService();
List<Context> contexts = contextService.selectAll(user);
//判断此用户是否有文章
if(!contexts.isEmpty()){
writer.print(JSON.toJSON(R.ok(contexts)));
}else{
writer.print(JSON.toJSON(R.error("此用户没有文章")));
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request,response);
}
}
细节处理
package servlet;
import com.alibaba.fastjson.JSON;
import entity.Context;
import entity.User;
import service.ContextService;
import utils.R;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
@WebServlet("/detail")
public class DetailServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取用户参数 文章id
String str = request.getParameter("id");
Integer id = Integer.parseInt(str);
// 设置字符集
request.setCharacterEncoding("utf-8");
//设置响应头和数据格式
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
//判断session中是否有用户数据
//判断用户登录状态
HttpSession session = request.getSession();
User user = (User)session.getAttribute("user");
//调用service层
ContextService contextService = new ContextService();
Context detail = contextService.selectDetail(user,id);
//判断此用户是否有文章
if(detail != null){
writer.print(JSON.toJSON(R.ok(detail)));
}else{
writer.print(JSON.toJSON(R.error("用户没有登录")));
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request,response);
}
}