如何使用JDBC操作数据库,JDBC实战案例详细解读

news2025/1/18 3:19:27

1. 前言

前面 3 篇 JDBC 入门级基础文章中,我们已经探讨了什么是 JDBC,如何使用JDBC 操作数据库,JDBC API 详细解读,以及数据库连接池的基础等。文章带来的反馈还不错,今天我们使用前面学习的内容做一个实战案例训练。

  • JDBC快速入门,如何使用JDBC操作数据库?
  • 什么是数据库连接池?Druid(德鲁伊)连接池的使用详细解读
  • 什么是数据库连接池?Druid(德鲁伊)连接池的使用详细解读

image-20230124125442886

今天是初三,我们继续努力!都朝春天去,别烂在过去和梦里,要肆意妄为,要志得意满!!

前面我们说过,在 Java 代码中,执行 sql 查询语句以后返回一个 ResultSet 类的对象,并且 ResultSet 类提供了方法让我们可以操作查询结果数据,例如可以直接打印所有查询的数据。

示例:

public class JDBCDemo {

    public static void main(String[] args) throws Exception {
        //1. 注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        //2. 获取连接
        String url="jdbc:mysql://localhost:3306/blog?useSSL=false";
        String username="root";
        String ppassword="abc123";//密码
        Connection conn = DriverManager.getConnection(url,username,password);
        //3. 定义sql
        String sql="select * from student";
        //4. 获取sql执行对象
        Statement stmt = conn.createStatement();
        //5. 执行sql
        ResultSet rs = stmt.executeQuery(sql);
        //6. 处理结果
        while (rs.next()){
            int id=rs.getInt(1);
            String name=rs.getString(2);
            String gender=rs.getString(3);

            System.out.println(id);
            System.out.println(name);
            System.out.println(gender);

            System.out.println("---------");
        }
        //7. 释放资源
        rs.close();
        stmt.close();
        conn.close();
    }
}

运行结果:

image-20230124144624978

显然这样并不是我们想要的效果,数据零散不好处理。所以我们可以把每条数据封装为一个实体类的对象,每个对象对应数据库表的一条记录,并且把每个对象放到集合中存储。练习使用的数据库表:

drop table if exists student;

create table student(
	id int primary key auto_increment,
	name varchar(10),
	gender char(1)
);

insert into student(name,gender) values
('张三','男'),
('李四','女'),
('王五','男');

在 Navicat 中查看数据表:

image-20230124162412597

2. 实战案例

查询学生信息表数据,封装为 Student 类对象,并存放在 ArrayList 集合中。

思路:要解决这个问题,大概分为以下几个步骤:

  • 创建一个 Student 实体类
  • 查询数据库中的数据,并且赋值给对象的属性
  • 将对象存储到 ArrayList 集合中

第一步:创建一个Student 实体类,并定义 set() 方法,重写 Object 类中的 toString 方法,方便查看打印效果。

public class Student {
    private int id;
    private String name;
    private String gender;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                '}';
    }
}

小tips :在 idea 中使用 Alt + Inset 快捷键可以快速给类添加或重写一些方法,例如 get() ,set() ,toString() 方法等。使用 Ctrl + 鼠标左键可以快速选择多项方法。

第二步:使用 Java 代码操作数据库,查询数据库表中所有学生信息并通过 set() 方法赋值给 Student 类的对象,将对象存储到集合中。

public class JDBCDemo {

    public static void main(String[] args) throws Exception {
        //1. 注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        //2. 获取连接
        String url = "jdbc:mysql://localhost:3306/blog?useSSL=false";
        String username = "root";
        String ppassword = "abc123";//密码
        Connection conn = DriverManager.getConnection(url, username, password);
        //3. 定义sql
        String sql = "select * from student";
        //4. 获取sql执行对象
        Statement stmt = conn.createStatement();
        //5. 执行sql
        ResultSet rs = stmt.executeQuery(sql);
        //6. 处理结果
        List<Student> students = new ArrayList<>();

        while (rs.next()) {
            Student s = new Student();
            int id = rs.getInt(1);
            String name = rs.getString(2);
            String gender = rs.getString(3);

            s.setId(id);
            s.setName(name);
            s.setGender(gender);

            students.add(s);
        }
        System.out.println(students);
        //7. 释放资源
        rs.close();
        stmt.close();
        conn.close();
    }
}

运行结果:

