博客系统后端设计(二) - 封装数据库操作

news2024/11/15 18:36:53

文章目录

  • 封装数据库操作
    • 1. 创建一个 db.sql 文件
    • 2. 封装数据库的连接操作
    • 3. 创建实体类
    • 4. 封装数据库的增删改查操作
      • 4.1 创建 BlogDao 类中的方法
      • 4.2 创建 UserDao 类中的方法

封装数据库操作


这个步骤主要是把一些基本的数据库操作封装好,以后备用。

1. 创建一个 db.sql 文件




src 目录下创建一个 db.sql 文件,在这个文件里实现 建库建表 的语句。

-- 这个文件是用来写建库建表的语句的
-- if not exists 是判断当前要创建的数据是否存在
create database if not exists blog_system;

use blog_system;

-- 删除旧表,重新创建新表,删除是为了残留的数据对后续的程序有负面影响
-- if not exists 是为了判断当前的表是否存在
drop table if not exists user;
drop table if not exists blog;

-- 创建博客表
create table blog (
    blogId int primary key auto_increment,
    title varchar(128),
    content varchar(4096),
    postTime dateTime,
    userId int
);

-- 创建用户表
create table user (
    userId int primary key auto_increment,
    username varchar(20) unique, -- 要求用户名要和别人不重复
    password varchar(20)
);

2. 封装数据库的连接操作


要新建一个 DBUtil 类,在这个类当中实现以下代码。

public class DBUtil {
    private static DataSource dataSource = new MysqlDataSource();

    static {
        ((MysqlDataSource) dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/blog_system?characterEncoding=utf8&useSSL=false");
        ((MysqlDataSource) dataSource).setUser("root");
        // 你的数据库密码是什么就写什么,没有就不写
        ((MysqlDataSource) dataSource).setPassword("000000");
    }
    
    // 通过这个方法来建立连接
    public static Connection getConnection() throws SQLException {
        return dataSource.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();
            }
        }
    }
}


jdbc:mysql://127.0.0.1:3306/blog_system?characterEncoding=utf8&useSSL=false

上述语句中的 blog_system 是你的数据库名。

3. 创建实体类


这里创建的实体类实际上就是和表中的记录对应的类。

例如:
blog 表就用 Blog 类对应,Bolg 的一个对象就对应表中的一条记录。

user 表就用 User 类对应,User 的一个对象就对应表中的一条记录。

接下来新建一个 Blog 和 User 类。


(1) 编写 Blog 类中的代码

public class Blog {
    private int blogId;
    private String title;
    private String content;
    private Timestamp postTime;
    private int userId;
}




上面代码中的成员要和 blog 表中的属性一样。

在上述代码的基础上还要生成 Getter 和 Setter 方法。

右击之后,点击圈出的位置



之后再出现的界面中点击 Getter and Setter



把界面中出现的成员全选,点击 ok 即可。



完整的代码

import java.sql.Timestamp;

public class Blog {
    private int blogId;
    private String title;
    private String content;
    private Timestamp postTime;
    private int userId;

    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 Timestamp getPostTime() {
        return postTime;
    }

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

    public int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }
}



(2) 编写 User 类中的代码

User 也要注意这些成员要和 user 表中的属性一致。



其余的步骤可 (1) 一致,以下是完整的代码。

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;
    }
}

4. 封装数据库的增删改查操作


创建一个 BlogDao 和 UserDao 类,在这个类中实现一些方法来进行增删改查操作。

4.1 创建 BlogDao 类中的方法


通过这个类,封装针对 博客表 的基本操作,
此处暂时不涉及到修改操作,修改操作也可以通过删除和新增来实现。

public class BlogDao {
    // 1.新增一个博客
    public void add(Blog blog) {

    }

    // 2.根据博客 id 来查询指定博客(博客详情页)
    public Blog selectById(int blogId) {
        return null;
    }

    // 3.直接查询出数据库中所有的博客列表(博客列表页)
    public List<Blog> selectAll() {
        return null;
    }
    
