MySQL——JDBC编程

目录

·前言

一、JDBC概述

二、准备工作

1.下载MySQL的JDBC驱动包

2.把jar引入到项目中

三、JDBC编程

1.插入操作

2.查询操作

·尾声


·前言

        本篇文章主要介绍如何利用Java代码进行操作数据库,在实际开发中,绝大多数对数据库的操作我们都是通过代码进行操作,而不是在控制台手动输入SQL语句进行操作数据库,通过代码操作数据库使我们对数据库的操作更方便,使我们程序的可移植性更强,本篇文章使用的是Java的JDBC来对数据库进行操作,下面进入本篇文章的学习吧。

一、JDBC概述

        JDBC,即Java Database Connectivity,在Java中操作数据库最基础的方式就是JDBC,为什么是最基础呢,因为现在出现了很多框架技术,他们在JDBC的基础上进行了封装,使JDBC用起来更方便。

        数据库是一个“级别”,有很多数据库,如:MySQL、Oracle、Sql Server等,那么通过代码操作数据库的前提,就是数据库要提供 api ,我们调用api才能完成代码操作数据库,这里 api 全称是 Application Programming Interface应用程序编程接口,这是一个通用术语,只要是基于这个东西进行编程,就需要这个东西提供api,然而各个数据库的api并不相同,因此Java站了出来,提供了一套api标准,保证各个数据库原有的api不变,在这个基础上加个封装层,适配到JDBC这一套接口上。

二、准备工作

1.下载MySQL的JDBC驱动包

        前面说到,每个数据库都有自己本身的一套api,在这个api基础上,重新封装,封装得到的就是JDBC的驱动包,这种驱动包属于“第三方库”,并不是JDK里原生就有的,就需要通过其他途径下载下来并引入到项目中,在咱们Java的世界中,有一个东西叫做“中央仓库”,这是一群大佬,把第三方库收集起来,统一放到一个服务器上,这样就可以通过这个服务器来获取到了,后续一些新的开发者做的一些新的第三方库也会上架到这个“中央仓库”上,这个中央仓库的连接如下:

Java中心仓库 打开可能会有一点慢,这种情况很正常。

 主界面如下:

         由于我使用的MySQL版本是5.7.27,所以此处也需要使用5系列的驱动包,选择上述两个仓库的第二个仓库,当然8版本的MySQL服务器,只要去下对应版本的驱动包即可。

         下载的是一个.jar这样的文件,jar本质上是一个类似于rar这样的压缩包,里面主要是.class文件, .class文件可能会有很多,每个类都会有一个.class文件,因此Java官方给出了解决方案,把这些 .class文件打成了.jar压缩包,在我们实际使用的时候,不需要对jar进行解压缩,只要把jar导入我们自己的项目中即可,使用jar包发布Java程序,是当前既定的一种方式。

2.把jar引入到项目中

        先在编译器中新建一个项目,然后创建一个目录,把刚才下载好的jar包拷贝进去。

 

        此时,编译器就可以解析到我们导入的jar包了,下面进行JDBC编程的介绍。

三、JDBC编程

        在这里,我们利用JDBC主要介绍两个数据库相关操作,一个是插入操作,一个是查询操作,其中插入操作与修改删除操作原理是一致的,所以只介绍插入这一种。在进行JDBC相关代码编写前,先打一个预防针,如果你是初次接触,可能会感觉有些麻烦,这是正常现象,因为这里涉及到了很多新的类和新的方法,不用担心,只要多敲几次代码,熟悉之后就会感觉很简单。

1.插入操作

        在进行完上述的导入jar包的操作后,我们开始编写JDBC的代码对数据库进行插入操作。

第一步:创建数据源(数据源描述了你要操作的数据库在哪里)

        数据库是一个服务器,这个服务器可能在你这个主机上,也可能在其他主机上,为了明确这个服务器的位置,我们通常用以下方式来进行定位:

        ip地址 + 端口号 + 数据库名 

