JDBC 学习笔记(基础)

2023-11-08

示意图

目录

创建 JDBC 应用

例子:通过本地协议纯 Java 驱动程序实现JDBC

代码具体步骤:

1.注册驱动

2.建立与数据库的连接

3.获取执行SQL语句的对象 Statement

4.定义执行 SQL 语句

5.操作结果集对象 ResultSet

6.关闭操作对象及连接对象

JDBC的主要类及常用方法

1.Class 类

2.DriverManager 类

3.Connection 类

4.Statement 类

5.ResultSet 类

SQL 注入问题

PreparedStatement 接口

JDBC连接不同的数据库


JDBC 核心类和库(java.sql)的主要类:

  • DriverMananer.:负责管理 JDBC 驱动程序,在使用JDBC驱动程序之前,必须先将驱动程序加载并注册后才可以使用,同时提供方法来建立与数据库的连接。
  • SQLException:有关数据库操作的异常。

而其主要接口如下:

  1. Connection:特定数据库的连接(会话)。在连接上下文中执行SQL语句并返回结果。
  2. PreparedStatement:表示预编译的SQL语句的对象。
  3. Statement:用于执行静态SQL语句并返回它所生成结果的对象。
  4. ResultSet:表示数据库结果集的数据表,通常通过执行查询数据库的语句生成。
  5. CallableStatement:用于执行SQL存储过程的接口。
     

创建 JDBC 应用程序

1.载入JDBC 驱动程序
首先要在应用程序中加载驱动程序 driver,使用 Class.forName() 方法加载特定的驱动程序,每种数据库管理系统的驱动程序不同,它们由数据库厂商提供。


2.定义连接URL


3.建立数据库连接
通过 DriverManager 类的 getConnection() 方法获得表示数据库连接的 Connection 类对象。

4.创建 Statement对象
获取 Connection对象以后,可以用Connection对象的方法创建一个 Statement对象的实例。

5.执行查询或更新
Statement对象可以执行 SELECT 语句的 executeQuery() 方法,可以执行 INSERT、UPDATE、DELETE 语句的 executeUpdate() 方法。


6.结果处理
利用语句对象对数据库操作返回的结果进行处理,ResultSet 包含一些用来从结果集中获取数据并保存到 Java 变量中的方法,主要包括 next() 方法:用于移动结果集游标;逐行处理结果集 getString()、getInt()、getDate()、getDouble() 等方法,用于将数据库中的数据类型转换为Java语言的数据类型。


7.关闭使用完的对象
使用与数据库相关的对象非常耗内存,因此,在数据库访问后要关闭与数据库的连接,同时还应该关闭ResultSet、 Statement和 Connection 等对象。可以使用每个对象自己的close()方法完成。

例子:通过本地协议纯 Java 驱动程序实现JDBC

以MySQL为例,我们先下载一个MySQL数据库驱动jar包。

前提:创建一个Java项目,在项目中创建一个名为libs的目录(为了方便管理,就把jar包文件放入此目录下),然后在src下建一个包,包下再建一个类,比如:

(注意!之后选择libs右键——>Add as Library,以导入识别jar包)

代码具体步骤:

  1. 导入jar包(package)
  2. 注册驱动
  3. 获取数据库的连接对象
  4. 获取执行SQL语句的对象
  5. 定义、执行SQL语句并接收返回结果
  6. 处理结果
  7. 释放资源

以 MySQL 为例来说明 JDBC 的步骤:

1.注册驱动

Class类提供的加载驱动程序的方法:

public static Class forName(String className) throws ClassNotFoundException

(加载驱动程序时会抛出 ClassNotFoundException 的 SQLException 异常)

例如加载 MySQL 驱动程序的语句描述:

Class.forName("com.mysql.jdbc.Driver");
2.建立与数据库的连接

DriverManager 类提供了 getConnection() 方法用于获取指定数据库的连接对象:

public static Connection getConnection (String url, String userName, String password) throws SQLException

MySQL 数据库的 url 格式为:

jdbc:mysql://[host1:port1],[host2:port2].../[database][?参数名1][=参数值1][&参数名2][=参数值2]...