    // 4.删除指定博客
    public void delete(int blogId) {
        
    }
}



点击 发布文章 的时候就会触发 add 方法新增一个博客。
博客列表页 点击 查看全文的时候就会触发 selectById 来跳转到 博客详情页
selectAll 方法可以查询出所有的博客列表,delete 方法对应的删除按钮后续在实现。


① 实现 add 方法,实现新增操作。

// 1.新增一个博客
public void add(Blog blog) {
    Connection connection = null;
    PreparedStatement statement = null;
    try {
        // 1.和数据库建立连接
        connection = DBUtil.getConnection();
        // 2.构造 sql
        String sql = "insert into blog values(null, ?, ?, ?, ?)";
        statement = connection.prepareStatement(sql);
        // 替换操作
        statement.setString(1, blog.getTitle());
        statement.setString(2, blog.getContent());
        statement.setTimestamp(3, blog.getPostTime());
        statement.setInt(4, blog.getUserId());
        // 3.执行 sql
        statement.executeUpdate();
    } catch (SQLException e) {
        e.printStackTrace();
    }finally {
        // 4.释放资源
        DBUtil.close(connection, statement, null);
    }
}


因为是一个新增操作,因此这里涉及的 sql 语句是 insert into blog values()

values 里的参数是要和之前建好的 blog 表是一致的。



因为自增主键不需要手动设置,设置为 null 让它自动分配即可,因此 第一个参数是 null。
以后的几个参数都使用 ? 这个占位符 来代替,在之后的操作中再将它替换为 blog 表中对应的属性。
因此后面几个参数都是 ?。因此构造的 sql 语句就是:insert into blog values(null, ?, ?, ?, ?)


② 实现 selectById 方法来查询指定博客

// 2.根据博客 id 来查询指定博客(博客详情页)
public Blog selectById(int blogId) {
    Connection connection = null;
    PreparedStatement statement = null;
    ResultSet resultSet = null;
    try {
        // 1.和数据库建立连接
        connection = DBUtil.getConnection();
        // 2.构造查询 sql
        String sql = "select * from blog where biogId = ?";
        statement = connection.prepareStatement(sql);
        statement.setInt(1, blogId);
        // 3.执行 sql
        resultSet = statement.executeQuery();
        // 4.遍历结果集和 由于 blogId 在 bolg 表中是唯一的(主键)
        // 此时的查询结果要么是没有查到任何数据,要么只有一条记录
        // 此处可以不使用 while,使用 if 判定即可
        if (resultSet.next()) {
            Blog blog = new Blog();
            // 把从数据库中读到信息设置到 blog 对象中
            blog.setBlogId(resultSet.getInt("blogId"));
            blog.setTitle(resultSet.getString("title"));
            blog.setContent(resultSet.getString("content"));
            blog.setPostTime(resultSet.getTimestamp("postTime"));
            blog.setUserId(resultSet.getInt("userId"));
            return blog;
        }
    } catch (SQLException throwables) {
        throwables.printStackTrace();
    }finally {
        // 4.释放资源
        DBUtil.close(connection, statement, resultSet);
    }
    return null;
}


因为是要完成指定查询,因此它的 sql 语句是 select * from blog where biogId = ?
将方法中的参数 blogId 替换到 占位符中以完成指定条件的查询。

在遍历结果集合的时候,由于 blogId 在 bolg 表中是唯一的(主键),因此查询的结果要么是没有查到任何数据,要么只有一条记录。

因此在此处可以不使用 while,使用 if 判定一次即可。


③ 实现 selectAll 方法 查询所有的博客列表

