JDBC基础(CRUD)使用详解(mysql)

news2024/12/29 8:47:24

1. 什么是JDBC

JDBC,即Java Database Connectivity,java数据库连接.是一种用于执行SQL语句的Java API,它是 Java中的数据库连接规范.这个API由 java.sql.*,javax.sql.* 包中的一些类和接口组成,它为Java 开发人员操作数据库提供了一个标准的API,可以为多种关系数据库提供统一访问.

简要来说,JDBC作为桥梁将JAVA代码和数据库连接起来,使得程序猿可以通过操作JAVA代码做到对于数据库的一些操作.

2. JDBC的使用流程

2.1 准备数据库驱动包

在项目中创建文件夹lib,将将依赖包mysql-connector-java-5.1.47.jar复制到lib中.(ctrl+c,ctrl+v).再右键lib,点击Add as library.

配置好jar包,应该呈现下图情况,IDEA告诉我们已经识别出了jar包,可以进行下一步.

2.2 设置数据源

2.2.1 dataSource

首先,我们需要创建一个数据源:dataSource.这里我们使用的是mysql,因此实例化一个MysqlDataSource对象,但是要进行向上转型,用一个DataSource引用来接收.(导包只需要根据报错Alt+Enter导入即可)

 DataSource dataSource = new MysqlDataSource();

原因非常简单,JDBC应该可以为多种关系型数据库提供统一访问,现在可能我们使用的是mysql,如果我们后期需要使用到其他数据库,使用向上转型的方式可以极大程度地减少代码的重构成本.

接着,毕竟当下我们使用的是mysql,在使用dataSource时需要强转为MysqlDataSource类型.我们通过这个dataSource来设置三个重要的量:Url,User,PassWord.

2.2.2 Url

URL 代表着是统一资源定位符(Uniform Resource Locator)。URL 无非就是一个给定的独特资源在 Web 上的地址。理论上说,每个有效的 URL 都指向一个唯一的资源。在这里我们先给出代码:

((MysqlDataSource) dataSource).setUrl(
"jdbc:mysql://127.0.0.1:3306/lzq?characterEncoding=utf8&useSSL=false");

Url的构成:"jdbc:数据库名称://默认的网络地址:端口号/需要操作的数据库?限定的字符集&不使用SSL)

这里面最重要的是,我们需要操作的数据库的名称,如果数据库的名称不对或者不存在对应数据库,就会报错.

2.2.3 User

对于User,在我们自己本地操作默认设置为root即可.

((MysqlDataSource) dataSource).setUser("root");
2.2.4 PassWord

这里的PassWord,要与我们之前在安装mysql时设置的客户端密码相同,否则会报错.

((MysqlDataSource) dataSource).setPassword("111111");

2.3 建立连接

建立连接只需要非常简单的一行代码:

Connection connection = dataSource.getConnection();

但是这里面需要我们仔细核对Connection来自于哪个包:

我们必须选择来自java.sql下的Connection!!!否则会报错,而且错误不容易排查!!!

2.4 创建sql语句

这里我们有两种sql语句的写法:

我们以给student表(id int,name varchar(40))插入一条记录为例.

-  直接将所需的字段填入语句

Scanner scanner = new Scanner(System.in);
int id = scanner.nextInt();
String name = scanner.nextLine();
String sql = "insert into student values("+id+","+name")";

这种写法看起来有点别扭,主要是有许多符号(括号,双引号,逗号)被硬生生地分割了,同时它们还聚合在一起,看起来比较费力.

-  先将需要填入的字段用?(占位符)占位,后续再操作

String sql = "insert into student values(?,?)";

之后怎么处理呢,我们要用到接下来介绍的东西.

2.5 执行sql语句

要执行sql语句,我们需要一个statement对象,但是statement对象每次使用时都需要进行编译,十分耗费时间.因此我们就可以使用preparedStatement(预编译的statement对象),可以通过connection的prepareStatement方法得到.

PreparedStatement preparedStatement = connection.prepareStatement(sql);

有了preparedStatement对象之后,我们来解决之前的问题.preparedStatement内置了设置字段的方法

preparedStatement.setInt(1,id);
preparedStatement.setString(2,name);

我们可以根据插入字段的不同类型,调用对应的set_方法,当传入的参数类型不符合时,编译会报错.

使用时还需要注意,对应占位符的下标从1开始.

对比这两种方法:第二种方法更优.

