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


    在这里插入图片描述

    请添加图片描述

    ⭐️前言⭐️

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

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

    使用到的开发工具:

    • idea
    • vscode
    • tomcat
    • postman
    • Fiddler

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

    文章源码见【GitHub仓库】.

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

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

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

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


    请添加图片描述

    请添加图片描述

    🍅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>
        
        <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>2span>
                        <span>1span>
                    div>
                div>
            div>
    
            
            <div class="right">
                
                <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="#">查看全文>>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="#">查看全文>>a>
                div>
            div>
        div>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76

    列表页引入的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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110

    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    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>2span>
                        <span>1span>
                    div>
                div>
            div>
    
            
            <div class="right">
                
                <div class="blog-content">
                    
                    <h3>我的第一篇博客h3>
                    
                    <div class="date">2022-10-22 18:17div>
                    
                    <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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97

    详情页引入的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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    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>Documenttitle>
        <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>
            
        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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    引入的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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63

    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>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    4)初始化编译器

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

    博客编辑页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>Documenttitle>
        <link rel="stylesheet" href="css/common.css">
        <link rel="stylesheet" href="css/blog_edit.css">
    
        
        <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>
            
            <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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    编辑页引入的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%;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    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');
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    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();
                }
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61

    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;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    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;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    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);
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115

    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;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65

    未完待续(见文章二)

    【跳转链接】


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

    请添加图片描述

  • 相关阅读:
    HTML5入门(1)——HTML基础
    最新NVIDIA Ada Lovelace架构 和 RTX 40系列详解
    C语言-数组
    php错误/异常/日志及常见调试和排错
    Redis常见命令
    JVM线程的几种状态
    原来Stable Diffusion是这样工作的
    Oracle关闭回收站
    直播预告 | 构建业务智联,快速拥抱财务数字化转型
    【二开】【JeecgBoot】修改分页参数
  • 原文地址:https://blog.csdn.net/qq_60856948/article/details/127710720