// 3.直接查询出数据库中所有的博客列表(博客列表页)
public List<Blog> selectAll() {
    Connection connection = null;
    PreparedStatement statement = null;
    ResultSet resultSet = null;
    List<Blog> blogs = new ArrayList<>();
    try {
        // 1.和数据库建立连接
        connection = DBUtil.getConnection();
        // 2.构造查询 sql
        String sql = "select * from blog";
        statement = connection.prepareStatement(sql);
        // 3.执行sql - 增删改 使用 executeUpdate 查使用 executeQuery
        resultSet = statement.executeQuery();
        // 4.遍历结果集合
        while (resultSet.next()) {
            Blog blog = new Blog();
            // 把从数据库中读到信息设置到 blog 对象中
            blog.setBlogId(resultSet.getInt("blogId"));
            blog.setTitle(resultSet.getString("title"));
            // 需要注意的是在博客列表页是不需要把整个正文全部显示出来的
            // 这里可以可以设置一个显示的篇幅
            String content = resultSet.getString("content");
            // 将篇幅的长度设置为 128
            if (content.length() >= 128) {
                // 如果篇幅大于 128 就提取 128 长度的篇幅
                // 这只是一个随便设置的篇幅长度
                // 如果最终显示出来效果不好看,还可以随时更改
                content = content.substring(0, 128) + "...";
            }
            blog.setContent(content);
            blog.setPostTime(resultSet.getTimestamp("postTime"));
            blog.setUserId(resultSet.getInt("userId"));
            // 调用 add 方法添加进去
            blogs.add(blog);
        }
    } catch (SQLException throwables) {
        throwables.printStackTrace();
    } finally {
        //  释放资源
        DBUtil.close(connection, statement, resultSet);
   }
    return blogs;
}


需要注意的是在 博客列表页 是不需要把整个正文全部显示出来的,
因此这里可以设置显示出的篇幅长度。

这里设置的为 128,这只是一个随便设置的长度,如果最终显示出来效果不好看,还可以随时更改。

这里是要将所有的博客列表查询出来,因此此处使用 while 来遍历结果集和。


④ 实现 delete 删除指定博客

 // 4.删除指定博客
 public void delete(int blogId) {
     Connection connection = null;
     PreparedStatement statement = 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 - 增删改 使用 executeUpdate 查使用 executeQuery
         statement.executeUpdate();
     } catch (SQLException throwables) {
         throwables.printStackTrace();
     } finally {
         DBUtil.close(connection, statement, null);
     }
 }


删除操作就是会通过方法里的参数 blogId 来找到要删除的博客,然后删除。
以上四个方法的大致实现方式是一致的,只是有个别的操作不同。

都要 和数据库建立连接、构造 sql 语句、执行 sql 语句、还有就是最后的释放资源
对于查询操作会有一个遍历结果集合的步骤,其余的步骤也是一致的。

以及就是在执行 sql 语句的时候,如果是 增删改 就要使用 executeUpdate
如果是 查询 操作,就要使用 executeQuery

4.2 创建 UserDao 类中的方法


通过这个类,封装针对 博客表 的基本操作。

// 1.根据 userId 来查用户信息
public User selectById(int userId) {

}

// 2.根据 username 来查用户信息
public User selectByUsername(String username) {
    
}



① 实现 selectById 方法,根据 userId 查询用户信息。

// 1.根据 userId 来查用户信息
public User selectById(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 throwables) {
        throwables.printStackTrace();
    } finally {
        // 5.释放资源
        DBUtil.close(connection, statement, resultSet);
    }
    return null;
}



② 实现 selectByUsername 方法,根据 username 查询用户信息。

这个方法与上面的方法类似,只是有两个步骤是不同的。

第一个步骤:

将上面方法构造出的 sql 语句: select * from user where userId = ?
改为了下面的 sql 语句。

// 2.构造 sql 语句
String sql = "select * from user where username = ?";


第二个步骤:

将上面方法中的 **statement.setInt(1, userId);**这条语句改为以下的这条语句。

statement.setString(1, username);


主要是将 int 类型 改为了 String 类型,以及 userId 改为了 username。

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

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

相关文章

微信小程序——wxs脚本

WXS目录 一、WXS的概述1、什么是wxs2、应用场景&#xff1a;3. wxs 与JavaScript(1)wxs 支持的数据类型:(2)wxs 不支持类似于 ES6 及以上的语法形式(3)wxs 遵循 CommonJS 规范 二 、WXS基础语法1、 内嵌 wxs 脚本2、外联的 wxs 脚本 三、WXS的特点1. 与 JavaScript 不同2. 不能…