image-20230124151820540

这样,我们的程序就达到了预期的效果,将来需要使用的数据全部封装为对象并存放在了集合中。

3. 增删改查操作练习

在数据库连接池入门篇中,我们学习了 Druid 连接池的使用,数据库连接池允许重复使用一个现有的数据库连接对象,提升了系统的响应速度和时间。下面我们使用数据库连接池来练习解决上面的问题,并且在获取 sql 执行对象时,我们使用 PreparedStatement 类,解决sql 注入的问题。

3.1 查询所有

查询所有数据,并把查询结果数据封装为对象存储在集合中,这里的数据表,Student 实体类和上面例子中相同。

public class DruidDemo {

    public static void main(String[] args) throws Exception {
        //加载配置文件
        Properties prop = new Properties();
        prop.load(new FileInputStream("jdbc-demo/src/druid.properties"));
        //获取数据库连接池对象
        DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
        //获取数据库连接对象
        Connection conn = dataSource.getConnection();
        //定义sql
        String sql = "select * from student";
        //获取 sql 执行对象
        PreparedStatement pstmt = conn.prepareStatement(sql);
        //执行 sql
        ResultSet rs = pstmt.executeQuery();
        //处理数据,将查询结果数据封装为对象存储在集合中
        List<Student> students = new ArrayList<>();
  
        while (rs.next()) {
            Student s = new Student();
            int id = rs.getInt(1);
            String name = rs.getString(2);
            String gender = rs.getString(3);

            s.setId(id);
            s.setName(name);
            s.setGender(gender);

            students.add(s);
        }
        System.out.println(students);
        //释放资源
        rs.close();
        pstmt.close();
        conn.close();
    }
}

3.2 添加数据

现在演示往数据库中添加一条记录,应用场景为用户在客户端输入一条数据时,我们需要将数据添加到数据库。示例:

public class DruidDemo {

    public static void main(String[] args) throws Exception {
        //接收到用户的数据
        int id=4;
        String name="小美";
        String gender="女";
        //加载配置文件
        Properties prop = new Properties();
        prop.load(new FileInputStream("jdbc-demo/src/druid.properties"));
        //获取数据库连接池对象
        DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
        //获取数据库连接对象
        Connection conn = dataSource.getConnection();
        //定义sql
        String sql = "insert into student values(?,?,?)";
        //获取 sql 执行对象
        PreparedStatement pstmt = conn.prepareStatement(sql);
        //设置参数
        pstmt.setInt(1,id);
        pstmt.setString(2,name);
        pstmt.setString(3,gender);
        //执行 sql
        int count = pstmt.executeUpdate();//返回受影响的行数
        //处理数据
        if(count>0){
            System.out.println("添加成功");
        }else{
            System.out.println("添加失败");
        }
        //释放资源
        pstmt.close();
        conn.close();
    }
}

image-20230124161437384

此时的数据表:

image-20230124162502370

3.3 修改数据

现在数据表中的数据,应用场景为用户在客户端修改数据,对应数据库中的数据也要完成修改。示例:

public class DruidDemo {

    public static void main(String[] args) throws Exception {
        //接收到用户的数据
        int id=1;
        String name="小王";
        String gender="女";
        //加载配置文件
        Properties prop = new Properties();
        prop.load(new FileInputStream("jdbc-demo/src/druid.properties"));
        //获取数据库连接池对象
        DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
        //获取数据库连接对象
        Connection conn = dataSource.getConnection();
        //定义sql
        String sql = "update student set name=?,gender=? where id=?";
        //获取 sql 执行对象
        PreparedStatement pstmt = conn.prepareStatement(sql);
        //设置参数
        pstmt.setString(1,name);
        pstmt.setString(2,gender);
        pstmt.setInt(3,id);
        //执行 sql
        int count = pstmt.executeUpdate();//返回受影响的行数
        //处理数据
        if(count>0){
            System.out.println("修改成功");
        }else{
            System.out.println("修改失败");
        }
        //释放资源
        pstmt.close();
        conn.close();
    }
}

image-20230124161542027

此时的数据表:

image-20230124162612729

3.4 删除数据

下面演示删除数据,用户在客户端选择删除某条数据记录时,数据库中的数据也要完成删除操作。示例:

public class DruidDemo {

