目录
前言
上一篇文章:基于Servlet+JDBC实现的基础博客系统>>系列2 -- 前端基础页面 对整个博客系统进行了简要的构建,接下来将博客系统进行实现前后端的交互. 全文项目的代码链接已经上传到git,欢迎大家访问,也希望得到大家的指点.谢谢.
1. 前期准备
1. 了解MVC模式
MVC(Model View Controller)是一种软件设计的框架模式,它采用模型(Model)-视图(View)-控制器(controller)的方法把业务逻辑、数据与界面显示分离。把众多的业务逻辑聚集到一个部件里面,当然这种比较官方的解释是不能让我们足够清晰的理解什么是MVC的。用通俗的话来讲,MVC的理念就是把数据处理、数据展示(界面)和程序/用户的交互三者分离开的一种编程模式。
2. 创建Maven项目,引入相关依赖
下面是pom.xml的内容,主要是引入了Servlet Jackson MySQL的环境依赖
<?xml version="1.0" encoding="UTF-8"?> <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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>blogSystem</artifactId> <version>1.0-SNAPSHOT</version> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.15.0</version> </dependency> <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.49</version> </dependency> </dependencies> </project>
3. 整个项目使用idea中的插件SmartTomCat ,方便进行调试.
2. Model层
2.1 数据库的设计
在博客系统中,主要包含登录功能、注销功能、发布博客、删除博客、博客展示的功能。涉及到的实体即博客和用户。数据库表设计如下,具体见代码注释:
-- 一般对于建表的 sql 都会单独搞个 .sql 文件来保存.
-- 后续程序可能需要在不同的主机上部署. 部署的时候就需要在对应的主机上把数据库也给创建好.
-- 把建表 sql 保存好, 方便在不同的机器上进行建库建表
-- 1.创建数据数据库
create database if not exists java107_blog_system character set utf8mb4;
use java107_blog_system;
-- 2. 创建各种表
drop table if exists blog;
-- 2.1 blog表
create table blog(
blogId int primary key auto_increment,
title varchar(128),
content varchar(4096),
userId int,
postTime datetime
);
drop table if exists user;
-- 2.2 user表
create table user(
userId int primary key auto_increment,
username varchar(50) unique,
password varchar(50)
);
insert into user values(null, '张三', '123'), (null, '李四', '123');
insert into blog values(null, '我的第一篇博客', '这是博客正文', 1, '2023-06-04 12:00:00');
insert into blog values(null, '我的第二篇博客', '这是博客正文', 1, '2023-06-05 12:00:00');
insert into blog values(null, '我的第二篇博客', '如果你想用Java的SimpleDateFormat类来格式化时间,你可以使用以下代码:import java.text.SimpleDateFormat;import java.util.Date;public class Main{public static void main(String[] args){Date date = new Date();String strDateFormat = "yyyy-MM-dd HH:mm:ss";SimpleDateFormat sdf = new SimpleDateFormat(strDateFormat);System.out.println(sdf.format(date));}}', 1, '2023-06-05 12:00:00');
2.2 数据库表对应的实体类实现
User类
每个 user 对象,对应 user 表的一条记录。
package model;
/**
* Created with IntelliJ IDEA.
* Description:用户user表的实体
* User: YAO
* Date: 2023-06-21
* Time: 10:47
*/
public class User {
private int userId;
private String username;
private String password;
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
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;
}
}
Blog类
每个 blog 对象,对应 blog 表的一条记录。
package model;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
/**
* Created with IntelliJ IDEA.
* Description:博客blog表的实体
* 一个blog对象的实例就代表表中的一条记录
* User: YAO
* Date: 2023-06-21
* Time: 10:46
*/
public class Blog {
private int blogId;
private String title;
private String content;
private int userId;
private Timestamp postTime;
public int getBlogId() {
return blogId;
}
public void setBlogId(int blogId) {
this.blogId = blogId;
}
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 getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public Timestamp getPostTimeStamp() {
return postTime;
}
public String getPostTime() {
// TimeStamp 返回的是时间戳
// 这里要将时间戳进行格式化 使用SimpleDataFormat
String strDateFormat = "yyyy-MM-dd HH:mm:ss";
SimpleDateFormat sdf = new SimpleDateFormat(strDateFormat);
return sdf.format(postTime);
}
public void setPostTime(Timestamp postTime) {
this.postTime = postTime;
}
}
特别关注:针对时间戳在后端进行格式化字符串处理,便于前端的展示。
2.3 JDBC 工具类实现
DBUtil 封装了用于获取数据库连接和关闭数据库连接资源的方法,便于 各个实体的Dao 使用,降低代码冗余度。
package model;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* Created with IntelliJ IDEA.
* Description:通过封装处理数据库的连接操作
* User: YAO
* Date: 2023-06-21
* Time: 10:29
*/
public class DBUtil {
// 这个类要提供DataSource
private static volatile DataSource dataSource = null;
private static DataSource getDataSource(){
// 懒汉模式进行创建数据库连接实例
if (dataSource == null){
synchronized (DBUtil.class){
if (dataSource == null){
dataSource = new MysqlDataSource();
((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java107_blog_system?characterEncoding=utf8&useSSL=false");
((MysqlDataSource)dataSource).setUser("root");
((MysqlDataSource)dataSource).setPassword("111111");
}
}
}
return dataSource;
}
public static Connection getConnection() throws SQLException {
// 建立数据库连接
return getDataSource().getConnection();
}
public static void close(Connection connection, PreparedStatement statement, ResultSet resultSet) throws SQLException {
if (resultSet != null){
resultSet.close();
}
if (statement!=null){
statement.close();
}
if (connection!=null){
connection.close();
}
}
}
2.4 UserDao 的实现
DAO: Data Access Object 就是通过这个对象进行访问数据
主要实现方法:
1. selectUserById
2. selectUserById
package model;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* Created with IntelliJ IDEA.
* Description:user表的增删改查
* DAO : Data Access Object 通过这样的对象进行访问数据
* User: YAO
* Date: 2023-06-21
* Time: 10:52
*/
public class UserDao {
public User selectUserById(int userId) throws SQLException {
// 根据id查询用户对象
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try{
connection = DBUtil.getConnection();
String sql = "select * from user where userId= ?";
statement = connection.prepareStatement(sql);
statement.setInt(1,userId);
resultSet = statement.executeQuery();
if (resultSet.next()){
User user = new User();
user.setUserId(resultSet.getInt("userId"));
user.setUsername(resultSet.getString("username"));
user.setPassword(resultSet.getString("password"));
return user;
}
} catch (SQLException e) {
e.printStackTrace();
}
finally {
DBUtil.close(connection,statement,resultSet);
}
return null;
}
public User selectUserByName(String username) throws SQLException {
// 根据name查询用户对象
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
connection = DBUtil.getConnection();
String sql = "select * from user where username = ?";
statement = connection.pre