【计算机图形学基础教程】MFC基本绘图函数2

MFC基本绘图函数 绘图工具类 CGdiObject类&#xff1a;GDI绘图工具的基类CBitmap类&#xff1a;封装了GDI画刷&#xff0c;可以选作设备上下文的当前画刷&#xff0c;用于填充图形的内部CFont类&#xff1a;封装了GDI字体&#xff0c;可以选作设备上下文的当前字体CPalette类…

一图看懂 aiohttp 模块:基于 asyncio 的异步HTTP网络库, 资料整理+笔记(大全)

本文由 大侠(AhcaoZhu)原创&#xff0c;转载请声明。 链接: https://blog.csdn.net/Ahcao2008 一图看懂 aiohttp 模块&#xff1a;基于 asyncio 的异步HTTP网络库, 资料整理笔记&#xff08;大全&#xff09; 摘要模块图类关系图模块全展开【aiohttp】统计常量模块1 aiohttp.hd…

Redis超详细入门手册教程!还不快来看看?

地址&#xff1a; RedisRedis is an open source (BSD licensed), in-memory data structure store, used as a database, cache, and message broker. Redis provides data structures …https://redis.io/ 1&#xff1a;NoSQL简介 1.1&#xff1a;数据库应用的演变历程 单…

【Matlab】基于改进的 Hausdorf 距离的DBSCAN船舶航迹聚类

【Matlab】基于改进的 Hausdorff 距离的DBSCAN船舶航迹聚类 一、模型简介1.1问题背景1.2具体内容AIS数据的预处理船舶轨迹分割船舶轨迹相似度度量船舶轨迹表达方式船舶轨迹相似度量方法改进的 Hausdorff 距离船舶轨迹聚类及轨迹提取基于改进DBSCAN算法轨迹聚类船舶典型轨迹的提…

PHP+vue基于web的小区物业管理管理系统1995a

小区物业管理系统主要是对小区物业以及居民信息进行管理&#xff0c;方便用户使用该资源的一种有效手段。能有效地对物业以及用户信息进行管理并为广大用户服务是该管理系统的基本要求&#xff0c;同时用户也可以及时了解最新的物业信息&#xff0c;方便地查询相关物业情况。基…

Django配置WebSocket:django3配置websocket步骤

一、websocket概述 简单可以认为是在web上实现socket功能&#xff0c;在服务器上与浏览器保持socket长连接。 实现websocket是通过magic string 二、环境概述 解释器&#xff1a;python3.9 django3.2 channels3.0.4 #有些时候是channels版本有问题&#xff0c;导致配置不…

linux和window下svn版本控制可视化工具

之前一直用命令行来拉取代码建立分支&#xff0c;推送代码等等 也不是不行&#xff0c;但是用久了&#xff0c;感觉很麻烦&#xff0c;后面就用了svn的版本可视化工具 linux和window下svn版本控制可视化工具 Linux环境下使用图形化界面的SVN客户端软件&#xff0c;那么RabbitVC…

触控笔和电容笔哪个好用?ipad第三方电容笔了解下

和最早出现的那一些触控笔相比&#xff0c;现在电容笔最大的不同之处在于&#xff0c;这些电容笔具备了防误触、倾斜可以随意调整笔迹粗细的特性。苹果的Pencil&#xff0c;现在的价格&#xff0c;也是非常高的。所以&#xff0c;对于预算不足的人群来说&#xff0c;平替电容笔…

SDMTSP:斑马优化算法ZOA求解单仓库多旅行商问题(提供MATLAB代码,可更改起点及旅行商个数)

一、单仓库多旅行商问题 单仓库多旅行商问题&#xff08;Single-Depot Multiple Travelling Salesman Problem, SD-MTSP&#xff09;&#xff1a;&#x1d45a;个推销员从同一座中心城市出发&#xff0c;访问其中一定数量的城市并且每座城市只能被某一个推销员访问一次&#x…

