MySQL——JDBC编程

news2024/11/19 17:43:51

目录

·前言

一、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.构造 DataSource
        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
        String sql = "select * from people";
        PreparedStatement statement = connection.prepareStatement(sql);

        //4.执行SQL
        ResultSet 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.coloradmin.cn/o/1715741.html

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

相关文章

三十五岁零基础转行成为AI大模型开发者怎么样呢?

以下从3个方面帮大家分析: 35岁转行会不会太晚?零基础学习AI大模型开发能不能学会?AI大模型开发行业前景如何,学完后能不能找到好工作? 一、35岁转行会不会太晚? 35岁正处于人生的黄金时期,拥…

【前端篇】前端开发大厂面试真题

为助力小伙伴们梳理前端知识体系,从而能够充分地做好面试准备,那么今天就来给大家分享一份前端开发的面试真题与相关知识点,其中涵盖了最新版本的八股文(包含最新的 Vue 3 面试题)、高频算法题以及大佬的面经&#xff…

相对位姿估计

相对位姿估计 示意图 理论推导 离线数据库: P的位置 P [ X , Y , Z ] T P[X,Y,Z]^{T} P[X,Y,Z]T 相机内参 k 1 k_{1} k1​ 安卓手机: 相机内参 k 2 k_{2} k2​ 两个像素点位置 : p 1 和 p 2 p_1和p_2 p1​和p2​ 公式一:…

java版本知识服务系统-高效知识付费Saaas平台的架构与功能模块设计

知识付费平台,作为我国近年来崭露头角的新型在线教育模式,正迅速改变着传统的学习方式。这种模式紧贴用户需求,将高质量的内容作为核心,借助互联网技术的力量,为用户打造了一个轻松便捷的学习环境。这些平台如同知识的…

【3.vi编辑器使用(上)】

一、vi编辑器的三种模式及切换命令 1、vi是linux中最基本的编辑器。但vi编辑器在系统管理、服务器配置工作中永远都是无可替代的。 2、vi编辑器的三种模式:命令行模式、插入模式、底行模式。 (1)命令行模式:用户在用vi编辑文件…

同时执行多个python脚本扫描,报如下错误,原因为文件越大读取到内存占用内存越多。

killed nohup python $file unable to fork process cannot allocate memory ls: error while loading shared libraries: libdl.so.2 failed to map segment from shared object cannot allocate memory python进程被系统或者某个用户通过 kill 命令强制终止了

vue3+electron+typescript 项目安装、打包、多平台踩坑记录

环境说明 这里的测试如果没有其他特别说明的,就是在win10/i7环境,64位,node 版本v16.20.2 创建项目 vite官方是直接支持创建electron项目的,所以,这里就简单很多了。我们已经不需要向开始那样自己去慢慢搭建 yarn …

【Linux】centos7编写C语言程序,补充:使用yum安装软件包组

确保已安装gcc编译器 C语言程序,一般使用gcc进行编译,需确保已安装gcc。 若没有,可以使用yum安装gcc(版本4.8.5),也可以使用SCL源安装gcc(例如:版本9.3)。 安装gcc&am…

SpringMVC: 跨线程获取requests请求对象

文章目录 引言I RequestContextHolder1.1 用法1.2 跨线程获取requests请求对象II ThreadLocal2.1 采用threadLocal存储token信息,异步线程无法获取。2.2 InheritableThreadLocal解决异步线程,无法获取token信息问题。引言 异步操作的场景: 不影响业务主流程的操作(日志的记…

外企如何有效面对日益严格的跨境数据传输法律?

在当今这个数据驱动的时代,随着全球化步伐的加快,企业跨国界的数据交流已成为常态。但随之而来的,是各国政府对跨境数据传输日益严格的规定和监管,这让众多外资企业(简称“外企”)在享受全球市场红利的同时…

Java用反射reflect来实例化对象: class.getDeclaredConstructor().newInstance()

Java用反射reflect来实例化对象: class.getDeclaredConstructor().newInstance() 从java9开始, class.newInstance()已过时, 被加上Deprecated强烈反对注解 SuppressWarnings("removal")CallerSensitiveDeprecated(since"9")public T newInstance()throws …

探索RS与AES加密技术:从经典到现代

新书上架~👇全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~ 目录 一、MD5加密技术:经典中的经典 二、非对称加密:RSA技术的魅力 RSA技…

运维开发.MySQL.范式与反范式化

运维开发 MySQL.三大范式 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite:http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.csdn.net/qq_28550263/artic…

轻松放大图片600%,Topaz Gigapixel AI图片无损清晰放大软件下载安装

Topaz Gigapixel AI 该软件拥有卓越的性能和先进的技术,能够轻松实现图像的精细放大,最多可将图像放大至原始尺寸的六倍,而无需担心图像质量的损失。 相较于传统的图像放大软件,Topaz Gigapixel AI 表现出了明显的优势。传统软件…

学习笔记——动态路由协议——OSPF(简介)

一、 OSPF简介 1、前言 由于静态路由由网络管理员手工配置,因此当网络发生变化时,静态路由需要手动调整,这制约了静态路由在现网大规模的应用。 动态路由协议因其灵活性高、可靠性好、易于扩展等特点被广泛应用于现网。在动态路由协议之中…

Python保存为json中文Unicode乱码解决json.dump()

保存为json中文Unicode乱码: 可以看到,中文字符没有乱码,只是出现了反斜杠,此时解决方法应考虑是否进行了二次序列化。 一、原因1 在dump时加入ensure_asciiFalse 即可解决,即json.dump(json_data, f, indent4, en…

VSCode小技巧,忽略不想格式化的代码行

零.格式化工具文档 1 . Black Ignoring sections功能 2 . autopep8 disabling-line-by-line功能;;–line-range选项 3 . Prettier prettier-ignore功能(例:适用于JS的// prettier-ignore,适用于CSS的/* prettier-igno…

【WEB前端2024】开源智体世界:乔布斯3D纪念馆-第29课-会员制展厅

【WEB前端2024】开源智体世界:乔布斯3D纪念馆-第29课-会员制展厅 使用dtns.network德塔世界(开源的智体世界引擎),策划和设计《乔布斯超大型的开源3D纪念馆》的系列教程。dtns.network是一款主要由JavaScript编写的智体世界引擎&…

前端Vue小兔鲜儿电商项目实战Day02

一、Pinia快速入门 此处见:Vue从入门到实战Day12-CSDN博客 二、创建项目并精细化配置 1. 创建项目 2. src目录调整 ①删除一些初始化的默认文件 清空assets、components、store、views文件夹下的内容; ②修改剩余代码内容 router/index.js import …

常用图像分类预训练模型大小及准确度比较

近年来,深度学习技术的发展使得图像分类任务变得越来越容易。预训练模型的出现更是使得图像分类任务变得更加简单和高效。然而,随着预训练模型的数量和大小的增加,我们需要了解每个模型的特点和优缺点,以便更好地选择和使用它们。…