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

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;}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic String operation() {return "delete from "+tableName+" where "+condition;}
}

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

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

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

相关文章

Docker安装部署RabbitMQ(单机版)

文章目录 1.1.下载镜像1.2.安装MQ 本篇文章探讨的是单机部署 环境:Centos7 1.1.下载镜像 方式一:在线拉取 docker pull rabbitmq:3.8-management方式二:从本地加载 【1】将该镜像包上传到虚拟机的tmp目录 【2】上传到虚拟机中后,切换到存…

词令直达微信二维码如何生成关键词口令?

什么是词令直达微信二维码? 词令直达微信二维码是指商家生成指定的词令关键词口令后,可将商家的个人微信、企业微信、微信群、微信公众号、微信小程序等二维码关联到已生成的词令。用户使用词令微信小程序关键词口令直达工具,输入商家的词令…

MySQL表的增删改查---多表查询和联合查询

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好,我是xiaoxie.希望你看完之后,有不足之处请多多谅解,让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN …

冰岛人[天梯赛]

文章目录 题目描述思路AC代码 题目描述 输入样例 15 chris smithm adam smithm bob adamsson jack chrissson bill chrissson mike jacksson steve billsson tim mikesson april mikesdottir eric stevesson tracy timsdottir james ericsson patrick jacksson robin patrickss…

ORA-600 2662快速恢复之Patch scn工具---惜分飞

有客户数据库启动报ORA-600 2662错误 SQL> recover database; 完成介质恢复。 SQL> alter database open ; alter database open * 第 1 行出现错误: ORA-00603: ORACLE server session terminated by fatal error ORA-00600: internal error code, arguments: [2662], […

AI如何支持慈善组织

为各种有意义的事业提供支持,无论是努力寻找治愈疾病的方法、研发使生活更轻松的技术,还是为有需要的人提供服务,都是无比崇高的使命。提供捐款或是投入时间支持的捐助者和志愿者往往对他们选择支持的事业的目标、服务和资源分配存有诸多疑虑…

Linux系统如何使用tcpdump实时监控网络速度:方法与技巧解析

在网络管理和故障排查中,了解网络速度是一个重要的环节。而tcpdump,作为一个强大的网络数据包分析工具,不仅可以用于分析数据包的内容,还能用于实时监控网络速度。本文将介绍Linux系统如何使用tcpdump来实时监控网络速度。 首先&…

工大智信智能听诊智慧医疗的创新

智能听诊器,智慧医疗的新突破 工大智信智能听诊器是一款结合了先进技术和医疗专业知识的创新产品。它以其独特的优势,为医疗行业带来了前所未有的突破和变革。 传统听诊器依赖于医生的主观判断和经验,而工大智信智能听诊器采用了先进的传感技…

CV论文--2024.3.21

1、Chain-of-Spot: Interactive Reasoning Improves Large Vision-Language Models 中文标题:Chain-of-Spot:交互式推理改进大型视觉语言模型 简介:在视觉语言理解领域,模型在解释和推理视觉内容方面的熟练程度已经成为许多应用的…

vue学习笔记27-组件生命周期⭐

每个vue组件实例在创建时都需要经历一系列初始化步骤,比如设置好数据侦听,编译模板,挂载实列到DOM,以及在数据改变时更新DOM。在此过程中,它也会运行称为生命周期钩子的函数,让开发者有机会在特定阶段运行自…

⾃定义类型:结构体

大家好我们今天学习的是结构体,话不多说。上车吧!!! 文章目录 1. 结构体类型的声明2. 结构体变量的定义创建和初始化3. 结构成员访问操作符4. 结构体内存对⻬5. 结构体传参6. 结构体实现位段 前言 C语言中类型有很多,…

【Linux】Bash支持各种指令选项的原理:命令行参数

前言 大家好吖,欢迎来到 YY 滴Linux系列 ,热烈欢迎! 本章主要内容面向接触过Linux的老铁 主要内容含: 欢迎订阅 YY滴C专栏!更多干货持续更新!以下是传送门! YY的《C》专栏YY的《C11》专栏YY的《…

Linux常用命令之文件权限类

1.1 Linux的文件属性 在Linux里使用ll或者ls-l命令来显示一个文件的属性以及文件所属的用户和组。 以-开头:普通文件 以d开头:目录 以l开头:链接 以c开头:字符类型的设备文件(例如:鼠标、键盘,他们输入…

排序算法:归并排序(递归)

文章目录 一、归并排序的思路二、代码编写 先赞后看&#xff0c;养成习惯&#xff01;&#xff01;&#xff01;^ _ ^<3 ❤️ ❤️ ❤️ 码字不易&#xff0c;大家的支持就是我坚持下去的动力。点赞后不要忘了关注我哦&#xff01; 所属专栏:排序算法 一、归并排序的思路 单…

nRF Sniffer 在Wireshark中的使用

一、简介 使用nRF Sniffer在wireshark中抓包是经常使用的。但是每次抓包会获取到空气中所有的数据包&#xff0c;数据量非常大。而对于开发人员而言&#xff0c;只需要其中特定的信息。此时就需要掌握数据的过滤语句。 二、过滤 1.根据MAC地址进行过滤 btle.advertising_add…

2023年蓝桥杯省赛——平方差

目录 题目链接&#xff1a;1.平方差 - 蓝桥云课 (lanqiao.cn) 思路 暴力偷分 发现规律 发现蹊跷 总结 题目链接&#xff1a;1.平方差 - 蓝桥云课 (lanqiao.cn) 思路 咱就是说&#xff0c;写蓝桥杯的题目的第一件事情是什么&#xff0c;那就是不管三七二十一先暴力一下把能…

【爬虫】web自动化和接口自动化

专栏文章索引&#xff1a;爬虫 目录 一、介绍 二、推荐 1.接口自动化 2.Web自动化 一、介绍 爬虫技术一般可以分为两种类型&#xff1a;接口自动化和web自动化。下面是它们的简要介绍&#xff1a; 1.接口自动化 接口自动化技术的主要目的是通过模拟HTTP请求来实现自动化…

Docker在Mac上轻松部署RabbitMQ:从拉取镜像到创建运行带管理界面的容器全攻略

1、去官网下载docker 安装&#xff1a;把图标拉到应用程序即可 https://docs.docker.com/desktop/install/mac-install/ 2、拉取rabbitmq镜像 docker pull rabbitmq:3.8-management 3、创建并启动容器&#xff0c;同时设置环境变量以创建用户和密码 docker run -d --name m…

axure和蓝湖上查看页面的说明和上传文件

蓝湖上传文件 入口 可添加链接和文件 文件可添加 PDF&#xff0c;word&#xff0c;Excel等&#xff0c;不能添加压缩包&#xff0c;可在线预览文件内容 axure元件说明 在原型上添加说明 axure发布页 axure预览页或发布到axure的服务器上&#xff0c;查看页面说明的方法 点…

C++之模版详解

一.array与vector对比 由图发现&#xff0c;使用array数组是必须提前开好空间&#xff0c;而vector是顺序表&#xff0c;可以实现动态开辟空间 array也支持迭代器&#xff0c;如下&#xff1a; int main() {array<int, 10> arr{ 1,2,3,4,5,6,7,8,9,10 };auto it arr.be…