安装java配置

目录 安装JDK ​编辑 环境变量配置 3、检验环境变量配置 二、安装tomcat 验证Tomcat配置是否成功 三、安装Mysql 一、安装 二、卸载 安装JDK 点击更改将C直接给为F即可。 点击确定后进行安装&#xff0c;安装完以后会提示安装JRE; 检测是否已经安装JDK的方法 java命令通…

尚硅谷-宋红康-JVM上中下篇完整笔记-JVM上篇_内存与垃圾回收篇

前言 一.jvm及java体系结构 1. Java及JVM简介 TIOBE语言热度排行榜 https://www.tiobe.com/tiobe-index/ 世界上没有最好的编程语言&#xff0c;只有最适用于具体应用场景的编程语言。 java: 跨平台的语言JVM: 跨语言的平台 随着Java7的正式发布,Java虚拟机的设计者们通过JS…

【周末闲谈】什么是云计算?

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️周末闲谈】 ✨第一周 二进制VS三进制 ✨第二周 文心一言&#xff0c;模仿还是超越&#xff1f; ✨第二周 畅想AR 文章目录 前言什么是云计算&#xff1f;&#x1f914;&#x1f914;&#x1f914;大数…

【Linux】进程信号(中)

在上一个文章中&#xff0c;关于信号的产生&#xff0c;还有没补充完的&#xff0c;所以在这篇文章补充一下 文章目录 1.信号的产生硬件异常产生信号a/0问题验证为8号信号 野指针问题验证为11号信号 核心转储设置核心转储大小Core与Term的区别核心转储的作用 2.信号保存1. 概念…

Windows搭建C++开发环境(visual studio 2022)

开发环境的搭建 开发工具&#xff1a;vscode、visual studio 2022、visual studio 2019、2015、2010 .. 安装步骤&#xff08;以Windows下visual studio2022为例&#xff09;&#xff1a; 打开官网地址 Visual Studio 2022 IDE - 适用于软件开发人员的编程工具 (microsoft.com…

Playwright-python 自动化测试【Anaconda】环境配置

第一步&#xff1a;Anaconda的安装 安装Anaconda的好处&#xff0c;比prenv网速快&#xff0c;并且拥有独立的python环境&#xff0c;再也不用烦恼用哪个python好了。 Anaconda的下载页参见官网下载&#xff0c;Linux、Mac、Windows均支持。 https://mirrors.tuna.tsinghua.ed…

传奇人物《周兴和》书连载之68 创意改变了世界

2008年11月3日。 上海。 这一天对周兴和来说&#xff0c;是一个非常值得记忆的日子。 这一天&#xff0c;联合国“南南全球技术产权交易所” 揭牌仪式在上海举行。这个交易所是由联合国开发计划署、中国商务部和上海市三方共同组建设立的。其主要任务是帮助发展中国家&#…

.NET 发布和支持计划介绍

对于 .NET 的发布&#xff0c;大多数童鞋都知道现在每年发布一个版本&#xff0c;针对 .NET 的发布&#xff0c;最近有些更新&#xff0c;Current 版本将改为 STS 版本&#xff0c;所以写一篇文章介绍一下 每年 11 月都会发布新的 .NET 主要版本&#xff0c;使开发人员、社区和…

回归预测 | MATLAB实现MLR多元线性回归预测(多指标评价)

回归预测 | MATLAB实现MLR多元线性回归预测(多指标评价) 目录 回归预测 | MATLAB实现MLR多元线性回归预测(多指标评价)预测效果基本介绍模型描述程序设计参考资料预测效果 基本介绍 回归预测 | MATLAB实现MLR多元线性回归预测(多指标评价) 模型描述 多元线性回归(Multip…

【Docker】命令大全

文章目录 基本命令镜像相关docker imagesdocker pulldocker rmidocker rundocker build镜像发布镜像常用命令 容器相关docker psdocker logs容器常用命令 数据卷相关网络相关compose相关swarm相关 基本命令 命令说明docker version显示版本信息docker info显示系统信息&#x…