手把手带你搭建个人博客系统(一)

news2024/11/26 18:30:38

在这里插入图片描述

请添加图片描述

⭐️前言⭐️

该web开发系统涉及到的知识:

  • Java基础
  • MySQL数据库
  • JDBC技术
  • 前端三件套(HTML+CSS+JavaScript)
  • Servlet

使用到的开发工具:

  • idea
  • vscode
  • tomcat
  • postman
  • Fiddler

博主将会手把手带你搭建个人博客系统。
因文章篇幅较长,所以整个流程分两篇文章来完成

🍉博客主页: 🍁【如风暖阳】🍁
🍉精品Java专栏【JavaSE】、【备战蓝桥】、【JavaEE初阶】、【MySQL】、【数据结构】
🍉欢迎点赞 👍 收藏留言评论 📝私信必回哟😁

🍉本文由 【如风暖阳】 原创,首发于 CSDN🙉

🍉博主将持续更新学习记录收获,友友们有任何问题可以在评论区留言

🍉博客中涉及源码及博主日常练习代码均已上传码云(gitee)、GitHub


请添加图片描述

📍内容导读📍

  • 🍅1.准备工作
  • 🍅2.前端页面设计
    • 2.1 博客列表页
    • 2.2 博客详情页
    • 2.3 博客登录页
    • 2.4 博客编辑页
    • 2.5 前端页面引入项目
  • 🍅3.编写数据库操作代码
    • 3.1 数据库设计
    • 3.2 封装数据库操作
      • 3.2.1 创建DBUtil类
      • 3.2.2 创建实体类
      • 3.2.3 封装针对数据的增删改查
  • 未完待续(见文章二)

请添加图片描述

🍅1.准备工作

该步骤完成主要的maven项目搭建,与一般的servlet项目开发流程相同。
1)创建maven项目
在这里插入图片描述
2)引入必要依赖
MySQL 5版本依赖
servlet 3.1.0 版本依赖
jackson依赖

pom文件中引入这些依赖
在这里插入图片描述
3.创建必要目录,填写web.xml文件的代码块

在这里插入图片描述

在这里插入图片描述
4.编写基本servlet代码,用于测试环境是否搭建完成
在这里插入图片描述
5、6打包部署
在这里插入图片描述
7.验证
在这里插入图片描述

🍅2.前端页面设计

在这一步,我们先完成前端页面的设计,填写基本的内容,了解基本的业务需求,共需要设计以下界面:

2.1 博客列表页

在这里插入图片描述
列表页HTML代码:blog_list.html

<!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>
    <link rel="stylesheet" href="css/common.css">
    <link rel="stylesheet" href="css/blog_list.css">
</head>
<body>
    <div class="nav">
        <img src="image/dd.jpg" alt="">
        <span>我的博客系统</span>
        <!-- 空白元素,用来占位置 -->
        <div class="spacer"></div>
        <a href="blog_list.html">主页</a>
        <a href="blog_edit.html">写博客</a>
        <a href="#">注销</a>
    </div>
    <!-- container作为页面的版心 -->
    <div class="container">
        <!-- 左侧个人信息 -->
        <div class="left">
            <!-- 表示整个用户信息区域 -->
            <div class="card">
                <img src="image/2.jpg" alt="">
                <h3>如风暖阳</h3>
                <a href="#">gitHub地址</a>
                <div class="counter">
                    <span>文章</span>
                    <span>分类</span>
                </div>
                <div class="counter">
                    <span>2</span>
                    <span>1</span>
                </div>
            </div>
        </div>

        <!-- 右侧个人信息 -->
        <div class="right">
            <!-- .blog对应一个博客 -->
            <div class="blog">
                <!-- 博客标题 -->
                <div class="title">
                    我的第一篇博客
                </div>
                <!-- 博客发布时间 -->
                <div class="date">
                    2022-10-21 21:24:00
                </div>
                <div class="desc">
                    刷爆LeetCode!Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolore, hic ipsa veritatis adipisci rem, provident accusantium deserunt soluta magnam distinctio consequatur fugit, neque omnis explicabo deleniti reiciendis magni architecto eaque!
                </div>
                <a href="#">查看全文&gt;&gt;</a>
            </div>
            
            <div class="blog">
                <!-- 博客标题 -->
                <div class="title">
                    我的第一篇博客
                </div>
                <!-- 博客发布时间 -->
                <div class="date">
                    2022-10-21 21:24:00
                </div>
                <div class="desc">
                    刷爆LeetCode!Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolore, hic ipsa veritatis adipisci rem, provident accusantium deserunt soluta magnam distinctio consequatur fugit, neque omnis explicabo deleniti reiciendis magni architecto eaque!
                </div>
                <a href="#">查看全文&gt;&gt;</a>
            </div>
        </div>
    </div>
