JDBC简介及原理和使用介绍

JDBC简介

jdbc概述

Java数据库连接,(Java Database Connectivity,简称JDBC)是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。

使用Java程序访问数据库时,Java代码并不是直接通过TCP连接去访问数据库,而是通过JDBC接口来访问,而JDBC接口则通过JDBC驱动来实现真正对数据库的访问

例如,我们在Java代码中如果要访问MySQL,那么必须编写代码操作JDBC接口。JDBC接口是Java标准库自带的,所以可以直接编译。而具体的JDBC驱动是由数据库厂商提供的。因此,访问某个具体的数据库,我们只需要引入该厂商提供的JDBC驱动,就可以通过JDBC接口来访问,这样保证了Java程序编写的是一套数据库访问代码,却可以访问各种不同的数据库 Java 应用程序 -> JDBC Interface -> JDBC Driver -> Database

 

JDBC 的常用接口和类

 

JDBC接口(API)

JDBC接口(API)包括两个层次

 

Driver接口

 

建立连接的六大步骤

  1. 加载(注册驱动)数据库
  2. 建立链接(Connection)
  3. 创建执行SQL的语句(Statement)
  4. 执行语句
  5. 处理结果集(ResultSet)
  6. 关闭数据库释放资源

 

加载与注册JDBC驱动

 

建立连接(Connection)

示例:

jdbc : 协议 mysql : 子协议 localhost:3306/databasename : 子名称

常见的数据库URL

 

PreparedStatement接口

PreparedStatement,是java.sql包中的接口,继承了Statement,并与之在两方面有所不同,包含已编译的 SQL 语句,用以执行包含动态参数的SQL查询和更新。

 

数据类型转换

java类型SQL类型
booleanBIT
byteTINYINT
shortSMALLINT
intINTEGER
longBIGINT
StringCHAR,VARCHAR,LONGVARCHAR
byte arrayBINARY , VAR BINARY
java.sql.DateDATE
java.sql.TimeTIME
java.sql.TimestampTIMESTAMP

 

数据库释放资源

数据库连接(Connection)是非常稀有的资源,用完后必须马上释放,如果Connection不能及时正确的关闭将导致系统宕机。Connection的使用原则是尽量晚创建,尽量早的释放

 

ResultSet接口

ResultSet,数据库结果集的数据表,通常通过执行查询数据库的语句生成

关于ResultSet的说明

  1. 查询需要调用Prepared Statement 的 executeQuery() 方法,查询结果是一个 ResultSet 对象

  2. 关于 ResultSet:代表结果集

    1. ResultSet: 结果集. 封装了使用 JDBC 进行查询的结果
    2. 调用 PreparedStatement 对象的 executeQuery() 可以得到结果集
    3. ResultSet 返回的实际上就是一张数据表. 有一个指针指向数据表的第一条记录的前面
  3. 可以调用 next() 方法检测下一行是否有效. 若有效该方法返回 true, 且指针下移. 相当于Iterator 对象的 hasNext() 和 next() 方法的结合体

  4. 当指针指向一行时, 可以通过调用 getXxx(int index) 或 getXxx(int columnName) 获取每一列的值

  5. ResultSet 也需要进行close关闭

 

JDBC代码使用

环境准备

准备MySQL测试库

一般常用的为MySQL5.7或者MariaDB均可

创建一个database:wow

创建一张表:wow_info

插入一些实验样例数据:

查看环境信息:

idea新建maven项目

项目信息可自定义设置,不影响代码调试测试

pom文件中增加Test、MySQLjdbc依赖

因为核心逻辑使用到jdbc的jar包,所以需要在pom中加依赖

注意:

version版本取决于使用的数据库是什么版本,例如MySQL5.7则需要去找到对应的MySQL版本依赖

所有的依赖信息清单见:

https://mvnrepository.com/artifact/mysql/mysql-connector-java

例如5.7添加了5.1.38,小版本影响不大 mysql mysql-connector-java 5.1.38

 

新建package

在包下会陆续创建各个实现类,例如 JDBCDemo

pom文件中每加一个新依赖,对应一个新xxx

接口开发使用介绍

项目整体结构:

 

简单连接数据库demo实现

包下创建一个TestJdbc类

代码示例:

执行效果如下:

但是这种简单实现,一般业务上很少使用,仅用于调试或者功能测试时使用,弊端非常明显,MySQL连接信息写死在代码中,查询功能高度耦合,非常的不灵活,基于这些原因,需要使用面向对象的思路去拆分功能来实现。

 