例子:定义本地默认连接 url

1.
String url = " jdbc:mysql://localhost:3306/eshop?useUnicode=true&characterEncoding=UTF-8";
2.
String url2 = "jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&userSSL=false&serverTimezone=GMT%2B8";

拿到数据库的连接:

Connection conn = DriverManager.getConnection(url,"root","password")
3.获取执行SQL语句的对象 Statement

Connection 接口中提供了获取 Statement 对象的方法:

Statement createStatement() throws SQLException

通过调用重载的 createStatement() 方法指定参数,设置数据库操作结果的相关属性。比如获取 Statement 对象(用来执行 SQL 语句,并接收返回结果)

Statement stmt = conn.createStatement();
4.定义执行 SQL 语句

需通过可以发送 SQL 命令的 Statement 对象 st。比如调用对象 st 的 executeQuery() 方法发送 SQL 查询命令。查询的主要方法如下:

1.
boolean execute(String sql) throws SQLException
2.
ResultSet executeQuery(String sql) throws SQLException
3.
int executeUpdate(String sql) throws SQLException
5.操作结果集对象 ResultSet

ResultSet 接口提供可对结果集进行操作的主要方法如下:

1.
boolean next() throws SQLException
//移动结果集操作指针
2.
XXX getXXX(String columnName) throws SQLException
//指定数据类型,根据传入列的名字获取指定列的值
3.
XXX getXXX(1) throws SQLException
//指定数据类型,根据传入列的编号获取指定列的值

SQL 类型和 Java 数据类型的对应关系
SQL 类型 Java 类型
CHAR String
VARCHAR String
LONGVARCHAR String
NUMERIC java.math.BigDecimal
DECIMAL java.math.BigDecimal
BIT boolean
TINYINT byte
SMALLINT short
INTEGER int
BIGINT long
REAL flout
FLOAT double
DOUBLE double
BINARY byte[]
VARBINARY byte[]
LONGVARBINARY byte[]
DATE java.sql.Date
TIME java.sql.Time
TIMESTAMP java.sql.Timestamp
6.关闭操作对象及连接对象

数据库操作完成后,就可调用接口 ResultSet、Statement、Connection 中的关闭方法了,立即释放数据库和JDBC相关资源。如下所示:

void close() throws SQLException

关闭顺序如下:

  1. 关闭 ResultSet 对象
  2. 关闭 Statement 对象
  3. 关闭 Connection 对象

JDBC的主要类及常用方法

JDBC 的一系列步骤都由 JDBC API 中一组类的方法实现,如下:

1.Class 类

java.lang.Class,Java程序运行时会自动创建程序中的每个类的Class对象,通过Class类的方法可以得到程序中每个类的信息。

格式 效能 补充/例子
public static Class forName(String className) 根据“限定全类名”来获取相应的Class对象

Class.forName(sun.jdbc.odbc.JdbcOdbcDriver)加载指定名称(JDBC-ODBC桥)的驱动程序

public String getName() 根据对象,返回类名 不怎么常用

2.DriverManager 类

DriverManager(驱动程序管理器)类维护着用户程序与数据库驱动程序之间的连接。它实现了驱动程序的装载、创建连接数据库系统的 Connection 类对象。

格式 效能 补充
public static Connection getConnection(String url, String user, String password) 根据url(数据库JDBC-ODBC桥名称)、数据库用户名、密码获取一个数据库的连接对象 静态成员方法

3.Connection 类

Connection 连接类用于管理指定数据库的连接。

格式 效能
createStatement() 创建 Statement 类的实例
prepareSatement() 创建 PreparedStatement 类的实例
close() 关闭 Connection 对象

4.Statement 类

Statement 数据库操作类提供执行数据库操作的方法,如更新、查询数据库记录等。例子如下:

Statement stmt = conn.createStatement();

重要的成员方法如下:

格式 效能
ResultSet executeQuery(String sql) 用来执行查询语句,并返回一个ResultSet对象
int executeUpdate(String sql) 用来执行“增删改”语句,返回值代表影响的行数
boolean execute(String sql) 用来执行任意语句,返回代表是否返回了ResultSet
close() 关闭 Statement 对象