    public static void main(String[] args) throws Exception {
        //接收到用户的数据
        int id=4;
        //加载配置文件
        Properties prop = new Properties();
        prop.load(new FileInputStream("jdbc-demo/src/druid.properties"));
        //获取数据库连接池对象
        DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
        //获取数据库连接对象
        Connection conn = dataSource.getConnection();
        //定义sql
        String sql = "delete from student where id=?";
        //获取 sql 执行对象
        PreparedStatement pstmt = conn.prepareStatement(sql);
        //设置参数
        pstmt.setInt(1,id);

        //执行 sql
        int count = pstmt.executeUpdate();//返回受影响的行数
        //处理数据
        if(count>0){
            System.out.println("删除成功");
        }else{
            System.out.println("删除失败");
        }
        //释放资源
        pstmt.close();
        conn.close();
    }
}

image-20230124161944039

此时的数据表:

image-20230124162647734

4. 总结

本文是 JDBC 基础教程的练习篇,学会使用 Java 代码操作数据库,完成数据库,数据表,表中数据的增删改查操作。

大家新年好,下期见。


🔖Java编程基础教程系列

Java编程进阶之路(从入门到精通) 👉 点击订阅👈

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

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

相关文章

贪心 135. 分发糖果

135. 分发糖果 难度困难1086 n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。 你需要按照以下要求&#xff0c;给这些孩子分发糖果&#xff1a; 每个孩子至少分配到 1 个糖果。相邻两个孩子评分更高的孩子会获得更多的糖果。 请你给每个孩子分发糖果&…

uboot启动流程简要版(基于armv7)

uboot启动流程&#xff08;armv7&#xff09; uboot介绍 uboot就是一段引导程序&#xff0c;在加载系统内核之前&#xff0c;完成硬件初始化&#xff0c;内存映射&#xff0c;为后续内核的引导提供一个良好的环境。 uboot是bootloader的一种&#xff0c;全称为universal boot…

二叉树基础oj练习

1.单值二叉树 题目: 力扣https://leetcode.cn/problems/univalued-binary-tree/ 思路: 单值二叉树 root和左右孩子的值相等 左子树是单值二叉树 右子树是单值二叉树 代码: /*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeN…

CSS 艺术之心形-彩虹-加载动画

CSS 艺术之心形-彩虹-加载动画&#xff08;居中抖动问题&#xff09;参考描述效果HTMLCSS重置元素的部分默认样式bodyli动画定义指定animationul居中抖动问题代码总汇参考 项目描述搜索引擎BingMDNMDN Web Docs 描述 项目描述Edge109.0.1518.61 (正式版本) (64 位) 效果 HTML…

【Vue笔记】Vue中默认插槽slot、具名插槽slot、自定义组件的v-model属性的使用

这篇文章&#xff0c;主要介绍Vue中默认插槽slot、具名插槽slot、自定义组件的v-model属性的使用。 目录 一、插槽slot介绍 1.1、默认插槽 1.2、具名插槽 &#xff08;1&#xff09;如何定义具名插槽&#xff1f;&#xff1f;&#xff1f; &#xff08;2&#xff09;如何使…

3DMAX纹理插件BerconMaps使用教程

BerconMaps是3dMax的第三方纹理插件。它添加了五个新的3dMax纹理贴图&#xff1a;噪波&#xff08;Noise&#xff09;、木纹&#xff08;Wood&#xff09;、瓷砖&#xff08;Tile&#xff09;、失真&#xff08;Distortion&#xff09;和渐变&#xff08;Gradient&#xff09;。…

linux配置samba服务

文章目录samba服务第一步&#xff1a;下载samba服务第二步&#xff1a;开启服务&#xff0c;查看服务状态第三步&#xff1a;在文件夹系统查看第四步&#xff1a;设置samba的配置文件第五步&#xff1a;再次去尝试连接linux服务共享修改smab服务的配置设置samba服务的用户名和密…

verilog实现计算器设计

该实验为用verilog编写的一个运算系统,其功能是实现4位整数的加、减、乘、除运算。运算时通过矩阵键盘输入运算类型和运算所需要的数据,然后通过内部电路处理,将计算的结果送于数码管或LCD1602显示。 工程截图如下: 本设计分为两个子模块,按键输入和数码管输出。 还有LC…

python字符串

