文章目录
介绍博客项目
有四个页面,登录页面,博客列表页,博客编辑页,博客详情页
一、准备工作
1、创建Maven项目
2、引入依赖
Servlet
jackson
mysql
3、创建目录
二、设计数据库
1、设计数据库
设计的关键是要找到数据库的实体,对应博客系统来说,需要blog表,user表。
create database if not exists blog_system;
use blog_system;
create table blog (
blogId int primary key auto_increment,
title varchar(1024), -- 博客标题
content mediumtext, -- 博客正文
userId int, -- 作者id
postTime datetime -- 发布时间
);
create table user (
userId int primary key auto_increment, -- 作者id
username varchar(128) unique, -- 用户名
password varchar(128) -- 密码
);
2、封装数据库操作
web开发中典型的代码结构:MVC
M: Model 模型,管理和组织数据
V: View 界面/视图,对应显示给用户的界面
C: Controller 控制器,表达业务逻辑
在 java 下创建 model 目录
创建 DBUtil.java 类
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;
// 通过这个类封装数据库建立连接/断开连接的操作
// 懒汉模式要考虑线程安全问题
// Servlet 程序天然就是运行在多线程模式下的, 每个请求都有可能对应一个线程(tomcat是通过多线程来处理很多请求的)
public class DBUtil {
private volatile static DataSource dataSource = null;
private static DataSource getDataSource() throws SQLException {
// 对 DBUtil 这个类进行加锁操作
if (dataSource == null) {
synchronized (DBUtil.class) {
if (dataSource == null) {
dataSource = new MysqlDataSource();
((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/blog_system?characterEncoding=utf8&useSSL=false");
((MysqlDataSource)dataSource).setUser("root");
((MysqlDataSource)dataSource).setPassword("1234");
}
}
}
return dataSource;
}
public static Connection getConnection() throws SQLException {
return getDataSource().getConnection();
}
public void close(Connection connection, PreparedStatement statement, ResultSet resultSet) {
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (statement != null) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
创建 Blog.java 类
package model;
import java.sql.Timestamp;
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 getPostTime() {
return postTime;
}
public void setPostTime(Timestamp postTime) {
this.postTime = postTime;
}
}
创建 User.java 类
package model;
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;
}
}
在创建两个类 BlogDao.java 和 UserDao.java
这里的Dao是什么意思?
Dao:Data Access Object 用来访问数据的对象,不过这只是习惯命名,也有叫 mapper 的,不是强制要求。
BlogDao.java
package model;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
// 针对博客要实现的功能
// 1.新增博客(博客编辑页)
// 2.查询出博客列表(博客列表页)
// 3.可以查询出指定博客的详情(博客详情页)
// 4.删除指定博客(可以博客详情页加入)
public class BlogDao {
// 1.新增博客(博客编辑页)
public void insert(Blog blog) {
Connection connection = null;
PreparedStatement statement = null;
try {
// 1.和数据库建立连接
connection = DBUtil.getConnection();
// 2.构造SQL语句
// SQL中提供了一个now()来提供现在的时间,也可以通过Java来获取时间再写入
String sql = "insert into blog values(null, ?, ?, ?, now())";
statement = connection.prepareStatement(sql);
statement.setString(1, blog.getTitle());
statement.setString(2, blog.getContent());
statement.setInt(3, blog.getUserId());
// 3.执行SQL语句
int ret = statement.executeUpdate();
if (ret == 1) {
System.out.println("插入成功");
} else {
System.out.println("插入失败");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtil.close(connection, statement, null);
}
}
// 2.查询出博客列表(博客列表页)
public List<Blog> selectAll() {
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
List<Blog> blogs = null;
try {
// 1.连接数据库
connection = DBUtil.getConnection();
// 2.构造SQL语句
String sql = "select * from blog";
statement = connection.prepareStatement(sql);
// 3.执行SQL
resultSet = statement.executeQuery();
// 4.遍历结果集
while (resultSet.next()) {
Blog blog = new Blog();
blog.setBlogId(resultSet.getInt("blogId"));
blog.setTitle(resultSet.getString("title"));
String content = resultSet.getString("content");
// 只截取前100个字符作为摘要
blog.setContent(content.substring(0, 100));
blog.setUserId(resultSet.getInt("userId"));
blog.setPostTime(resultSet.getTimestamp("postTime"));
blogs.add(blog);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtil.close(connection, statement, resultSet);
}
return blogs;
}
// 3.可以查询出指定博客的详情(博客详情页)
public Blog select(int blogId) {
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
// 1.数据库连接
connection = DBUtil.getConnection();
// 2.构造SQL语句
String sql = "select * from blog where blogId = ?";
statement = connection.prepareStatement(sql);
statement.setInt(1, blogId);
// 3.执行SQL
resultSet = statement.executeQuery();
// 4.遍历结果集,此处结果只能是0条或1条
if (resultSet.next()) {
Blog blog = new Blog();
blog.setBlogId(resultSet.getInt("blogId"));
blog.setContent(resultSet.getString("content"));
blog.setTitle(resultSet.getString("title"));
blog.setUserId(resultSet.getInt("userId"));
blog.setPostTime(resultSet.getTimestamp("postTime"));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtil.close(connection, statement, resultSet);
}
return null;
}
// 4.删除指定博客(可以博客详情页加入)
public void delete(int blogId) {
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
// 1.数据库连接
connection = DBUtil.getConnection();
// 2.构造SQL语句
String sql = "delete from blog where blogId = ?";
statement = connection.prepareStatement(sql);
statement.setInt(1, blogId);
// 3.执行SQL
int ret = statement.executeUpdate();
if (ret == 1) {
System.out.println("删除成功");
} else {
System.out.println("删除失败");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtil.close(connection, statement, resultSet);
}
}
}
UserDao.java
package model;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
// 关于 User表涉及的操作
// 1.根据用户名查询用户信息(实现登录的时候)
// 2.根据用户的id查询用户信息(获取文章的时候,根据博客的userId拿到作者的信息)
public class UserDao {
// 1.根据用户名查询用户信息(实现登录的时候)
public User select(String username) {
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
// 1.连接数据库
connection = DBUtil.getConnection();
// 2.构造SQL语句
String sql = "select * from user where username = ?";
statement = connection.prepareStatement(sql);
statement.setString(1, username);
// 3.执行SQL
resultSet = statement.executeQuery();
// 4.遍历结果集
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;
}
// 2.根据用户的id查询用户信息(获取文章的时候,根据博客的userId拿到作者的信息)
public User select(int userId) {
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
// 1.连接数据库
connection = DBUtil.getConnection();
// 2.构造SQL语句
String sql = "select * from user where userId = ?";
statement = connection.prepareStatement(sql);
statement.setInt(1, userId);
// 3.执行SQL
resultSet = statement.executeQuery();
// 4.遍历结果集
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;
}
}
上述的数据库操作代码有很多重复的,所以后面学的MyBatis就是一个常用的数据库操作框架,只要定制好你要执行的SQL是啥,具体的JDBC代码由框架帮我们自动生成。
三、核心业务
这里给出博客系统的前端代码:
CSDN 详解
gitee
直接从 gitee 上拷贝并解压到 webapp 目录下就可以了,接下来我们来改造这么系统,将前后端结合起来。
博客列表页实现:
前端从