</body>
</html>

列表页引入的css样式:
1.所有页面共同的css样式:common.css

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

/* 给整个页面加上背景图 */
html,body {
    height: 100%;
}

body {
    background-image: url(../image/555.png);
    background-repeat: no-repeat;
    background-position: center center;
    background-size: cover;
}

.nav {
    width: 100%;
    height: 50px;

    background-color: rgba(51,51,51,0.5);
    color: white;

    /* 导航栏内部的内容,都是一行排列的 */
    display: flex;
    /* 实现子元素垂直居中 */
    align-items: center;
}
.nav img {
    width: 40px;
    height: 40px;
    border-radius: 50%;

    margin-left: 30px;
    margin-right: 10px;
}

.nav .spacer{
    width: 80%;
}

.nav a {
    color:white;
    text-decoration: none;
    padding: 0 10px;
}

/* 版心样式 */
.container {
    /* 版心略小于窗口 */
    width: 1000px;
    /* 闪出导航栏的高度 */
    height: calc(100% - 50px);

    /* 水平居中 */
    margin: 0 auto;

    display: flex;
    justify-content: space-around;
}

.container .left {
    height: 100%;
    width: 200px;
}

.container .right {
    height: 100%;
    width: 795px;

    background-color: rgba(255,255,255,0.8);
    border-radius: 10px;

    overflow:auto;
}

.card {
    background-color: rgba(255,255,255,0.8);
    border-radius: 10px;

    padding: 30px;
}

.card img{
    width: 140px;
    height: 140px;
    border-radius: 50%;
}

.card h3 {
    text-align: center;
    padding: 10px;
}

.card a {
    /* 默认a是行内元素,很多功能对行内元素不生效,需要将其设为块级元素 */
    display: block;
    text-align: center;
    text-decoration: none;
    color: #999;
    padding: 10px;
}

.card .counter {
    display: flex;
    justify-content: space-around;
    padding: 5px;
}

2.博客列表页单独的css样式:blog_list.css

/* 这个文件专门写和博客列表页相关的样式 */

.blog {
    width: 100%;
    padding: 20px;
}

.blog .title {
    text-align: center;
    font-size: 23px;
    font-weight: bold;
    padding: 10px 0;
}

.blog .date {
    text-align: center;
    color: rgb(15,100,60);
    padding: 10px 0;
}

.blog .desc {
    text-indent: 2em;
}

.blog a {
    /* 设置成块级元素,方便设置尺寸和边框 */
    display: block;
    width: 140px;
    height: 40px;
    margin: 10px auto;
    border: 2px black solid;

    color: black;
    line-height: 38px;
    text-align: center;
    text-decoration: none;

    transition: all 0.5s;
}

.blog a:hover {
    background-color: #333;
    color: #fff;
}

2.2 博客详情页

在这里插入图片描述
详情页HTML代码块:blog_detail.html

<!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>
    <link rel="stylesheet" href="css/common.css">
    <link rel="stylesheet" href="css/blog_detail.css">