-  增加了安全性,会确保参数的合法性.

-  在视觉上较为舒适,便于排查sql语句中可能出现的语法错误.

2.6 获得结果

接着,如果我们将CRUD的操作分为两类:

2.6.1 Create(增).Update(改).Delete(删)

对于这三种操作,都对数据库中的表做了一定的修改,我们可以使用如下语句,得到一个int类型的返回值:

int n = preparedStatement.executeUpdate();
System.out.println(n);

这里n接收的返回值,代表这个操作影响了表中的几行,如果操作的对象不存在(例如删除一条不存在的记录),这里的n就没有办法正常地打印出来.

2.6.2 Retrieve(查)

对于查询操作,并没有对数据库中的表进行修改,查询出来的只是一张临时表,可以使用如下语句:

 ResultSet resultSet = preparedStatement.executeQuery();
 while(resultSet.next()) {
     int id = resultSet.getInt("id");
     String name = resultSet.getString("name");
     System.out.println("id = "+id+", name = "+name);
 }

executeQuery这个方法得到的返回值是一个结果集,并不能直接打印出来,可以通过循环+指定字段来逐条记录打印.

2.7 收尾工作

在使用preparedStatement和connection之后,我们要进行资源的回收,即调用preparedStatement和connection的close方法.注意:通常来说,回收顺序与创建顺序相反,先创建preparedStatement对象,再创建connection对象,因此应该先回收connection对象,再回收preparedStatement对象.但dataSource对象可以反复利用,不必进行回收.

3.JDBC优缺点分析

优势:

-  Java语言访问数据库操作完全面向抽象接口编程
-  开发数据库应用不用限定在特定数据库厂商的API
-  程序的可移植性大大增强

不足:

相较于Mybatis等支持自定义数据库的框架操作比较繁琐,开发的效率大打折扣.
 

4.基于JDBC实现CRUD

将每个操作做成一个类,使用JDBC进行操作,这里直接给出代码:

程序主体:

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;
import java.util.Scanner;