python字符串 文章目录python字符串一、实验目的二、实验原理三、实验环境四、实验内容五、实验步骤1.字符串创建2.转义字符3.运算符4.格式化5.三引号6.内建函数总结一、实验目的 掌握字符串的用法 二、实验原理 字符串 字符串是一种序列&#xff0c;用于表示和存储文本。py…

Ubuntu16.04安装Chrome出错

安装了Ubuntu16.04之后想要装个Chrome&#xff0c;本来觉得是很简单的事情&#xff0c;下载->安装就结束了&#xff0c;结果没想到搞了好久&#xff0c;最后发现是因为自己偷懒所造成的&#xff01;因此&#xff0c;写下这篇博文做警示&#xff0c;如果其他人也碰到这样的问…

20230124使AIO-3568J开发板在Android12下横屏

20230124使AIO-3568J开发板在Android12下横屏 2023/1/24 14:05 百度搜索&#xff1a;RK3568 强制横屏 http://www.360doc.com/content/12/0121/07/29321110_1049371522.shtml RK3568 Android-HDMI旋转屏幕显示 硬件开发板&#xff1a;OK3568-C开发板&#xff08;基于国产瑞芯微…

【Leetcode每日一题】34.在排序数组中查找元素的第一个和最后一个位置|二分求下标

&#x1f331;博主简介&#xff1a;大一计科生&#xff0c;努力学习Java中!热爱写博客~预备程序媛 &#x1f4dc;所属专栏&#xff1a;LeetCode每日一题–进击大厂 ✈往期博文回顾: 【Leetcode每日一题】35.搜素插入位置|二分查找数组下标 &#x1f575;️‍♂️近期目标&#…

恶意代码分析实战 5 分析恶意Windows程序

1 Lab07-01 本次实验分析lab07-01.exe,lab07-02.exe,先来看lab07-01.exe的问题 问题 计算机重启后&#xff0c;这个程序如何确保它继续运行&#xff08;达到持久化驻留&#xff09; 首先&#xff0c;查看导入函数。 OpenSCManagerA和CreateServiceA函数暗示着这个恶意代码…

蓝队-HTTP协议的分析

文章目录应用层的协议→HTTP协议访问地址web网站的正确访问姿势请求协议https访问的密钥文件网站的部署通过https协议访问请求报文响应报文请求方法http头协议cookiesRefererUser-AgentX-Forwarded-ForHTTP 状态码HTTP content-type抓包分析HTTP抓包代理插件的下载代理第一种方…

电商项目之同一笔单多次收款成功

1 问题背景 有个收单系统&#xff08;简称S系统&#xff09;&#xff0c;作用是收单&#xff0c;相当于支付渠道&#xff0c;能够作为第三方服务对接其他支付平台。电商系统&#xff08;简称A系统&#xff09;与S系统是隔离的。A系统发起支付请求给S系统&#xff0c;S系统包装一…

Java高效率复习-坦克大战[Java基础合集]

目录 前言 该文章会从零开始制作一个坦克大战的游戏&#xff0c;该游戏使用Java的AWT和Swing作为窗体和容器&#xff0c;使用面向对象、线程等技术来丰富游戏&#xff0c;本文章相等于Java前期和中期技术的一个合集&#xff08;对于IO、网络、反射并没有涉及到&#xff09;。 …

高级Spring之Bean 生命周期

老样子&#xff0c;话不多说&#xff0c;直接上代码&#xff1a; 准备容器&#xff1a; SpringBootApplication public class A03 {public static void main(String[] args) {ConfigurableApplicationContext context SpringApplication.run(A03.class, args);context.close(…

【价格型需求响应】基于Logistic函数的负荷转移率模型需求响应研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

前端学习——CSS

文章目录1.CSS1.1什么是CSS1.2快速入门1.3.三种CSS导入方式2.选择器2.1基本选择器2.1.1标签选择器2.1.2类选择器2.1.3id选择器2.2层次选择器2.2.1后代选择器2.2.2子选择器2.2.3相邻兄弟选择器2.2.4通用选择器2.3结构伪类选择器2.4属性选择器3.美化网页元素3.1span标签3.2字体样…

swagger测试Restful API

swagger出现背景 我们构建Restful API的目的通常都是由于多终端的原因&#xff0c;这些终端会共用很多底层业务逻辑&#xff0c;因此我们会抽象出这样一层来同时服务于多个移动端或者Web前端&#xff0c;不同端由不同的团队或者小组负责&#xff0c;为了减少与其他团队平时开发…