</head>
<body>
    <div class="nav">
        <img src="image/dd.jpg" alt="">
        <span>我的博客系统</span>
        <!-- 空白元素,用来占位置 -->
        <div class="spacer"></div>
        <a href="blog_list.html">主页</a>
        <a href="blog_edit.html">写博客</a>
        <a href="#">注销</a>
    </div>

    <div class="container">
        <!-- 左侧个人信息 -->
        <div class="left">
            <!-- 表示整个用户信息区域 -->
            <div class="card">
                <img src="image/2.jpg" alt="">
                <h3>如风暖阳</h3>
                <a href="#">gitHub地址</a>
                <div class="counter">
                    <span>文章</span>
                    <span>分类</span>
                </div>
                <div class="counter">
                    <span>2</span>
                    <span>1</span>
                </div>
            </div>
        </div>

        <!-- 右侧个人信息 -->
        <div class="right">
            <!-- 使用该div来包裹整个博客的内容详情 -->
            <div class="blog-content">
                <!-- 博客标题 -->
                <h3>我的第一篇博客</h3>
                <!-- 博客的时间 -->
                <div class="date">2022-10-22 18:17</div>
                <!-- 正文 -->
                <p>
                    刷爆LeetCode!Lorem ipsum dolor sit amet consectetur, adipisicing elit. Maiores sunt ut odio earum sit dolorem ex delectus expedita ratione et quaerat, repudiandae tenetur possimus nihil officia distinctio quis rem voluptate!
                </p>
                <p>
                    刷爆LeetCode!Lorem ipsum dolor sit amet consectetur, adipisicing elit. Maiores sunt ut odio earum sit dolorem ex delectus expedita ratione et quaerat, repudiandae tenetur possimus nihil officia distinctio quis rem voluptate!
                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat fugiat totam perferendis veniam porro harum dolorem ullam reiciendis atque, amet quia minus odio neque odit iusto, temporibus veritatis. Magnam, accusantium!
                </p>
                <p>
                    刷爆LeetCode!Lorem ipsum dolor sit amet consectetur, adipisicing elit. Maiores sunt ut odio earum sit dolorem ex delectus expedita ratione et quaerat, repudiandae tenetur possimus nihil officia distinctio quis rem voluptate!
                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat fugiat totam perferendis veniam porro harum dolorem ullam reiciendis atque, amet quia minus odio neque odit iusto, temporibus veritatis. Magnam, accusantium!
                </p>
                <p>
                    刷爆LeetCode!Lorem ipsum dolor sit amet consectetur, adipisicing elit. Maiores sunt ut odio earum sit dolorem ex delectus expedita ratione et quaerat, repudiandae tenetur possimus nihil officia distinctio quis rem voluptate!
                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat fugiat totam perferendis veniam porro harum dolorem ullam reiciendis atque, amet quia minus odio neque odit iusto, temporibus veritatis. Magnam, accusantium!
                </p>
                <p>
                    刷爆LeetCode!Lorem ipsum dolor sit amet consectetur, adipisicing elit. Maiores sunt ut odio earum sit dolorem ex delectus expedita ratione et quaerat, repudiandae tenetur possimus nihil officia distinctio quis rem voluptate!
                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat fugiat totam perferendis veniam porro harum dolorem ullam reiciendis atque, amet quia minus odio neque odit iusto, temporibus veritatis. Magnam, accusantium!
                </p>
                <p>
                    刷爆LeetCode!Lorem ipsum dolor sit amet consectetur, adipisicing elit. Maiores sunt ut odio earum sit dolorem ex delectus expedita ratione et quaerat, repudiandae tenetur possimus nihil officia distinctio quis rem voluptate!
                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat fugiat totam perferendis veniam porro harum dolorem ullam reiciendis atque, amet quia minus odio neque odit iusto, temporibus veritatis. Magnam, accusantium!
                </p>
                <p>
                    刷爆LeetCode!Lorem ipsum dolor sit amet consectetur, adipisicing elit. Maiores sunt ut odio earum sit dolorem ex delectus expedita ratione et quaerat, repudiandae tenetur possimus nihil officia distinctio quis rem voluptate!
                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat fugiat totam perferendis veniam porro harum dolorem ullam reiciendis atque, amet quia minus odio neque odit iusto, temporibus veritatis. Magnam, accusantium!
                </p>
                <p>
                    刷爆LeetCode!Lorem ipsum dolor sit amet consectetur, adipisicing elit. Maiores sunt ut odio earum sit dolorem ex delectus expedita ratione et quaerat, repudiandae tenetur possimus nihil officia distinctio quis rem voluptate!
                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat fugiat totam perferendis veniam porro harum dolorem ullam reiciendis atque, amet quia minus odio neque odit iusto, temporibus veritatis. Magnam, accusantium!
                </p>
                <p>
                    刷爆LeetCode!Lorem ipsum dolor sit amet consectetur, adipisicing elit. Maiores sunt ut odio earum sit dolorem ex delectus expedita ratione et quaerat, repudiandae tenetur possimus nihil officia distinctio quis rem voluptate!
                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat fugiat totam perferendis veniam porro harum dolorem ullam reiciendis atque, amet quia minus odio neque odit iusto, temporibus veritatis. Magnam, accusantium!
                </p>
                <p>
                    刷爆LeetCode!Lorem ipsum dolor sit amet consectetur, adipisicing elit. Maiores sunt ut odio earum sit dolorem ex delectus expedita ratione et quaerat, repudiandae tenetur possimus nihil officia distinctio quis rem voluptate!
                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat fugiat totam perferendis veniam porro harum dolorem ullam reiciendis atque, amet quia minus odio neque odit iusto, temporibus veritatis. Magnam, accusantium!
                </p>
                <p>
                    刷爆LeetCode!Lorem ipsum dolor sit amet consectetur, adipisicing elit. Maiores sunt ut odio earum sit dolorem ex delectus expedita ratione et quaerat, repudiandae tenetur possimus nihil officia distinctio quis rem voluptate!
                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quaerat fugiat totam perferendis veniam porro harum dolorem ullam reiciendis atque, amet quia minus odio neque odit iusto, temporibus veritatis. Magnam, accusantium!
                </p>
            </div>
        </div>
    </div>
