实现第一个JDBC程序
通过前面小节的学习,我们对JDBC及其常用API有了大致的了解,接下来就开始学习JDBC编程,JDBC编程大致按照以下几个步骤进行:
(1) 加载并注册数据库驱动,具体方式如下:
DriverManager.registerDriver(Driver driver);
(2) 通过DriverManager获取数据库连接,具体方式如下:
Connection conn = DriverManager.getConnection(String url, String user, String pass);
从上述方式可以看出,getConnection()方法中有3个参数,它们分别表示数据库url、登录数据库的用户名和密码。数据库url通常遵循如下形式的写法:
jdbc:subprotocol:subname
上面的url写法中jdbc部分是固定的,subprotocol指定连接到特定数据库的驱动程序,而subname部分则很不固定,也没有什么规律,不同数据库的url形式可能存在较大差异,以MySQL数据库url为例,其形式如下:
jdbc:mysql://hostname:port/databasename
(3) 通过Connection对象获取Statement对象。Connection创建Statement的方式有如下三种:
● createStatement():创建基本的Statement对象。
● prepareStatement():创建PreparedStatement对象。
● prepareCall():创建CallableStatement对象。
以创建基本的Statement对象为例,具体方式如下:
Statement stmt = conn.createStatement();
(4) 使用Statement执行SQL语句。所有的Statement都有如下三种方法来执行SQL语句:
● execute():可以执行任何SQL语句。
● executeQuery():通常执行查询语句,执行后返回代表结果集的ResultSet对象。
● executeUpdate():主要用于执行DML和DDL语句。执行DML语句,如 INSERT、UPDATE或DELETE时,返回受SQL语句影响的行数,执行DDL语句返回0。
以executeQuery()方法为例,具体方式如下:
// 执行SQL语句,获取结果集ResultSet
ResultSet rs = stmt.executeQuery(sql);
(5) 操作ResultSet结果集。如果执行的SQL语句是查询语句,执行结果将返回一个ResultSet对象,该对象里保存了SQL语句查询的结果。程序可以通过操作该ResultSet对象来取出查询结果。ResultSet对象主要提供的方法主要可以分为以下两类:
● next()、previous()、first()、last()、beforeFirst()、afterLast()、absolute()等移动记录指针的方法。
● getXxx()获取指针指向行,特定列的值。
(6) 回收数据库资源。关闭数据库连接,释放资源,包括关闭ResultSet、Statement和Connection等资源。
至此,JDBC编程的大致步骤已经讲解完成,为了帮助初学者快速学习如何开发JDBC程序,接下来,编写第一个JDBC程序,该程序从users表中读取数据,并将结果打印在控制台,具体步骤如下所示。
(1) 搭建实验环境
在MySQL中创建一个名称为chapter01的数据库,然后在该数据库中创建一个users表,SQL语句如下所示:
CREATE DATABASE chapter01;
USE chapter01;
CREATE TABLE users(
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(40),
password VARCHAR(40),
email VARCHAR(60),
birthday DATE
)CHARACTER SET utf8 COLLATE utf8_general_ci;
数据库和表创建成功后,再向users表中插入3条数据,SQL语句如下所示:
INSERT INTO users(NAME,PASSWORD,email,birthday)
VALUES('zs','123456','zs@sina.com','1980-12-04');
INSERT INTO users(NAME,PASSWORD,email,birthday)
VALUES('lisi','123456','lisi@sina.com','1981-12-04');
INSERT INTO users(NAME,PASSWORD,email,birthday)
VALUES('wangwu','123456','wangwu@sina.com','1979-12-04');
为了查看数据是否添加成功,使用SELECT语句查询users表,执行结果如下所示:
SELECT * FROM users;
+----+--------+----------+-----------------+------------+
| id | name | password | email | birthday |
+----+--------+----------+-----------------+------------+
| 1 | zs | 123456 | zs@sina.com | 1980-12-04 |
| 2 | lisi | 123456 | lisi@sina.com | 1981-12-04 |
| 3 | wangwu | 123456 | wangwu@sina.com | 1979-12-04 |
+----+--------+----------+-----------------+------------+
3 rows in set (0.03 sec)
(2) 导入数据库驱动
新建Java工程chapter01,将要访问的数据库驱动文件添加到classpath中。由于应用程序访问的是MySQL数据库,因此,我们将MySQL的数据库驱动文件mysql-connector-java-5.0.8-bin.jar添加到classpath中即可。
(3) 编写JDBC程序
在工程chapter01中,新建Java类Example01,该类用于读取数据库中的users表,并将结果输出,如例1所示。
例1 Example01.java
1 package cn.itcast.jdbc.example;
2 import java.sql.Connection;
3 import java.sql.DriverManager;
4 import java.sql.ResultSet;
5 import java.sql.SQLException;
6 import java.sql.Statement;
7 import java.sql.Date;
8 public class Example01 {
9 public static void main(String[] args) throws SQLException {
10 // 1. 注册数据库的驱动
11 DriverManager.registerDriver(new com.mysql.jdbc.Driver());
12 // 2.通过DriverManager获取数据库连接
13 String url = "jdbc:mysql://localhost:3306/chapter01";
14 String username = "root";
15 String password = "itcast";
16 Connection conn = DriverManager.getConnection (url, username, password);
17 // 3.通过Connection对象获取Statement对象
18 Statement stmt = conn.createStatement();
19 // 4.使用Statement执行SQL语句。
20 String sql = "select * from users";
21 ResultSet rs = stmt.executeQuery(sql);
22 // 5. 操作ResultSet结果集
23 System.out.println("id | name | password | email | birthday");
24 while (rs.next()) {
25 int id = rs.getInt("id"); // 通过列名获取指定字段的值
26 String name = rs.getString("name");
27 String psw = rs.getString("password");
28 String email = rs.getString("email");
29 Date birthday = rs.getDate("birthday");
30 System.out.println(id + " | " + name + " | " + psw + " | " + email + " | " + birthday);
31 }
32 // 6.回收数据库资源
33 rs.close();
34 stmt.close();
35 conn.close();
36 }
37 }
程序的运行结果如图1所示。
图1 运行结果
从图1中可以看出,程序输出了结果集中指定的数据。由此可见,使用ResultSet对象处理结果集是相当灵活的。
在例1中演示了JDBC访问数据库的步骤。首先注册MySQL的数据库驱动器类,通过DriverManager获取一个Connection对象,然后使用Connection对象创建了一个Statement对象,Statement对象能够通过executeQuery()方法执行SQL语句,并返回结果集ResultSet对象。最后,通过遍历ResultSet对象便可得到最终的查询结果。
需要注意的是,在实现第一个JDBC程序时,还有两个方面需要改进,具体如下:
1、注册驱动
在注册数据库驱动时,虽然DriverManager.registerDriver(new com.mysql.jdbc.Driver())方法可以完成,但会使数据库驱动被注册两次。这是因为Driver类的源码中,已经在静态代码块中完成了数据库驱动的注册。所以,为了避免数据库驱动被重复注册,我们只需要在程序中加载驱动类即可,具体加载方式如下所示:
Class.forName("com.mysql.jdbc.Driver");
2、释放资源
由于数据库资源非常宝贵,数据库允许的并发访问连接数量有限,因此,当数据库资源使用完毕后,一定要记得释放资源。为了保证资源的释放,在Java程序中,我们应该将最终必须要执行的操作放在finally代码块中,具体方式如下:
if(rs!=null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
}
if(stmt!=null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if(conn!=null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}