一、JDBC简介
JDBC API 允许用户访问任何形式的表格数据,尤其是存储在关系数据库中的数据。
执行流程:
- 连接数据源,如:数据库。
- 为数据库传递查询和更新指令。
- 处理数据库响应并返回的结果。
二、JDBC代码实现
驱动获取
我这里使用的是MySql数据库,所以,我这里使用Mysql的驱动包。这里使用Maven安装驱动包(我的Mysql是5.0的,所以驱动也安这个版本的,不同人的不一样)。
<dependencies>
<!--mysql驱动包-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.35</version>
</dependency>
</dependencies>
刷新下,在这里看到这个就算安装成功了:
简单实现
驱动有了,接下来就是直接连接数据库来试试了。主要步骤是分为:
- 加载驱动
- 连接数据库
- 实现增删改查
最后记得关闭连接。
代码实现:
//1. 加载驱动程序
Class.forName("com.mysql.jdbc.Driver");
//2. 获取数据库的连接
Connection coon = DriverManager.getConnection(URL, USERNAME, PASSWORD);
//3. 通过数据库的连接操作数据库,实现增删改查
Statement stmt = (Statement) coon.createStatement();
// 查用 executeQuery,其它用 execute
ResultSet rs = stmt.executeQuery("select * from user");//返回 ResultSet 对象
//打印数据
while (rs.next()) {
//返回字符串, 两种查询的方式
System.out.println(rs.getString("user_name")+" "+rs.getString("user_pwd"));
}
rs.close();
stmt.close();
coon.close();
ps:URL, USERNAME, PASSWORD都是预设的值。
运行结果
与数据库中的结果是一样的:
代码解释
接下来,我们来一行行的解释这些代码到底干了什么。
驱动加载
首先是Class.forName
,我们一般都称呼为驱动加载。但是实际上它和硬件上的驱动挂载是完全不同的,它只是一个接口。所以我们为什么要这么执行这一步嘞?
要想看懂程序为什么这么做,就要先看到它的本质是什么,去看源码:
这里我们可以看到,它的源码什么都没干,就是定义了一个静态代码块,然后注册了驱动而已(别问为什么必须要注册,这是规范规定的)。
所以,实际上我们只用调用一下它的静态代码块就可以了。
而我们都知道,JVM把class文件加载到内存,并对数据进行校验、解析和初始化,最终形成 JVM可以直接使用的Java类型。初始化过程中,会执行类构造器(clinit)方法。类构造器(clinit)方法是由编译器自动收集 类中的所有类变量的赋值动作和静态语句块(static块)中的语句合并产生的。
所以,如果我们只用执行某个类的静态代码块,我们只用把它加载进JVM就可以了,不用再去为这个类创建一个实例(也就是new)。
而根据java代码在计算机中的三个阶段我们可以发现,(反射涉及到的)Class类正好可以帮我们加载类进JVM!
Class.forName
源码:
所以,,说白了这么做就是为了执行com.mysql.jdbc.Driver
的static代码块(害,虽然这么做的目的很简单,过程很简单,但是里面涉及到的却很多,这就是大佬们的代码叭。上面大多是我自己通过查阅+个人理解+翻看源码的理解,不一定绝对正确。)。
获取连接
顾名思义,就是通过DriverManager.getConnection
获取连接。没有很多要说的,但是我们可以继续扩展上面的内容。
SO,上面我们说到,执行Class.forName
就是为了执行那块静态代码块,只要是我们的.class文件加载进JVM就会执行它。所以,如果我们使用new
的方法,理论上也可以获取连接,对吧?。来我们来验证下。
com.mysql.jdbc.Driver driver = new com.mysql.jdbc.Driver();
Connection coon = DriverManager.getConnection(URL, USERNAME, PASSWORD);
Statement stmt = (Statement) coon.createStatement();
ResultSet rs = stmt.executeQuery("select * from user");//返回 ResultSet 对象
System.out.println("username password status phone registertime");
while (rs.next()) {
System.out.println(rs.getString("user_name")+" "+rs.getString("user_pwd"));
}
rs.close();
stmt.close();
coon.close();
运行结果:
哈哈,一点儿不差。不过这种方法我们可以发现,我们白白实例化了一个driver对象,却从头到尾都没用过它对吧。。所以这种方法几乎没几个人用(正常情况下也没人用)。
执行语句
执行语句的代码有俩行:
//3. 通过数据库的连接操作数据库,实现增删改查
Statement stmt = (Statement) coon.createStatement();
// 查用 executeQuery,其它用 execute
ResultSet rs = stmt.executeQuery("select * from user");//返回 ResultSet 对象
这里 Statement
本身就可以翻译成语句,所以这里是创建了一条语句,然后执行。返回结果是一个ResultSet对象。
解析结果
用while
就可以把结果遍历出来了,这里就不再解释了。