</body>
</html>

详情页引入的CSS样式:blog_detail.css

/* 博客详情页样式文件 */
.blog-content {
    padding: 30px;
}

.blog-content h3 {
    text-align: center;
    padding: 20px 0;
}

.blog-content .date {
    text-align: center;
    color: rgb(0,128,0);
    padding: 10px 0;
}

.blog-content p {
    text-indent: 2em;
    padding: 10px 0;
}

2.3 博客登录页

在这里插入图片描述
登录页HTML代码:blog_login.html

<!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>Document</title>
    <link rel="stylesheet" href="css/common.css">
    <link rel="stylesheet" href="css/blog_login.css">
</head>
<body>
    <div class="nav">
        <img src="image/dd.jpg" alt="">
        <span>我的博客系统</span>
        <!-- 空白元素,用来占位置 -->
        <div class="spacer"></div>
        <a href="blog_list.html">主页</a>
        <a href="blog_edit.html">写博客</a>
        <!-- <a href="#">注销</a> -->
    </div>

    <div class="login-container">
        <div class="login-dialog">
            <h3>登录</h3>
            <div class="row">
                <span>用户名</span>
                <input type="text" id="username">
            </div>
            <div class="row">
                <span>密码</span>
                <input type="password" id="password">
            </div>
            <div class="row">
                <button>提交</button>
            </div>
        </div>
    </div>
</body>
</html>

引入的css样式:blog_login.css

.login-container {
    width: 100%;
    /* 注意减号两边有空格 */
    height: calc(100% - 50px);

    /* 需要让里面的子元素, 垂直水平居中, 需要用到 flex 布局 */
    display: flex;
    align-items: center;
    justify-content: center;
}

.login-dialog {
    width: 400px;
    height: 350px;
    background-color: rgba(255,255,255,0.8);
    border-radius: 10px;
}

.login-dialog h3 {
    text-align: center;
    padding: 50px 0;
}

.login-dialog .row {
    height: 50px;
    width: 100%;

    display: flex;
    align-items: center;
    justify-content: center;
}

.login-dialog .row span {
    /* 把span设置为块级元素方便后续设置尺寸 */
    display: block;
    width: 100px;
    font-weight: 700;
}

#username,#password {
    width: 200px;
    height: 40px;
    font-size: 22px;
    line-height: 40px;
    padding-left: 10px;
    border-radius: 10px;
}

.row button {
    width: 300px;
    height: 50px;
    border-radius: 10px;
    color: white;
    background-color: rgb(0,128,0);
    border: none;
    outline: none;

    margin-top:50px ;
}

.row button:active {
    background-color: #666;
}

2.4 博客编辑页

在这里插入图片描述
实现博客编辑页,我们可以看到页面上需要有一个博客编辑器——markdown编辑器,我们可以通过引入第三方库来实现这样的效果。

插入编辑器流程如下:
1)搜索edito.md,下载压缩包,并解压到代码目录。
在这里插入图片描述
在这里插入图片描述
2)引入edtior编辑器必要的依赖jQuery
搜素jquery,复制其地址,引入script标签
在这里插入图片描述
3)引入html文件中editor.md的依赖

	<link rel="stylesheet" href="editor.md/css/editormd.min.css" />
    <script src="js/jquery.min.js"></script>
    <script src="editor.md/lib/marked.min.js"></script>
    <script src="editor.md/lib/prettify.min.js"></script>
    <script src="editor.md/editormd.js"></script>

4)初始化编译器

	<script>
        // 初始化编辑器
        let editor = editormd("editor", {
            // 这里的尺寸必须在这里设置. 设置样式会被 editormd 自动覆盖掉. 
            width: "100%",
            // 设定编辑器高度
            height: "calc(100% - 50px)",
            // 编辑器中的初始内容
            markdown: "# 在这里写下一篇博客",
            // 指定 editor.md 依赖的插件路径
            path: "editor.md/lib/"
        });
    </script>