5.ResultSet 类

ResultSet 结果集类提供对查询结果集进行处理的方法,如:

ResultSet rs = stmt.executeQuery("select * from users");

ResultSet 对象维持着一个指向表格的行的指针,开始运行时指向表格的起始位置(第一行之前:0行)

格式 效能
next() 光标(指针)移到下一条记录,返回一个boolean值
privious() 光标(指针)移到上一条记录

getXXX("字段名")或

getXXX(int i)等

获取指定类型的字段值。
close() 关闭 ResultSet 对象

ResultSet 接口提供的 getXXX 方法
方法 Java返回类型
getASCIIStream java.io.InputStream
getBigDecimal java.math.BigDecimal
getBinaryStream java.io.InputStream
getBoolean boolean
getByte byte
getBytes byte[]
getDate java.sql.Date
getDouble double
getFloat float
getInt int
getLong long
getObject Object
getShort short
getString java.lang.String
getTime java.sql.Time
getTimestamp java.sql.Timestamp
getUnicodeStream java.io.InputStream of Unicode characters

SQL 注入问题

在使用 Statement 对象查询数据库时,由于定义的 SQL 语句是拼接的,就有可能出现 SQL 注入问题。所谓SQL注入就是把SQL命令插入查询字符串中,最终达到欺骗服务器执行恶意的SQL命令的目的。

PreparedStatement 接口

此接口表示预编译的 SQL 语句的对象,是为了解决 Statement 静态拼接所产生的 SQL 注入问题。PreparedStatement 接口是 Statement 接口的子接口,其允许使用不同的参数多次执行相同的SQL语句。

Connection 接口提供创建 PreparedStatement 接口对象的方法,可指定SQL语句

PreparedStatement preparedStatement(String sql) throws SQLException

虽然 PreparedStatement 接口继承了 Statement 接口,但 PreparedStatement 语句中包含了警告预编译的 SQL 语句,因此其效率更高。

PreparedStatement Statement
能写啥? 带参数的SQL语句 简单的SQL语句
比较 可动态设置参数、增加了预编译功能、提高了执行速度 -

而且 PreparedStatement 的语句可以包含多个用“?”代替的字段,设置时按要素出现顺序传参即可。如:

Connection conn = DBUtil.getConnection();
PreparedStatement ps = null;
ResultSet rs = null;
String sql = "SELECT * FROM users WHERE NAME=? AND PWD=?";
ps = conn.preparedStatement(sql);
ps.setString(1, name);
ps.setString(2, pwd);
rs = ps.executeQuery();

格式 效能
ResultSet executeQuery() 执行SQL查询并获取ResultSet对象
int executeUpdate() 执行“增删改”操作,返回值是执行该操作所影响的行数
boolean execute() 执行任意语句,返回代表是否返回了ResultSet

PreparedStatement 接口 setXXX 方法
方法 SQL类型
setASClIStream 产生一个 LONGVARCHAR 型的 ASCII 流
setBigDecimal NUMERIC
setBinaryStream LONGVARBINARY
setBoolean BIT
setByte TINYINT
setBytes

VARBINARY 或 LONGVARBINARY

(大小取决于对 VARBINARY 的限制)

setDate DATE
setDouble DOUBLE
setFloat FLOAT
setInt INTEGER
setLong BIGINT
setNull NULL
setObject 在发送之前,转换为目标 SQL 类型的给定对象
setShort SMALLINT
setString

VARCHAR 或LONGVARCHAR

(大小取决于驱动程序对 VARCHAR 的限制)

setTime TIME
setTimestamp TIMESTAMP

JDBC连接不同的数据库

JDBC 是一套数据库连接的标准,许多数据库连接的区别如下:

  1. 数据库驱动路径名不同
  2. 连接数据库的 url 不同

数据库连接池(连接对象的集合)

数据库连接池的特点:

  • 是个容器,负责分配、管理数据库连接
  • 允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个连接
  • 释放空闲时间超过最大空闲时间的数据库连接,来避免因为没有释放数据库连接而引起的数据库连接遗漏

