实现一个简单的“个人博客”项目,java 基础大纲思维导图
@Override
public String toString() {
return "Blog{" +
"blogId=" + blogId +
", title='" + title + ''' +
", content='" + content + ''' +
", userId=" + userId +
", postTime=" + postTime +
'}';
}
}
User 类
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;
}
@Override
public String toString() {
return "User{" +
"userId=" + userId +
", username='" + username + ''' +
", password='" + password + ''' +
'}';
}
}
[](
)3.1 实现 Dao 层
针对 博客和用户进行具体的增删改查
创建 Dao 层 数据访问对象 通过 Dao 类来访问对象 Dao (Date access Object) 数据操作对象
BlogDao 类:
import java.sql.Connection;
import jav
a.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class BlogDao {
//1.新增一条博客
public void insertBlog(Blog blog){
//1.先建立连接 //2.写 sql 语句 //3.关闭资源
Connection connection=DBUtil.getConnection();
PreparedStatement preparedStatement=null;
String sql="insert into blog values (null,?,?,?,now())";
try {
preparedStatement=connection.prepareStatement(sql);
preparedStatement.setString(1,blog.getTitle());
preparedStatement.setString(2,blog.getContent());
preparedStatement.setInt(3,blog.getUserId());
int ret=preparedStatement.executeUpdate();
if(ret==1){
System.out.println("插入成功");
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
DBUtil.close(connection,preparedStatement,null);
}
}
//2.删除一条博客
public void deleteBlog(int blogId){
Connection connection=null;
PreparedStatement preparedStatement=null;
try{//1.建立连接
connection=DBUtil.getConnection();
//2.写 sql 语句
String sql="delete from blog where blogId=?";
preparedStatement=connection.prepareStatement(sql);
preparedStatement.setInt(1,blogId);
int ret=preparedStatement.executeUpdate();
if(ret==1){
System.out.println("删除成功!!!");
}
}catch (SQLException e){
e.printStackTrace();
}finally {
DBUtil.close(connection,preparedStatement,null);
}
}
//3.查找所有博客
//博客列表页需要
public List<Blog> selectAllBlog(){
//1.建立连接
Connection conn=null;
PreparedStatement pre=null;
ResultSet res=null;
List<Blog> blogList=new ArrayList<>();
conn=DBUtil.getConnection();
//2.写 sql 语句
String sql="select * from blog;";
try {
pre=conn.prepareStatement(sql);
//3.执行 SQL 语句
res=pre.executeQuery();
while(res.next()){
Blog blog=new Blog();
blog.setBlogId(res.getInt("blogId"));
blog.setTitle(res.getString("title"));
blog.setContent(res.getString("content"));
blog.setUserId(res.getInt("userId"));
blog.setPostTime(res.getTimestamp("postTime"));
blogList.add(blog);
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
DBUtil.close(conn,pre,res);
}
return blogList;
}
//4.从数据库查询指定的一篇博客
//博客内容页
public Blog selectOne(int blogId){
Connection conn=null;
PreparedStatement pre=null;
ResultSet res=null;
Blog blog=new Blog();
//1.建立连接
conn=DBUtil.getConnection();
//2.写 sql 语句
String sql="select * from blog where blogId=?";
try {
pre=conn.prepareStatement(sql);
pre.setInt(1,blogId);
res=pre.executeQuery();
if(res.next()){
blog.setBlogId(res.getInt("blogId"));
blog.setTitle(res.getString("title"));
blog.setContent(res.getString("content"));
blog.setUserId(res.getInt("UserId"));
blog.setPostTime(res.getTimestamp("postTime"));
return blog;
}
} catch (SQLException e) {
e.printStackTrace();
}
finally {
DBUtil.close(conn,pre,res);
}
return null;
}
}
UserDao 类:
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import sun.security.pkcs11.Secmod;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class UserDao {
//1.新增一个用户
public void insertUser(User user) {
//插入操作 新增用户
Connection conn = null;
PreparedStatement pre = null;
conn = DBUtil.getConnection();
try {
String sql = "insert into user values (null,?,?)";
pre = conn.prepareStatement(sql);
pre.setString(1, user.getUsername());
pre.setString(2, user.getPassword());
int ret = pre.executeUpdate();
if (ret == 1) {
System.out.println("注册成功!!!");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtil.close(conn, pre, null);
}
}
//2.登录时根据用户名来查找用户
public User selectByName(String username) {
Connection conn = null;
PreparedStatement pre = null;
ResultSet res = null;
conn = DBUtil.getConnection();
try {
String sql = "select * from user where username=?";
pre = conn.prepareStatement(sql);
pre.setString(1, username);
res = pre.executeQuery();
if (res.next()) {
User user = new User();
user.setUserId(res.getInt("userId"));
user.setUsername(res.getString("username"));
user.setPassword(res.getString("password"));
return user;
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtil.close(conn, pre, res);
}
return null;
}
//3.根据用户 id 查询
//显示博客的作者页 查询
public User selectById(int userId) {
Connection conn = null;
PreparedStatement pre = null;
ResultSet res = null;
User user = new User();
//建立连接 写 SQL 执行 关闭
conn = DBUtil.getConnection();
String sql = "select * from user where userId=?";
try {
pre = conn.prepareStatement(sql);
pre.setInt(1, userId);
res = pre.executeQuery();
if (res.next()) {
user.setUserId(res.getInt("userId"));
user.setUsername(res.getString("username"));
user.setPassword(res.getString("password"));
return user;
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtil.close(conn, pre, res);
}
return null;
}
}
[](
)3.2 总结
书写流程:
1.建立连接
2.写 SQL 语句
3.执行 SQL 语句
4.如果是查询操作就要遍历结果集
5.关闭资源
注意在写 Dao 类时代码都是类似的,只有查找操作时返回结果集,需要使用.executeQuery 方法来输出结果集,其他三种操作返回的是 int 类型有几条数据被执行成功了
这是查找操作
res=pre.executeQuery();
这是删除,插入,修改操作
int ret=preparedStatement.executeUpdate();
查找操作需要设置属性,通过.set 属性(结果集来.get 方法获取)
blog.setTitle(res.getString("title"));
blog.setContent(res.getString("content"));
通常用?来作为占位符,再设置占位符
preparedStatement.setString(1,blog.getTitle());
preparedStatement.setString(2,blog.getContent());
[](
)四.实现博客页面
===========================================================================
[](
)4.1 实现博客列表页
使用模板引擎(Thymeleaf)来实现页面,模板就是一个 HTML 文件,只不过缺失了一些关键信息
重要的时我们先使用写一些固定的 HTML 文件,只不过关键数据来使用 Thymeleaf 的特殊符号进行占位,之后从 Servlet 代码中获取到这些关键信息之后把关键信息替换到 HTML 模板中的特殊符号。
Thymeleaf 中的提供的语法都是以 th 开头的
我们在构建页面的时候,需要动态的显示博客展示页中有几篇博客,而不是写死,所有就要用到 Thymeleaf 中 each 以及{ }大括号里面的内容就是 Thymeleaf 从 java 代码中获取到的变量,此时 blogs 就是动态的显示数据库中有几个对象。
<div class="blog" th:each="blog : ${blogs}">
th:text 把变量里的内容按照字符串的形式,替换到 HTML 标签内部
<a th:href="{blog.title}">我是标题</a>
通过 Thymeleaf 在 Java 代码中进行渲染,格式基本是一样的
1.在使用 Thymeleaf 之前,要先进行初始化
// 1) 创建一个 engine(引擎), 负责把 Java 中的数据替换到模板中.
TemplateEngine engine = new TemplateEngine();
2.创建一个 resolver 对象
// 2) 创建一个 resolver 对象(解析器), 负责找到 html 模板在哪, 并加载到内存中.
// 供 engine 对象来使用.
ServletContextTemplateResolver resolver = new ServletContextTemplateResolver(sce.getServletContext());
3.给 resolver 设置一些属性
// 3) 给 resolver 设置一些属性, 让它能够找到 html 模板.
resolver.setCharacterEncoding("utf-8");
// Prefix 表示 "前缀", 设定了满足啥样条件的文件被加载到内存中作为 HTML 模板
resolver.setPrefix("/WEB-INF/template/");
// Suffix 表示 "后缀"
resolver.setSuffix(".html");
把 resolver 和 engine 关联起来.
// 4) 把 resolver 和 engine 关联起来.
engine.setTemplateResolver(resolver);
初始化之后就可以进行渲染了
编写 Java 代码的具体的流程
1.对 Thymeleaf 进行初始化
// 1) 创建一个 engine(引擎), 负责把 Java 中的数据替换到模板中.
TemplateEngine engine = new TemplateEngine();
// 2) 创建一个 resolver 对象(解析器), 负责找到 html 模板在哪, 并加载到内存中.
// 供 engine 对象来使用.
ServletContextTemplateResolver resolver = new ServletContextTemplateResolver(sce.getServletContext());
// 3) 给 resolver 设置一些属性, 让它能够找到 html 模板.
resolver.setCharacterEncoding("utf-8");
// Prefix 表示 "前缀", 设定了满足啥样条件的文件被加载到内存中作为 HTML 模板
resolver.setPrefix("/WEB-INF/template/");
// Suffix 表示 "后缀"
resolver.setSuffix(".html");
// 4) 把 resolver 和 engine 关联起来.
engine.setTemplateResolver(resolver);
2.进行渲染
用 Webcontext,把数据收集起来,统一传给 engine,使用 engine.process 方法,就是进行具体的渲染工作。
注意 Thymeleaf 只需要初始化依次,所以同一个 engine 需要在多个 Servlet 中共享,就可以使用 ServletContent,把初始化 engine 的工作在 ServletContent 进行,并且把 engine 实例交给 ServletContent 管理,这样的话,任意的 Servlet 都能拿到 ServletContent 对象,也就是都能拿到同一个 engine 对象了。
[](
)4.2 实现博客正文页
点击博客标题,就能跳转到博客正文,显示博客标题,正文,时间,内容等
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>博客详情页</title>
<style> /* 清除浏览器默认样式 */
{
margin: 0;
padding: 0;
}
body {
background-color: #f3f3f3;
}
.container {
width: 800px;
margin: 0 auto;
background-color: #fff;
}
.title {
text-align: center;
padding: 10px 0;
font-size: 36px;
}
.author {
text-align: center;
padding: 10px 0;
color: #999aaa;
}
.post-time {
text-align: center;
color: #999aaa;
}
.content {
padding: 10px 0;
text-indent: 20px;
}
.nav {
height: 50px;
background: #000;
color: #fff;
display: flex;
align-items: center;
}
.nav-title {
padding-left: 10px;
}
.nav-button {
color: #fff;
text-decoration: none;
padding: 0 10px;
}
.spacer {
width: 55%;
} </style>
</head>
<body>
<div class="nav">
<h3 class="nav-title">我的博客系统</h3>
<div class="spacer"></div>
<a class="nav-button" th:href="${'blogDelete?blogId=' + blog.blogId}">删除</a>
</div>
<div class="container">
<h3 th:text="${blog.title}" class="title">这是博客标题</h3>
<div class="author" th:text="${username}">FY</div>
<div class="post-time" th:text="${blog.postTime}">2021-07-20 12:21:42</div>
<div class="content" th:text="${blog.content}">
这是博客正文
这是博客正文
这是博客正文
这是博客正文
这是博客正文
</div>
</div>
</body>
</html>
服务器实现:
使用 GET 请求,来实现跳转,从请求中捕获点击的第几篇博客(BlogId)之后从数据库中查找到 user 对象,
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.WebContext;
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 java.io.IOException;
@WebServlet("/blogContent")
public class BlogContentServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
//点击 跳转 GET 请求
//1.从 req 中读取到出 BlogId
String blogId=req.getParameter("blogId");
if(blogId==null||"".equals(blogId)){
// resp.getWriter().write("<h3>博客页面不存在</h3>"); 两种都可以
resp.sendError(404,"blogId 参数错误");
return ;
}
//2. 从 BlogId 在数据库中查找详细内容出
BlogDao blogDao=new BlogDao();
Blog blog=blogDao.selectOne(Integer.parseInt(blogId));
评论