博客编辑页HTML文件:blog_edit.html

<!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>Document</title>
    <link rel="stylesheet" href="css/common.css">
    <link rel="stylesheet" href="css/blog_edit.css">

    <!-- 引入 editor.md 的依赖 -->
    <link rel="stylesheet" href="editor.md/css/editormd.min.css" />
    <script src="js/jquery.min.js"></script>
    <script src="editor.md/lib/marked.min.js"></script>
    <script src="editor.md/lib/prettify.min.js"></script>
    <script src="editor.md/editormd.js"></script>
</head>
<body>
    <div class="nav">
        <img src="image/dd.jpg" alt="">
        <span>我的博客系统</span>
        <!-- 空白元素,用来占位置 -->
        <div class="spacer"></div>
        <a href="blog_list.html">主页</a>
        <a href="blog_edit.html">写博客</a>
        <a href="#">注销</a>
    </div>
    <!-- 包裹整个博客编辑页内容的顶级容器 -->
    <div class="blog-edit-container">
        <div class="title">
            <input type="text" placeholder="在此处输入标题">
            <button>发布文章</button>
        </div>
        <!-- 放置md编译器 -->
        <div id="editor">

        </div>
    </div>

    <script>
        // 初始化编辑器
        let editor = editormd("editor", {
            // 这里的尺寸必须在这里设置. 设置样式会被 editormd 自动覆盖掉. 
            width: "100%",
            // 设定编辑器高度
            height: "calc(100% - 50px)",
            // 编辑器中的初始内容
            markdown: "# 在这里写下一篇博客",
            // 指定 editor.md 依赖的插件路径
            path: "editor.md/lib/"
        });
    </script>
</body>
</html>

编辑页引入的css样式:blog_edit.css

.blog-edit-container {
    width: 1000px;
    height: calc(100% - 50px);
    margin: 0 auto;
}

.blog-edit-container .title {
    width: 100%;
    height: 50px;
    
    display: flex;
    align-items: center;
    justify-content: space-around;
}

.blog-edit-container .title input {
    width: 895px;
    height: 40px;
    border-radius: 10px;
    border: none;
    outline: none;
    font-size: 22px;
    line-height: 40px;
    padding-left: 40px;

    background-color: rgba(255,255,255,0.8);
}

.blog-edit-container .title button {
    width: 100px;
    height: 40px;
    border-radius: 10px;
    color: white;
    background-color: orange;
    border: none;
    outline: none;
}

.blog-edit-container .title button:active {
    background-color: #666;
}

#editor {
    border-radius: 10px;

    opacity: 80%;
}

2.5 前端页面引入项目

将刚刚完成的所有关于前端页面设计的文件,拷贝到webapp目录下。
在这里插入图片描述

🍅3.编写数据库操作代码

3.1 数据库设计

该步骤需要根据需求,完成数据库/数据表的创建。

根据需求中的实体,需要创建两个表——博客表(用于博客的管理)、用户表(用于用户登录的验证,以及用户的管理操作)
在这里插入图片描述

SQL代码:

-- 编写建库建表的SQL
create database if not exists blog_system;
use blog_system;

-- 创建一个博客表
drop table if exists blog;
create table blog(
    blogID int primary key auto_increment,
    title varchar(1024),
    content mediumtext,
    userId int,
    postTime datetime
);

-- 给博客表中插入一些数据,方便测试
insert into blog values(null, '这是第一篇博客', '从今天开始, 我要认真学 Java', 1, now());
insert into blog values(null, '这是第二篇博客', '从昨天开始, 我要认真学 Java', 1, now());
insert into blog values(null, '这是第三篇博客', '从前天开始, 我要认真学 Java', 1, now());
insert into blog values(null, '这是第一篇博客', '从今天开始, 我要认真学 C++', 2, now());
insert into blog values(null, '这是第二篇博客', '从昨天开始, 我要认真学 C++', 2, now());

-- 创建一个用户表
drop table if exists user;
create table user(
    userId int primary key auto_increment,
    username varchar(128) unique,
    -- 后续会使用用户名进行登录,一般用于登录的用户名都是不能重复的
    password varchar(128)
);

insert into user values (null,'zhangsan','123');
insert into user values (null,'lisi','123');

3.2 封装数据库操作

3.2.1 创建DBUtil类

创建DBUtil类,完成数据库连接操作的封装

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;