JDBCUtils工具类

创建JDBCUtils类,用于实现连接逻辑,交互配置文件等等

因为实际使用场景中,几乎数据库连接信息都不会写死在代码中,采用了配置文件的形式,使得灵活配置

对于配置文件的实现:

  1. 创建Properties对象
  2. 创建流
  3. 加载流
  4. 通过Properties对象读取文件中的内容
  5. 关闭资源

 

JDBCUtils工具类详解:

  1. 在JdbcUtils的静态代码static代码块中读取db.properties中的相关配置,并加载驱动
  2. 每次使用JDBC之前都要获取getConnection连接,而获取连接的代码都是固定的,因此可以提取成一个公共方法getConnection;用户代码可以通过调用JdbcUtils.getConnection()来获取连接。
  3. 使用JDBCUtils工具类的优点,在我们有大量使用mysql的数据库的情况下,可以通过更改jdbc.properties配置文件就可以灵活修改数据库的配置,而不是寻找代码然后在一次次更改代码中的数据
  4. 查询操作中可以通过调用JdbcUtils.close(rs, stmt, conn)来关闭释放资源,而更新操作中可以通过调用JdbcUtils.close(stmt, conn)来释放资源

JDBCUtils.java代码示例:

代码行:fis = new FileInputStream("jdbc.properties");

这里使用的是以项目的根目录为相对路径,直接文件名意味着在项目顶级路径下查找jdbc.properties配置文件

在项目根目录下创建jdbc.properties配置文件:

使用key=value的键值对形式来进行配置

表对象

表对象Wow.java

这里Wow表仅仅做参考,不同的表对应不同的对象,把MySQL中被操作的表理解成一个对象

后面会用到,也可以在new Wow对象,调用JDBCUtils工具类去操作Wow对象时,再创建。这里提前创建好备着

流程基本固定为:

private定义属性对应表中的字段

无参构造器

全参构造器

属性的get和set方法

重写toString方法

Wow.java代码示例:

增删改查操作示例

insert新增数据

原表:

创建DemoInsert类插入数据

代码示例:

控制台输出内容:

执行代码后验证:

最后一行:11 | lr | 龙人 | longren | 锁甲 则为新增数据,已经可以查询到

Update修改操作

创建DemoUpdate类:

代码示例:

验证:

role_pinyin列的值已经从“longren”被改为“小龙人”。

Delete删除操作

创建DemoDelete类:

代码示例:

验证:

Select查询操作

DemoSelect01:尝试查询某条数据

进行条件查询,找出id=xxx的某条数据

代码示例:

输出验证:

DemoSelect02:满足条件的多条数据

进行条件查询,查询满足条件的多条数据

代码示例:

输出验证:

DemoSelect03:获取表中所有的数据

通过调用方法获取表中所有的数据

输出验证:

JDBC事务

事务基本介绍

数据库事务:

事务处理(事务操作):保证所有事务都作为一个工作单元来执行,即使出现了故障,都不能改变这种执行方式。当在一个事务中执行多个操作时,要么所有的事务都被提交(commit),那么这些修改就永久地保存下来;要么数据库管理系统将放弃所作的所有修改,整个事务回滚(rollback)到最初状态。

JDBC 事务:

实现流程:

  1. 获取数据库连接

    • conn = JDBCUtils.getConnection();
  2. 开启事务

    • conn.setAutoCommit(false);
  3. 进行数据库操作

    xxx

  4. 若没有异常,则提交事务

    • conn.commit();
  5. 若有异常,则回滚事务

准备实验环境

在wow库中新建一张表 game_gold,插入样例数据

需求:玩家1对玩家2交易金币800,玩家1扣除金币和玩家2获取到金币必须都完成,数据最终才准确

创建GameGold类,进行事务功能测试

代码如下:

因为有System.out.println(1 / 0);代码的存在,结果预期内的抛异常

java.lang.ArithmeticException: / by zero at com.wangting.bigdata.GameGold.main(GameGold.java:27)

回到MySQL查询数据:

数据并没有发生一半执行一半没执行的情况,说明触发了事务回滚

现在将System.out.println(1 / 0);代码注释掉,再次执行GameGold类main方法

验证最终结果:

总结:

使用 ROLLBACK 语句可使数据变化失效