总结:(我觉得有点像 DHCP 服务器)

  1. 资源重用
  2. 提升系统响应速度
  3. 避免数据库连接遗漏

数据库连接池实现

标准接口:DateSource(而不是以往的 JavaManager)

  • 官方(Sun)提供的数据库连接池标准接口,由第三方组织实现此接口
  • 其功能就是获取连接

常见的数据库连接池:DBCP、C3P0、Druid

我们以Druid(德鲁伊)为例,其是阿里巴巴开源的数据库连接池项目(功能强大、性能优秀)。

注意SQL命令、参数设置、处理结果

略,有点事以后补充!

DBUtils我觉得还算是一个挺好用组件,在学习Hibernate,Mybatis这些ORM框架之前,可以学着用用。可以极大简化我们的JDBC的代码,用起来也很方便。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JDBC 学习笔记(基础) 的相关文章

  • Android:java.lang.OutOfMemoryError:

    我在 Android 上开发了一个使用大量图像的应用程序 可绘制文件夹中有很多图像 比如说超过 100 张 我正在开发图像动画应用程序 我使用 imageview 来显示 GIF 图像 我使用了将 gif 图像分割成多个 PNG 格式图像的
  • 简单 XML 框架:ElementMap 中的对象具有“类似内联”的行为

    我正在尝试在 Android 上序列化自定义对象的 Hashmap 以获得如下 xml
  • 类型已知,但方法指的是缺失类型

    我对 java 和 Eclipse 不太有经验 但遇到以下问题 我正在写类似的东西 Point3D myPoint myClass myMethod arg 我收到错误 方法 myMethod myType arg 引用缺失的类型 Poin
  • JAXB 继承冲突 - 重新注释子类

    目前我的项目中有这样的环境 public abstract class Foo private List
  • Apache Thrift Java-Javascript 通信

    我正在编写一个基于 Apache Thrift 的 Java 服务器 它将从 Javascript 客户端接收数据 我已经完成了 Java 服务器 但问题是我可以获得 Javascript 客户端的工作示例 我无法找到一个好的示例 构建文档
  • 在 Eclipse 3.5 上安装旧版 TestNG 插件时出现问题

    我正在尝试在 eclipse 3 5 上安装 TestNG 5 11 并获得以下信息 eclipse buildId unknown java version 1 6 0 19 java vendor Sun Microsystems In
  • 获取Android库中的上下文

    我正在编写一个 Android 应用程序 它的一些功能封装在内部库中 但是 要使此功能发挥作用 库需要一个应用程序上下文的实例 为图书馆提供这种上下文的最佳方式是什么 我看到了一些选择 但没有一个有吸引力 Have my library c
  • Selenium 和 TestNG 同时使用“dependsOn”和“priority =”问题

    我正在努力在 GUI 自动化测试中实现更好的工作流程控制 我首先从dependsOn开始 但很快发现缺点是如果一个测试失败 则套件的整个其余部分都不会运行 所以我改用 priority 但看到了意外的行为 一个例子 Test priorit
  • 使用 kryo 注册课程的策略

    我最近发现了 kryonet 库 它非常棒并且非常适合我的需求 然而 我遇到的一个问题是制定一种好的策略来注册所有可以转移的类 我知道我可以在每个对象中编写一个静态方法 该方法将返回它使用的所有类的列表 但我真的不想这样做 为了我自己的时间
  • 绘制平滑曲线

    我想创建更平滑的曲线 而不仅仅是线角 这是我现在画的图 这是我的代码 case FREEHAND float pts float ptk ptk new float 2 imageMatrix invert inv if mCurrentS
  • 如何自动转换十六进制代码以将其用作 Java 中的 byte[]?

    我这里有很多十六进制代码 我想将它们放入 Java 中 而不需要向每个实体附加 0x 喜欢 0102FFAB 和我必须执行以下操作 byte test 0x01 0x02 0xFF 0xAB 我有很多很长的十六进制代码 有什么办法可以自动做
  • for循环中更新JLabel的问题

    我的程序的想法是从之前在其他 JFrame 中保存的列表中选择一个名称 我想在标签中一个接一个地打印所有名称 它们之间有很小的延迟 然后停在其中一个名称上 问题是lbl setText String 如果有多个则不起作用setText co
  • 如何在Netbeans中设置JList的ListModel?

    我在 Netbeans IDE 的帮助下设计了一个 Swing GUI 该 GUI 包含一个 JList 默认情况下 它使用 QAbstractListModel 将其作为 JList 构造函数中的参数传递以创建该 JList 我想在 Ne
  • 在Java中如何将字节数组转换为十六进制?

    我有一个字节数组 我希望该数组的每个字节字符串转换为其相应的十六进制值 Java中有没有将字节数组转换为十六进制的函数 byte bytes 1 0 1 2 3 StringBuilder sb new StringBuilder for
  • Time.valueOf 方法返回错误值

    我使用 Time valueOf 方法将字符串 09 00 00 转换为 Time 对象 如下所示 Time valueOf LocalTime parse 09 00 00 当我调用 getTime 来显示我得到的值时 28800000
  • 使用 Guava Ordering 对对象列表进行多条件排序

    我有一个类无法实现可比较 但需要根据 2 个字段进行排序 我怎样才能用番石榴实现这一目标 假设班级是 class X String stringValue java util Date dateValue 我有一个清单 List
  • 无法连接到docker中的elasticsearch容器

    我正在尝试使用 docker 的官方 elasticsearch 镜像 我遵循了本指南 https www elastic co guide en elasticsearch reference current docker html但是当
  • java.lang.UnsatisfiedLinkError - android studio gradle 中的 NDK?

    文件夹结构 app main java jni Android mk Application mk hello jni c res 在构建 gradle apply plugin com android application androi
  • 在java中执行匿名pl/sql块并获取结果集

    我想执行匿名 PL SQL 并需要获取结果集对象 我得到了可以通过在 PL SQL 块内使用游标来完成的代码 但 PL SQL 块本身将以文本形式来自数据库 所以我无法编辑该 PL SQL 块 并且它只会返回两个值 其列名始终相同 它将返回
  • 检查按钮是否可用?如果没有,请等待 5 秒钟,然后再次检查?

    基本上我想看看此刻是否可以单击按钮 如果没有我想再试一次 所以我需要某种 goto 函数来返回到代码的前一行 尽管我怀疑我写得非常糟糕 但它本来可以做得更容易 try driver findElement By xpath button i