public class DBUtil {
    private static final String url="jdbc:mysql://localhost:3306/blog_system?characterEncoding=utf8&useSSL=false";
    private static final String user="root";
    private static final String password="1234";

    private volatile static DataSource dataSource=null;

    //线程安全的单例模式
    private static DataSource getDataSource() {
        if(dataSource==null) {
            synchronized (DBUtil.class) {
                if(dataSource==null) {
                    dataSource=new MysqlDataSource();
                    ((MysqlDataSource)dataSource).setURL(url);
                    ((MysqlDataSource)dataSource).setUser(user);
                    ((MysqlDataSource)dataSource).setPassword(password);
                }
            }
        }
        return dataSource;
    }

    public static Connection getConnection() throws SQLException {
        return getDataSource().getConnection();
    }

    public static void close(Connection connection, PreparedStatement statement, ResultSet resultSet) {
        if(resultSet!=null) {
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (statement != null) {
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

3.2.2 创建实体类

用实体类来表示数据库中的一条记录,此处主要创建User类Blog类
User类:

package model;
//每个 model.User 对象,期望能够表示user表中的一条记录
public class User {
    private int userId=0;
    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类:

package model;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;

//每个 model.Blog对象,对应blog表里的一条记录
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 String getPostTime() {
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return simpleDateFormat.format(postTime);
    }

    public void setPostTime(Timestamp postTime) {
        this.postTime = postTime;
    }
}

3.2.3 封装针对数据的增删改查

创建DAO类,分别对对应的表能够进行增删该查操作。

BlogDao:

package model;

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 BlogDao {
    //1.往博客表里,插入一个博客
    public void insert(Blog blog) {
        Connection connection=null;
        PreparedStatement statement=null;
        try {
            //1)和数据库建立连接
            connection=DBUtil.getConnection();
            //2)构造SQL语句
            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
            statement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            //4)关闭连接,释放资源
            DBUtil.close(connection,statement,null);
        }
    }

    //2.能够获取到博客列表中的所有博客的信息
    // (用在博客列表页,获取到的是博客正文的摘要)
    public List<Blog> selectAll() {
        List<Blog> blogs=new ArrayList<>();
        Connection connection=null;
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        try {
            connection=DBUtil.getConnection();
            String sql="select * from blog order by postTime desc";
            statement= connection.prepareStatement(sql);
            resultSet=statement.executeQuery();
            while (resultSet.next()) {
                Blog blog=new Blog();
                blog.setBlogId(resultSet.getInt("blogId"));
                blog.setTitle(resultSet.getString("title"));
                //截取摘要
                String content=resultSet.getString("content");
                if(content.length()>50) {
                    content = content.substring(0,50)+"...";
                }
                blog.setContent(content);
                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.能够根据博客id获取到指定的博客内容(用于博客详情页)
    public Blog selectOne(int blogId) {
        Connection connection=null;
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        try {
            connection=DBUtil.getConnection();
            String sql="select * from blog where blogId=?";
            statement=connection.prepareStatement(sql);
            statement.setInt(1,blogId);
            resultSet=statement.executeQuery();
            //此处我们是使用 主键 来作为查询条件的,查询结果要么是1,要么是0
            if(resultSet.next()) {
                Blog blog=new Blog();
                blog.setBlogId(resultSet.getInt("blogId"));
                blog.setTitle(resultSet.getString("title"));
                blog.setContent(resultSet.getString("content"));
                blog.setUserId(resultSet.getInt("userId"));
                blog.setPostTime(resultSet.getTimestamp("postTime"));
                return blog;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DBUtil.close(connection,statement,resultSet);
        }
        return null;
    }

    //4.从博客表中,根据博客id删除博客
    public void delete(int blogId) {
        Connection connection=null;
        PreparedStatement statement=null;
        try {
            connection=DBUtil.getConnection();
            String sql="delete from blog where blogId=?";
            statement=connection.prepareStatement(sql);
            statement.setInt(1,blogId);
            statement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DBUtil.close(connection,statement,null);
        }
    }
}

UserDao:

package model;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

//这个表用来针对用户表的基本操作
public class UserDao {
    //1.根据用户名来查找用户信息(在登录逻辑中使用)
    public User selectByName(String username) {
        Connection connection=null;
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        try {
            connection=DBUtil.getConnection();
            String sql="select * from user where username=?";
            statement=connection.prepareStatement(sql);
            statement.setString(1,username);
            resultSet=statement.executeQuery();
            //此处username使用unique约束,要么能查到一个,要么一个都查不到
            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来找用户信息
    //博客详情页,就可以根据用户id来查询作者的名字并显示
    public User selectById(int userId) {
        Connection connection=null;
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        try {
            connection=statement.getConnection();
            String sql="select * from user where userId=?";
            statement=connection.prepareStatement(sql);
            statement.setInt(1,userId);
            resultSet=statement.executeQuery();
            // 此处 username 使用 unique 约束, 要么能查到一个, 要么一个都查不到.
            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;
    }
}

未完待续(见文章二)


⭐️最后的话⭐️
总结不易,希望uu们不要吝啬你们的👍哟(^U^)ノ~YO!!如有问题,欢迎评论区批评指正😁

请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/4210.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Spring boot 静态资源处理】

默认静态资源处理 Spring Boot 默认为我们提供了静态资源处理&#xff0c;使用 WebMvcAutoConfiguration 中的配置各种属性。 建议大家使用 Spring Boot 的默认配置方式&#xff0c;如果需要特殊处理的再通过配置进行修改。 如果想要自 己 完 全 控 制 WebMVC &#xff0c;就需…

快速创建django项目管理系统流程

首先创建django project&#xff0c;虚拟环境选择我已经有的虚拟环境&#xff0c;下面是创建后的画面&#xff0c;简单的框架模板&#xff0c;需要配置改动一些代码参数&#xff0c;才能适合我自己的习惯。 这里我经常用到的习惯必须导入的是simpleui库&#xff0c;还有django的…

基于STM32-Socket-Qt 遥控小车(一代)

文章目录一、项目分析1. 项目简介2. 知识储备3. 硬件选择二、STM32部分三、QT部分四、遥控小车演示程序源码一、项目分析 1. 项目简介 本项目本质为客户端与服务器之间的通信&#xff0c;通过发送不同的指令&#xff0c;服务器和客户端进行不同的操作。 客户端&#xff1a;基…

声学特征提取

声学特征提取流程图 语谱图 语谱图的横坐标是时间&#xff0c;纵坐标是频率&#xff0c;坐标点值为语音数据能量。由于是采用二维平面表达三维信息&#xff0c;所以能量值的大小是通过颜色来表示的&#xff0c;颜色深&#xff0c;表示该点的语音能量越强。 语谱图形成过程 …

zabbix监控Linux

1. 环境配置&#xff1a; 主机名主机地址操作系统角色zabbix192.168.188.201Rocky Linux release 8.6zabbix-servernode1192.168.188.111CentOS7zabbix-agent 2. 配置zabbix客户端&#xff1a; 1>. 下载并安装zabbix客户端&#xff1a; [rootnode1 ~]# wget https://mi…

Ubuntu 22.04安装Cuda11.7和cudnn

安装显卡驱动 打开‘软件和更新。 点击附加驱动安装显卡驱动 如果已经安装显卡驱动&#xff0c;请忽略上面的步骤。 安装gcc 新安装的Ubuntu22.04 没有安装gcc&#xff0c;需要安装gcc。在终端输入gcc -version 查看有没有gcc。 执行命令 sudo apt install gcc安装CUDA …

什么是蜂窝移动网络?

文章目录前言移动网络 vs WIFI蜂窝移动通信网蜂窝网络实现移动上网通信网架构总结前言 本博客仅做学习笔记&#xff0c;如有侵权&#xff0c;联系后即刻更改 科普&#xff1a; 移动网络 vs WIFI 计网课外实验月&#xff0c;我走在宿舍一楼正数着AP有多少个&#xff0c;突然W…

待业将近一个月,晚上11点接到面试邀约电话,我却拒绝了...

前言 一位测试朋友最近一直在找工作&#xff0c;前两天刚拒绝了一个面试。那天晚上11点多&#xff0c;他接到一个HR的面试电话&#xff0c;让他第二天早上10点去公司面试。朋友和HR聊了两句&#xff0c;了解到这位HR经常加班&#xff0c;于是果断拒绝了这个面试。我还为他可惜&…

LongAdder的源码学习与理解

&#x1f468;‍&#x1f4bb;个人主页&#xff1a; 才疏学浅的木子 &#x1f647;‍♂️ 本人也在学习阶段如若发现问题&#xff0c;请告知非常感谢 &#x1f647;‍♂️ &#x1f4d2; 本文来自专栏&#xff1a; Java基础 ❤️ 支持我&#xff1a;&#x1f44d;点赞 &#x1…

Android Studio开发之使用内容组件Content获取通讯信息讲解及实战(附源码 包括添加手机联系人和发短信)

运行有问题或需要源码请点赞关注收藏后评论区留言 一、利用ContentResolver读写联系人 在实际开发中&#xff0c;普通App很少会开放数据接口给其他应用访问。内容组件能够派上用场的情况往往是App想要访问系统应用的通讯数据&#xff0c;比如查看联系人&#xff0c;短信&#…

Linux top命令的cpu使用率和内存使用率

文章目录前言一、cpu使用率1.1 top简介1.2 cpu使用率的来源二、内存使用率2.1 总内存有关的数据2.2 进程使用内存有关的数据2.3 内存使用率的来源三、 pmap参考资料前言 NAMEtop - display Linux processes一、cpu使用率 1.1 top简介 top程序提供当前运行系统的动态实时视图…

网络协议:一文搞懂Socket套接字

本篇内容包括&#xff1a;Socket 套接字的简介、Socket 套接字的分类、Java 中的 Socket 即 java.net.ServerSocket、java.net.Socket 的使用&#xff0c;以及Java 使用套接字 Scoket 编程的Demo。 一、Socket 简介 TCP&#xff08;传输控制协议&#xff09;是一种面向连接的、…

Qt编写跨平台RTSP/RTMP/HTTP视频流播放器

一、前言 很早以前就做过这款播放器的入门版本&#xff0c;最开始用的ffmpeg去解析&#xff0c;后面陆续用vlc播放器、mpv播放器来做&#xff0c;毕竟播放器提供的接口使用也很方便&#xff0c;而且功能强大&#xff0c;后面发现播放器主要的应用场景是播放视频文件&#xff0…

安装配置Anaconda3

1.装anaconda&#xff0c;就不需要单独装python了 2、 下载Anaconda Anaconda | Anaconda Distribution 3、 安装Anaconda 其他默认 4、配置Anaconda环境变量 此电脑——属性——高级系统设置——环境变量——path——编辑——新建 C:\ProgramData\Anaconda3 C:\ProgramDa…

mybatis 自动化处理 mysql 的json类型字段 终极方案

文章目录mybatis 自动化处理 mysql 的json类型字段 终极方案mysql 建表 json 字段&#xff0c;添加1条json 数据对应的java对象 JsonEntitymybatis&#xff0c;不使用 通用mapper手动自定义1个类型处理器&#xff0c;专门处理 JsonNode 和Json 的互相转化将 自定义的类型处理器…

Java笔记(十二)

文献种类&#xff1a;专题技术总结文献 开发工具与关键技术&#xff1a; IntelliJ IDEA、Java 语言 作者&#xff1a; 方建恒 年级&#xff1a; 2020 撰写时间&#xff1a; 2022 年 11 月 8 日 Java笔记(十二) 今天我给大家继续分享一下我的Java笔记&#xff0c; 我们继续来了…

使用前缀和数组解决“区间和查询“问题

本文已收录到 GitHub AndroidFamily&#xff0c;有 Android 进阶知识体系&#xff0c;欢迎 Star。技术和职场问题&#xff0c;请关注公众号 [彭旭锐] 进 Android 面试交流群。 前言 大家好&#xff0c;我是小彭。 今天分享到一种非常有趣的数据结构 —— 前缀和数组。前缀和…

每日一题|2022-11-8|1684. 统计一致字符串的数目|哈希表|Golang

1684. 统计一致字符串的数目 思路1:丢人做法 哈希记录allowed&#xff0c;暴力遍历words所有字母&#xff0c;如果有不在哈希表里的&#xff0c;计数。最后用words的长度减去 计数 就行。 func countConsistentStrings(allowed string, words []string) int {has1 : make(map[…

如何判断一段程序是否是裸机程序?

在嵌入式MCU领域&#xff0c;一般将不移植操作系统直接烧录运行的程序称为裸机程序。 一般来说&#xff0c;非易失性存储&#xff0c;时钟&#xff0c;图形显示&#xff0c;网络通讯&#xff0c;用户I/O设备…都需要硬件依赖。 基于硬件基础&#xff0c;内存管理、文件系统、…

【API部署】fastapi与nuitka打包py项目

提示&#xff1a;分两部分&#xff1a;fastapi接口调用&#xff0c;与nuitka快速打包 功能&#xff1a;作为一名算法工程师&#xff0c;训练机器学习模型只是为客户提供解决方案的一部分。 除了生成和清理数据、选择和调整算法之外&#xff0c;还需交付和部署结果&#xff0c;…