public class main {
    public static void main(String[] args) throws SQLException {
        Scanner scanner = new Scanner(System.in);
        //1.设置数据源
        DataSource dataSource = new MysqlDataSource();
        ((MysqlDataSource) dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/lzq?characterEncoding=utf8&useSSL=false");
        ((MysqlDataSource) dataSource).setUser("root");
        ((MysqlDataSource) dataSource).setPassword("111111");

        //2.建立连接
        Connection connection = dataSource.getConnection();

        //3.构造sql语句
        System.out.print(
            "1.增: insert into sign1(tableName) values(sign2(id),sign3(name));\n" +
            "2.删:delete from sign1(tableName) where sign2(condition);sign3为null\n" +
            "3.改:update sign1(tableName) set sign2(update) where sign3(condition); \n" +
            "4.查:select sign1(sign) from sign2(tableName) where sign3(condition);\n"
        );

        System.out.println("choice = ");
        int choice = scanner.nextInt();

        System.out.println("sign1 = ");
        String sign1 = scanner.next();

        System.out.println("sign2 = ");
        String sign2 = scanner.next();

        System.out.println("sign3 = ");
        String sign3 = scanner.next();

        Operation[] operation = {new Create(sign1,sign2,sign3),new Delete(sign1,sign2,sign3),
                new Update(sign1,sign2,sign3),new Retrieve(sign1,sign2,sign3)};
        String sql = operation[choice-1].operation();
        //4.执行sql,把解析后的sql语句发送给服务器
        PreparedStatement preparedStatement = connection.prepareStatement(sql);

        if(choice == 4) {
            ResultSet resultSet = preparedStatement.executeQuery();
            while(resultSet.next()) {
                int id = resultSet.getInt("id");
                String name = resultSet.getString("name");
                System.out.println("id = "+id+", name = "+name);
            }
        }else {
            int n = preparedStatement.executeUpdate();
            System.out.println(n);
        }
        //5.收尾操作
        preparedStatement.close();;
        connection.close();
    }
}

Operation接口:

public interface Operation {
    String operation() ;
}

Create类:

public class Create implements Operation{
    String id;
    String name;
    String tableName;
    public Create(String tableName ,String id,String name) {
       this.tableName = tableName;
       this.id = id;
       this.name = name;
    }
    @Override
    public String operation() {
        return "insert into "+tableName+" values("+id+",'"+name+"')";
    }

}

Retrieve类:



public class Retrieve implements Operation{
    String sign;
    String condition;
    String tableName;
    public Retrieve(String sign,String tableName,String condition) {
        this.tableName = tableName;
        this.sign = sign;
        this.condition = condition;
    }
    @Override
    public String operation() {
        return "select " + sign + " from " + tableName + " where " + condition;
    }
}

Update类:



public class Update implements Operation{
    String update;
    String condition;
    String tableName;
    public Update(String tableName,String update,String condition) {
        this.tableName = tableName;
        this.update = update;
        this.condition = condition;
    }
    @Override
    public String operation() {
        return "update "+tableName+" set "+update+" where "+condition;
    }

}

Delete类:



public class Delete implements Operation{
    String empty;
    String condition;
    String tableName;
    public Delete(String tableName,String condition,String empty) {
        this.empty = empty;
        this.condition = condition;
        this.tableName = tableName;
    }
    @Override
    public String operation() {
        return "delete from "+tableName+" where "+condition;
    }
}

结合了多态的思想,基于JDBC实现了CRUD的操作.

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

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

相关文章

测试人员Bug书写规范

📋 个人简介 作者简介:大家好,我是凝小飞,软件测试领域作者支持我:点赞👍收藏⭐️留言📝 在测试人员日常工作中,关于bug的编写和定义是一个比较经常的工作,如果bug编写描…

FPGA高端项目:FPGA基于GS2971+GS2972架构的SDI视频收发+HLS多路视频融合叠加,提供1套工程源码和技术支持

目录 1、前言免责声明 2、相关方案推荐本博已有的 SDI 编解码方案本方案的SDI接收发送本方案的SDI接收图像缩放应用本方案的SDI接收纯verilog图像缩放纯verilog多路视频拼接应用本方案的SDI接收HLS图像缩放HLS多路视频拼接应用本方案的SDI接收OSD多路视频融合叠加应用本方案的S…

【Flink SQL】Flink SQL 基础概念(四):SQL 的时间属性

《Flink SQL 基础概念》系列,共包含以下 5 篇文章: Flink SQL 基础概念(一):SQL & Table 运行环境、基本概念及常用 APIFlink SQL 基础概念(二):数据类型Flink SQL 基础概念&am…

Java多线程实战-CountDownLatch模拟压测实现

🏷️个人主页:牵着猫散步的鼠鼠 🏷️系列专栏:Java全栈-专栏 🏷️本系列源码仓库:多线程并发编程学习的多个代码片段(github) 🏷️个人学习笔记,若有缺误,欢迎评论区指正…

QT UI窗口常见操作

MainWidget::MainWidget(QWidget *parent): QWidget(parent), ui(new Ui::MainWidget) {ui->setupUi(this);// 设置主窗口背景颜色QPalette plt;plt.setColor(QPalette::Window,QColor(180,220,130));this->setPalette(plt);// 禁止窗口最大化按钮setWindowFlags(windowF…

【前端Vue】Vue3+Pinia小兔鲜电商项目第1篇:认识Vue3,1. Vue3组合式API体验【附代码文档】

全套笔记资料代码移步&#xff1a; 前往gitee仓库查看 感兴趣的小伙伴可以自取哦&#xff0c;欢迎大家点赞转发~ 全套教程部分目录&#xff1a; 部分文件图片&#xff1a; 认识Vue3 1. Vue3组合式API体验 通过 Counter 案例 体验Vue3新引入的组合式API vue <script> ex…

Python爬虫与数据可视化源码免费领取

引言 作为一名在软件技术领域深耕多年的专业人士&#xff0c;我不仅在软件开发和项目部署方面积累了丰富的实践经验&#xff0c;更以卓越的技术实力获得了&#x1f3c5;30项软件著作权证书的殊荣。这些成就不仅是对我的技术专长的肯定&#xff0c;也是对我的创新精神和专业承诺…

Ubuntu18.04 中编译 TI 官方的ros驱动包中 autonomous_robotics_ros 包所存在的问题及解决方案

环境&#xff1a; 安装有 ROS 系统的 Ubuntu18.04 环境&#xff0c;并且已将 TI 官方的毫米波雷达 ROS 驱动下载到Ubuntu18.04系统中&#xff0c;如需获取此代码请点击此链接根据教程下载即可。 代码下载链接&#xff1a;TI IWR6843ISK ROS驱动程序搭建-CSDN博客 问题1&…

天软专业课 C语言 24

文章目录 基础知识进制转换字符在计算机内部的表示 程序设计的基本概念程序结构化程序设计 C程序设计的初识简单的C程序标识符、常量与变量整型数据实型数据字符型数据算数表达式赋值表达式自加自减与逗号运算符 顺序结构赋值语句数据的输出数据的输入复合语句与空语句程序实例…

Android VINF

周末搞这玩意欲仙欲死&#xff0c;没办法只有看看。VINTF是供应商接口对象&#xff08;VINTF 对象&#xff09;&#xff0c;准确的说&#xff0c;这个是属于兼容性矩阵概念。。。有点想起了以前看过的一个电影&#xff0c;异次元杀阵。。。下面是谷歌官方的图。 本质上其实就是…

Linux——开发工具yum与vim

Linux——开发工具yum与vim 文章目录 Linux——开发工具yum与vim一、Linux 软件包管理器-yum1.1 什么是软件包1.2 yum的使用 二、linux下的编辑器-vim2.1 vim的基本概念2.2 vim的基本操作插入模式下的基本命令底行模式下的基本指令 2.3 vim的配置 一、Linux 软件包管理器-yum …

C++面试宝典第35题:滑动窗口最大值

题目 给定一个数组nums,有一个大小为k的滑动窗口从数组的最左侧移动到数组的最右侧。滑动窗口每次只向右移动一位,你只可以看到在滑动窗口内的k个数字,请返回滑动窗口中的最大值。 示例: 输入:nums = [1, 3, -1, -3, 5, 3, 6, 7], k = 3 输出:[3, 3, 5, 5, 6, 7] 解析 这…

java数据结构与算法刷题-----LeetCode55. 跳跃游戏

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 文章目录 解题思路&#xff1a;时间复杂度O( n n n)&#xff0c;空间复杂度…

人人开源ueditor富文本+SpringBoot后端,配置问题解决

一、序言 首先博主第一次开始去使用到人人开源的富文本&#xff0c;在使用时几个问题解决了一天&#xff0c;如果你也存在我想你可以往下认真看&#xff0c;因为这篇博客是我刚刚解决问题时马上就写的总结&#xff0c;首先在使用过程中得到的问题如下&#xff0c;根据这些问题然…

ChatGPT国内镜像站大全

#今天在知乎看到一个问题&#xff1a;“平民不参与内测的话没有账号还有机会使用ChatGPT吗&#xff1f;” 从去年GPT大火到现在&#xff0c;关于GPT的消息铺天盖地&#xff0c;真要有心想要去用&#xff0c;途径很多&#xff0c;别的不说&#xff0c;国内GPT的镜像站到处都是&…

HDFS EXERCISES

bash: hdfs: command not found...这可能是因为hdfs命令不在系统环境变量中 whereis hadoop 找到hadoop的位置 一旦找到Hadoop安装目录&#xff0c;您需要将其 bin 目录添加到PATH环境变量中。 vi ~/.bashrc .bashrc 是一个在Linux和Unix系统中用于Bash shell的配置文件。当…

数据结构——lesson8二叉树的实现

&#x1f49e;&#x1f49e; 前言 hello hello~ &#xff0c;这里是大耳朵土土垚~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#x…

FFmpeg-aac、h264封装flv及时间转换

文章目录 时间概念流程api核心代码 时间概念 dts: 解码时间戳, 表示压缩帧的解码时间 pts: 显示时间戳, 表示将压缩帧解码后得到的原始帧的显示时间 时间基: time_base &#xff0c; 通常以ms为单位 时间戳: timestamp , 多少个时间基 真实时间&#xff1a;time_base * timest…

每日五道java面试题之mybatis篇(三)

目录&#xff1a; 第一题. MyBatis的框架架构设计是怎么样的?第二题. 为什么需要预编译?第三题. Mybatis都有哪些Executor执行器&#xff1f;它们之间的区别是什么&#xff1f;第四题. Mybatis中如何指定使用哪一种Executor执行器&#xff1f;第五题. Mybatis是否支持延迟加载…

DEiT中如何处理mask数据的?与MAE的不同

在DeiT里面&#xff0c;是通过mask的方式&#xff0c;将maskunmasked的patches输出进ViT中&#xff0c;但其实在下游任务输入的patches还是和训练时patches的数量N是一致的&#xff08;encoder所有的patches&#xff09;。 而MAE是在encoder中只encoder未被mask的patches 通过…