ip地址:用来描述一个主机在网络上的位置,往往是一串数字构成

端口号:一个主机上同时有很多服务器程序,使用端口号来区分不同的服务器程序

        这里我们使用的ip地址是一个特殊的ip地址“127.0.0.1”,这个ip地址也叫做“环回ip”,表示本机,因为我这里使用的数据库服务器与Java代码是在同一个主机上的,然后这里的端口号使用的是3306,(这是MySQL服务器默认的端口号)。具体代码,与详细介绍如下:

         到此,数据源就准备就绪了。

第二步:和数据库服务器建立连接

        代码如下:

Connection connection = dataSource.getConnection();

        这个代码就会和数据库服务器之间建立连接,建立好连接后,这过程可能会出错(抛出异常),比如:ip,port,数据库名,user,password……当出现错误的时候,异常信息中就会告诉我们错误原因。 

 第三步:构造SQL语句

        代码如下:

String sql = "insert into people values (1,'张三');";
//需要把String sql 转换成 语句对象
PreparedStatement statement = connection.prepareStatement(sql);

        这里的字符串sql中可以写任意的SQL语句,PreparedStatement 意思为预处理的语句,每条要执行的SQL语句是需要进行语法解析的,语法解析也是有一定开销的,通过控制台写SQL语句,都是把原始的SQL发给服务器,服务器负责解析SQL并执行,使用PreparedStatement这个类,就可以在客户端这边提前把SQL解析好,把解析后的结果发给服务器,这样服务器解析的开销就大幅度降低了,直接执行即可。

        上面构造SQL语句是将代码写“死”的,如果想要插入其他数据,就需要修改代码,重新编译,关于重新编译这种操作,代价可能会非常大,我们期望在执行过程中,可以自己输入要插入的数据,所以我们可以用以下这种写法:

Scanner scanner = new Scanner(System.in);
System.out.print("请输入id->: ");
int id = scanner.nextInt();
System.out.print("请输入姓名->: ");
String name = scanner.next();
String sql = "insert into people values (" + id + ",'" + name + "');";

        上述这种代码是通过简单的字符串拼接来构造的SQL,虽然是可以自己输入要插入的数据了,但是还有三个问题:

  1. 代码太乱,这里稍微构造错了一点,都会使SQL无法正确执行;
  2. 代码太丑(代码丑是一个很大的问题,这是一个看脸的世界);
  3. 代码存在SQL注入攻击的风险。

        这里简单介绍一下SQL注入攻击是什么,首先你要明确,永远不要预期你的用户会按照你的要求来输入内容,比如上述代码中,让输入name时,他不正常输入name,而是输入了‘);drop database .......这样的内容,此时上述代码就会把用户输入的内容构建到SQL语句中了,我们以为执行的只是一条insert,实际上已经带上了 drop database这样的操作了,当然这里只是举了个例子,真正的SQL注入攻击还是不太一样,但也差不多,为了解决上述的问题,真正的方案,是使用 PreparedStatement 提供的一个替换占位符的功能,代码如下:

Scanner scanner = new Scanner(System.in);
System.out.print("请输入id->: ");
int id = scanner.nextInt();
System.out.print("请输入姓名->: ");
String name = scanner.next();
String sql = "insert into people values (?,?)";
PreparedStatement statement = connection.prepareStatement(sql);
statement.setInt(1,id);
statement.setString(2,name);

        ? 作为占位符,占位的目的就是为了进行“替换”,通过上述代码中setInt()和setString()这个方式,也能够起到刚才动态构造SQL的效果,当然,这里是方法还有很多种,不同的方法就是对应到不同类型的参数:

第四步:把构造好的SQL发给服务器去执行

        代码如下:

int n = statement.executeUpdate();
System.out.println("n = " + n);

        在 PreparedStatement  这个类包含了以下两个方法:

         这里代码主要介绍的是插入操作,所以选择方法是executeUpdate()方法。此时,代码就会构造一个网络请求,发送给MySQL服务器(我写的这个代码就扮演了MySQL客户端的角色,相当于cmd一样),并且等待服务器响应数据,把得到的响应最终显示到控制台上。

第五步: 最后一步,释放必要的资源

        代码如下:

statement.close();
connection.close();

         内存,创建个变量之类的,也是一种重要的资源,之所以没有去手动释放,是因为JVM帮我们做了自动回收(垃圾回收,GC),然而我们在创建下面这俩对象的时候,是需要我们进行释放的,这两个对象内部都持有一些计算机重要的软/硬件资源,DataSource不需要释放,因为这里就只是单纯的保存了几个信息(URL,user,password),释放资源的顺序,和创建的顺序是相反的,我们先创建的connection,后创建的statement,所以先释放的是statement,再释放connection。

完整的代码如下:

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Scanner;public class TestJDBCInsert {public static void main(String[] args) throws SQLException {//1.创建数据源,数据源描述了你要操作的数据库在哪里DataSource dataSource = new MysqlDataSource();((MysqlDataSource) dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/bite?characterEncoding=utf8&useSSL=false");((MysqlDataSource) dataSource).setUser("root");((MysqlDataSource) dataSource).setPassword("111111");//2.和数据库服务器建立连接Connection connection = dataSource.getConnection();//3.构造SQL语句Scanner scanner = new Scanner(System.in);System.out.print("请输入id->: ");int id = scanner.nextInt();System.out.print("请输入姓名->: ");String name = scanner.next();String sql = "insert into people values (?,?)";//需要把String sql 转换成 语句对象PreparedStatement statement = connection.prepareStatement(sql);statement.setInt(1,id);statement.setString(2,name);//4.把构造好的SQL发送给服务器去执行int n = statement.executeUpdate();System.out.println("n = " + n);//5.最后一步,释放必要的资源statement.close();connection.close();}
}

运行结果如下: 

        插入,修改和删除,这些操作JDBC代码其实完全一样,唯一区别就是构造的SQL语句不一样。

2.查询操作

        查询这里的代码,和上面插入的代码就有些差别了,查询,会有一个返回的“结果集合”(临时表),查询操作中有三步:创建数据源、和数据库服务器建立连接、释放必要的资源,操作与上面查询操作一致,这里不再进行介绍,此处我们从不一样的地方开始进行介绍:

构造SQL:

        代码如下:

String sql = "select * from people";
PreparedStatement statement = connection.prepareStatement(sql);

        这里的操作和上面查询操作也比较类似,也可以使用占位符。

执行SQL:

        这里的操作与查询就截然不同了,代码如下:

//4.执行SQL
ResultSet resultSet = statement.executeQuery();
while (resultSet.next()){int id = resultSet.getInt("id");String name = resultSet.getString("name");System.out.println("id ->: " + id);System.out.println("name ->: " + name);
}

        这里ResultSet就是结果集合,代表了查询返回的临时表,利用循环,遍历ResultSet,将结果集中的数据打印出来。

完整代码如下:

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 TestJDBCSelect {public static void main(String[] args) throws SQLException {//1.构造 DataSourceDataSource dataSource = new MysqlDataSource();((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/bite?characterEncoding=utf8&useSSL=false");((MysqlDataSource)dataSource).setUser("root");((MysqlDataSource)dataSource).setPassword("111111");//2.建立连接Connection connection = dataSource.getConnection();//3.构造SQLString sql = "select * from people";PreparedStatement statement = connection.prepareStatement(sql);//4.执行SQLResultSet resultSet = statement.executeQuery();while (resultSet.next()){int id = resultSet.getInt("id");String name = resultSet.getString("name");System.out.print("id ->: " + id);System.out.println("  name ->: " + name);}//5.释放必要资源statement.close();connection.close();}
}

运行结果如下:

 

·尾声

        文章到这就要结束了,本篇文章介绍了什么是JDBC,如何下载并引用jar包,如何进行JDBC编程,当然这里针对JDBC编程只是编写了一个最简单的代码,由JDBC提供的API是有很多具体的方法的,所以在进行JDBC编程时也衍生出了不同的写法,本篇文章使用的是DataSource这一套写法,但是不只有这一种写法,这里只介绍这一种了,框架和技术都是在不断更迭的,有些东西是比较固定的,JDBC就是属于基本不变的技术,介绍JDBC也是为了在后面使用相关框架时能更好理解相关框架的底层的原理,如果读完本篇文章感觉有所收获,希望可以点赞收藏支持一下啦~~您的支持是我最大的动力,当然如果有什么问题欢迎在评论区进行留言,我们下一篇文章再见~~

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

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

相关文章

uni-app全局弹窗的实现方案

背景 为了解决uni-app 任意位置出现弹窗 解决方案 一、最初方案 受限于uni-app 调用组件需要每个页面都引入注册才可以使用,此方案繁琐,每个页面都要写侵入性比较强 二、改进方案 app端:新建一个页面进行跳转,可以实现伪弹窗…

筛选的艺术:数组元素的精确提取

新书上架~👇全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~ 目录 一、筛选的基本概念 二、筛选的实际应用案例 1. 筛选能被三整除的元素 2. 筛选小于特定值…

C++ list类

目录 0.前言 1.list介绍 1.1优势 1.2劣势 1.3容器属性 2.list使用 2.1构造函数 2.1.1默认构造函数 2.1.2填充构造函数 2.1.3范围构造函数 2.1.4拷贝构造函数 2.1.5初始化列表构造函数 2.2迭代器 2.2.1 begin() 2.2.2 end() 2.2.3 cbegin() 2.2.4 cend() 2.2.…

PyMySQL连接池

背景 在用python写后端服务时候,需要与mysql数据库进行一些数据查询或者插入更新等操作。启动服务后接口运行一切正常, 隔了第二天去看服务日志就会报错,问题如下: pymysql.err.OperationalError: (2006, "MySQL server ha…

JavaScript-内存分配

内存空间 内存分为栈和堆 栈:由操作系统自动释放存放的变量值和函数值等。简单数据类型存放在栈中 栈会由低到高先入后出 堆:存储引用类型 (对象) 对象会先将数据存放在堆里面,堆的地址放在栈里面

数字孪生智慧车站:全方位可视化管理平台

运用图扑数字孪生技术,智慧车站可视化管理平台实时模拟并监控车站运行状态,通过整合即时数据与历史数据,提供精准分析和预测。该平台支持乘客流量管理、设备运行监控、安全预警等多项功能,提高车站运营效率与安全性。直观的可视化…

这个橙子真的香!老司机徒手把玩香橙派Kunpeng Pro事后回忆录

说!你是哪个门派? 香橙,芸香科柑橘属小乔木。枝通常有粗长刺,新梢及嫩叶柄常被疏短毛。叶厚纸质,翼叶倒卵状椭圆形,顶部圆或钝。。。 咦?小李?我们不是搞IT的嘛,怎么会有…

(函数)求一元二次方程的根(C语言)

一、运行结果&#xff1b; 二、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h> # include <math.h>//声明函数&#xff1b; //判断条件等于0时&#xff1b; void zeor(double a, double b);//判断条件大于0时&#xff1b; void bigzeo…

浅谈 parallelStream和Stream 源码及其应用场景

上篇讲述了list.forEach()和list.stream().forEach() 异同点 谈到了并行流的概念&#xff0c;本篇则从源码出发&#xff0c;了解一下其原理。 一、流的初始操作流程 jdk8中 将Collection中加入了转换流的概念。 default Stream<E> stream() {return StreamSupport.str…

第十三章 进程与线程

第十三章 进程与线程 程序与进程的概念 程序&#xff1a; 英文单词为Program&#xff0c;是指一系列有序指令的集合&#xff0c;使用编程语言所编写&#xff0c;用于实现一定的功能。 进程&#xff1a; 进程则是指启动后的程序&#xff0c;系统会为进程分配内存空间。 函数式…

【PingPong_注册安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞 …

奶奶也能看懂的耦合协调度分析

不会计算&#xff1f;跟着文献学起来~ 案例数据连接&#xff08;复制链接后粘贴到浏览器中&#xff09;&#xff1a; 耦合协调度数据​spssau.com/spssaudata.html?shareDataF363000CD033FF15E557BB75B9B0D412 假如你有这样一组数据&#xff1a; 如何进行计算分析耦合协调度…

内网安全之证书模版的管理

证书模板 Certificate templates 是 CA 证书颁发机构的一个组成部分&#xff0c;是证书策略中的重要元素&#xff0c;是用于证书注册、使用和管理的一组规则和格式。当 CA 收到对证书的请求时&#xff0c;必须对该请求应用一组规则和设置&#xff0c;以执行所请求的功能&#x…

前端知识1-4:性能优化进阶

性能优化进阶 Navigation Timing API navigationStart / end 表示从上一个文档卸载结束时 > 如果没有上一个文档&#xff0c;这个值和fetchStart相等 unloadEventStart / end 标识前一个网页unload的时间点 redirectStart / end 第一个http重定向发生和结束的时间 fetch…

Hadoop3:HDFS中DataNode与NameNode的工作流程

一、DataNode中的数据情况 数据位置 /opt/module/hadoop-3.1.3/data/dfs/data/current/BP-823420375-192.168.31.102-1714395693863/current/finalized/subdir0/subdir0块信息 每个块信息&#xff0c;由两个文件保存&#xff0c;xxx.meta保存的是数据长度、校验和、时间戳&am…

芝加哥大学最新研究:GPT-4与财务预测,重塑财务分析的未来

最近&#xff0c;芝加哥大学的研究团队发表了一篇突破性的研究&#xff0c;展示了大型语言模型&#xff08;LLM&#xff09;&#xff0c;特别是 OpenAI 开发的 GPT-4&#xff0c;如何在财务报表分析领域取得了与专业分析师相匹配甚至超越的表现。这项研究不仅凸显了人工智能在高…

GDPU Java 天码行空13

&#xff08;一&#xff09;实验目的 1、掌握JAVA中与网络程序开发相关的知识点&#xff1b; 2、理解并掌握网络编程开发思想及方法&#xff1b; 3、熟悉项目开发的分包方法和依据&#xff1b; 4、实现聊天室中客服端和服务器端的实现方法&#xff1b; 5、熟悉多线程程序开发方…

Kinetix5700罗克韦尔AB伺服驱动器维修2198-D020-ERS3

Allen-Bradley罗克韦尔运动控制/伺服驱动器维修Kinetix 5700/Kinetix 6000/Kinetix 5500等系列电机驱动器/运动控制系统维修。 AB驱动器的控制接口有两种类型&#xff1a; 类型1&#xff1a;脉冲接口 类型2&#xff1a;模拟量接口 大部分小型PLC和伺服驱动器的链接方式都是开…

通过vlan实现同一网段下的网络隔离

现有两个电脑通过交换机直接连接在一起 pc1&#xff1a; pc2&#xff1a; 正常状态下是可以ping成功的 现在先进入交换机命令行界面&#xff0c;创建两个vlan <Huawei>system-view Enter system view, return user view with CtrlZ. [Huawei]vlan 10 [Huawei-vlan10…

2024年西安交通大学程序设计校赛

A题 签到题 代码如下 //A #include<iostream> #include<algorithm> #define int long long #define endl \n #define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); using namespace std; signed main() {IOSint a,b,c,d;cin>>a>>b>>c…