随机推荐

  • 汽配企业如何把MES管理系统的价值利用到最大化

    随着信息技术的快速发展 越来越多的汽配企业开始引入MES生产管理系统 以提高生产效率 优化资源利用和提升产品质量 然而 要想实现MES系统的最大化价值 汽配企业需要从以下几个方面入手 首先 汽配企业应该充分了解MES系统的功能和特点 并根据
  • git笔记

    git笔记 第一次使用配置 git config global user email you example com git config global user name Your Name 生成ssh key ssh keygen t
  • Matplotlib Intermediate Styling with cycler

    Styling with cycler 自定义属性循环设置的演示以控制多个 line 的图的颜色和其他样式属性 这个例子演示了两种不同的 API 设置 rc 参数 指定默认属性循环 这会影响所有随后的 axes 不会影响已经创建的 axes
  • 论文笔记:Learning Transferable Visual Models From Natural Language Supervision(CLIP)

    1 Intro 目前最先进的CV模型 大部分是现有一个定义好的类别的集合 然后模型通过预测这些提前定义好的类别 从而完成模型的训练 这些提前定义好的类别会大大简化问题本身 但采用了这种有限制性的监督信号 也大大限制了模型的泛化性 尤其是识别
  • 详解Python的切片(Slice)

    先看例子 array 0 1 2 3 4 5 print array print array 1 print array 2 print array 4 1 print array 4 5 print array 10 3 结果是 0 1
  • Ubuntu 12.04 搭建Android开发环境

    Ubuntu 12 04 搭建Android开发环境 2013 7 29 Linux环境下搭建Android开发环境 大部分开发人员可能都在Windows下做开发 可能是感觉在Windows下比较方便 我感觉也是 不过作为一名开发者仅局限在
  • R语言内置颜色色板+生成代码

    R语言内置颜色参照色板 日常使用中 想用一些R语言内置颜色 网上始终没有找到相对齐全的内置色板 于是自己写了一个 R语言内置颜色总共657种 文中代码共生成560种颜色 去掉了部分Grey渐变色 代码如下 RColors 568 col l
  • spring文件上传大小限制,Springboot大于一1G文件上传

    前言 一 SpringMVC简介 1 1 SpringMVC引言 为了使Spring有可插入的MVC架构 SpringFrameWork在Spring基础上开发SpringMVC框架 从而在使用Spring进行WEB开发时可以选择使用Spr
  • 宋浩线性代数笔记(六)二次型

    本章的内容比较少且均通俗易懂 较第三章和第五章容易许多 之后还有针对于数学一的第7更 数二数三的选手已经可以完结撒花
  • Dagger2 设计模式之构建者模式

    Dagger 中的设计模式分析 Builder 模式 DaggerFatherComponent 对象的构建 Dagger 中对 DaggerFatherComponent 对象的构建可以拆分成三部分 一 构建使用 Inject 注解构造函
  • ARMV8体系结构简介:AArch64应用级体系结构之Atomicity

    1 前言 Atomicity是内存访问的一个属性 描述为原子性访问 包括single copy atomicity和multi copy atomicity 2 基本概念 observer 可以发起对memory read write访问的
  • 经典机器学习算法之SVM算法

    本篇文章旨在让完全不懂的小伙伴对该算法有一个初步认识与理解 只适用于小白 如果想深入了解 可以参考本文的参考文章 文章目录 一 算法介绍 1 SVM简介 2 支持向量 二 算法分析 1 线性可分情况 线性可分的理解 找到最优的超平面 2 线
  • 【第四阶段】kotlin语言中的数组类型

    1 kotlin语言中的数组类型 类型 定义 IntArray intArrayOf DoubleArray doubleArrayOf LongArray longArrayOf ShortArray shortArrayOf ByteA
  • 模拟实现内存动态分区分配与回收(完整代码)

    memory类 package memory import java util LinkedList import java util Scanner public class memory private int size 内存大小 pr
  • vscode开发python项目使用flake8、yapf工具格式化pip8编码规范

    前言 使用flake8 yapf工具工具去格式化py文件 有助于生成满足pep8规范 使用快捷键即可完成 提高开发效率 安装配置 1 win10下安装flake8 yapf pip install flake8 pip install ya
  • python 实现批量抠图

    系统 windows10 语言 python 3 6 编辑器 pycharm 安装库 1 paddlepaddle python m pip install paddlepaddle i https mirror baidu com pyp
  • ES Module 和 Commonjs 的区别

    只有静态引入 tree shaking才能够知道哪些引入哪些不引入 动态引入 要引入的代码都没有执行 所以不会引入 所以tree shaking不知道哪些引入哪些不引入
  • 只利用 phpstudy 如何运行PHP文件 超详细教程

    1 先编写好PHP代码 我这里用记事本简单写了一个 2 打开phpstudy 检查下有没有下载PHP环境 启动Apache 3 把编写好的PHP文件复制到phpstudy目录下的www文件中 注 phpstudy可以通过 网站 管理 打开根
  • Vue常见简写 “:“ , “@“ , “#“ :帮助刚入行的伙伴快速看懂代码

    提示 本文仅仅是对Vue中比较常见的简写进行总结 适合刚入行有时看不懂代码的朋友 目录 文章目录 前言 一 是什么 1 是什么意思 2 怎么使用 二 是什么 1 是什么意思 2 怎么使用 三 是什么 1 是什么意思 2 怎么使用 总结 前言
  • JDBC 学习笔记(基础)

    示意图 目录 创建 JDBC 应用 例子 通过本地协议纯 Java 驱动程序实现JDBC 代码具体步骤 1 注册驱动 2 建立与数据库的连接 3 获取执行SQL语句的对象 Statement 4 定义执行 SQL 语句 5 操作结果集对象