JDBC是使用Java存取数据库系统的标准解决方案,它将不同数据库间各自差异API与标准SQL语句分开看待,实现数据库无关的Java操作接口。对于开发人员而言,使用JDBC统一的API接口,专注于标准SQL 语句,就可以避免直接处理底层数据库驱动程序与相关操作接口的差异性,而将主要精力投放于应用开发本身,从而加快开发进度。
1.JDBC的API接口
JDBC规范采用接口和实现分离的思想,设计了Java数据库编程的框架。JDBC的API提供了一组标准的Java语言中的接口和类,使用这些接口和类,Java客户端程序可以访问各种不同类型的数据库。如图1所示。
图1 JDBC工作原理示意图
其中,JDBC API由sun公司提供,定义与数据库建立连接、执行SQL语句、处理结果的方法,这些供程序员调用的接口与类,集成在java.sql和javax.sql包中。DriverManager类的作用是载入各种不同的JDBC驱动程序。而各种数据库的JDBC驱动程序则由不同的数据库厂商提供,用于针对具体的数据库产品实现JDBC API中的方法。
在JDBC的API中主要提供了以下一些接口和类:Connection、DriverManager、Statement、 ResultSet、PreparedStatement、CallableStatement。
其中,Connection对象代表与数据库的连接。连接过程包括所执行的SQL语句和在该连接上所返回的结果。一个应用程序可与单个数据库有一个或多个连接,或者可与许多数据库有连接。
DriverManager类是JDBC 的管理层,作用于用户和驱动程序之间。它跟踪可用的驱动程序,并在数据库和相应驱动程序之间建立连接。
Statement对象用于将SQL语句发送到数据库中。实际上有三种Statement 对象,它们都作为在给定连接上执行SQL语句的包容器:Statement、PreparedStatement和 CallableStatement。
ResultSet包含符合SQL语句中条件的所有行,并且它通过一套get方法(这些get方法可以访问当前行中的不同列)提供了对这些行中数据的访问。
PreparedStatement实例包含已编译的SQL语句。包含于 PreparedStatement 对象中的SQL语句可具有一个或多个参数。
CallableStatement对象为所有的DBMS提供了一种以标准形式调用已储存过程的方法。已储存过程储存在数据库中。对已储存过程的调用是CallableStatement对象所含的内容。
关于JDBC API的详细叙述可以参见《Java数据库接口JDBC入门基础讲座 》(http://www.yesky.com/zhuanti/443/1865943.shtml),讲解的非常详细。
2.环境搭建
下面简单讲讲如何安装MySQL数据库和Navicat for MySQL工具。
MySQL数据库的下载和安装可以参见《MySQL安装图解》(http://www.jb51.net/article/23876.htm),这里就不再赘述了。
Navicat for MySQL是基于Windows平台,为MySQL数据库量身订作的类似于MySQL的用户管理界面工具。使用了图形用户界面(GUI),可以用一种安全和更为容易的方式快速地创建、组织、存取和共享数据。
Navicat for MySQL的下载地址为:http://www.cr173.com/soft/26935.html
Navicat for MySQL的安装和使用可以参见《Navicat MySQL安装及使用说明》(http://wenku.baidu.com/view/6938c04b2b160b4e767fcf6b.html),这里也不再赘述了。
运行Navicat for MySQL工具,创建一个连接到我们所安装的MySQL数据库的连接,这里我创建的连接名为“myConnection”。打开该连接,并创建一个数据库,这里我创建了一个名为“mydb”的数据库。在该数据库中,我们创建了一张名为“userinfo”的表。
做好这一切之后,我们就可以对这张表进行设计了,设计的目的在于指定数据的储存结构。这这张表中我们存储了id、username、password三项内容。设计好的表如图2所示。
图2 表的设计
3.使用JDBC访问MySQL数据库
使用JDBC访问数据库的一般步骤如下:
3.1加载JDBC驱动程序
不同的数据库对应着不同的驱动程序,要使用JDBC API访问MySQL数据库,需要在工程的libs目录下导入MySQL数据库的驱动包mysql-connector-java-5.1.7-bin。
不同数据库厂商的驱动类名不同,具体为:
Oracle10g:oracle.jdbc.driver.OracleDriver
MySQL5:com.mysql.jdbc.Driver
SQLServer2005:com.microsoft.sqlserver.jdbc.SQLServerDriver
3.2提供连接参数
不同数据库产品的连接URL不同,具体为:
Oracle10g:jdbc:oracle:thin:@主机名:端口:数据库SID
比如:jdbc:oracle:thin:@localhost:1521:ORCL
MySQL5:jdbc:mysql://主机名:端口/数据库名
比如:jdbc:mysql://localhost:3306/test
SQLServer2005:jdbc:sqlserver://主机名:端口:DatabaseName=库名
比如:jdbc:sqlserver://localhost:1433:DatabaseName=BookDB
在使用JDBC访问数据库时,提供的连接参数除了数据库的URL之外,还有两个参数:数据库的用户名和数据库的密码。
3.3建立一个数据库的连接
Connection 对象是数据库连接的具体实例,一个Connection 对象就代表一个数据库连接,可以使用 DriverManager 的getConneciton()方法传入指定数据库的连接URL、用户名和密码。
从DriverManager中获得Connection对象,驱动程序会自动通过DriverManager.registerDriver() 方法注册,这样DriverManager就可以跟厂商的驱动程序通信了。
在连接数据库时,需要检测异常对象java.sql.SQLException。
建立数据库连接的具体实现方法如下:
1 private final String USERNAME = "root"; //定义数据库的用户名 2 private final String PASSWORD = "******"; //定义数据库的密码 3 private final String DRIVER = "com.mysql.jdbc.Driver"; //定义数据库的驱动信息 4 private final String URL = "jdbc:mysql://localhost:3306/mydb"; //定义访问数据库的地址 5 6 /* 7 * Function : 获取数据库连接 8 * Author : 博客园-依旧淡然 9 */ 10 public Connection getConnection() { 11 try { 12 mConnection = DriverManager.getConnection(URL, USERNAME, PASSWORD); 13 } catch (Exception e) { 14 System.out.println("连接数据库失败!"); 15 } 16 return mConnection; 17 }
3.4创建一个Statement对象
PreparedStatement对象用于执行动态SQL语句。SQL中会变动的部分可以使用?作为参数占位符。
3.5执行SQL语句
对数据库的常用操作有添加、删除以及修改。有时我们还需要对数据库表中的信息进行查询,这时我们可以使用如下方法来实现:
1 /* 2 * Function : 查询返回单条记录 3 * Author : 博客园-依旧淡然 4 */ 5 public Map<String, Object> findSimpleResult(String sql, List<Object> params) 6 throws SQLException { 7 Map<String, Object> map = new HashMap<String, Object>(); 8 int index = 1; 9 mPreparedStatement = mConnection.prepareStatement(sql); 10 if((params != null) && (!params.isEmpty())) { 11 for(int i = 0; i < params.size(); i++) { 12 mPreparedStatement.setObject(index++, params.get(i)); 13 } 14 } 15 mResultSet = mPreparedStatement.executeQuery(); //返回查询结果 16 ResultSetMetaData resultSetMateData = mResultSet.getMetaData(); //获得列的相关信息 17 int cols_len = resultSetMateData.getColumnCount(); //获得列的长度 18 while(mResultSet.next()) { 19 for(int i = 0; i < cols_len; i++) { 20 String cols_name = resultSetMateData.getColumnName(i+1) ; 21 Object cols_value = mResultSet.getObject(cols_name); 22 if(cols_value == null) { 23 cols_value = ""; 24 } 25 map.put(cols_name, cols_value); 26 } 27 } 28 return map; 29 }
3.6处理结果
通过以上几个步骤已经实现了对数据库的访问,在这一步就可以对访问到的数据进行处理了。
3.7关闭连接
在操作完成后要把所使用的JDBC对象全都关闭,以释放JDBC资源。具体的实现方法如下:
1 /* 2 * Function : 断开连接 3 * Author : 博客园-依旧淡然 4 */ 5 public void releaseConnection() { 6 if(mResultSet != null) { //关闭ResultSet对象 7 try { 8 mResultSet.close(); 9 } catch (SQLException e) { 10 e.printStackTrace(); 11 } 12 } 13 if(mPreparedStatement != null) { //关闭PreparedStatement对象 14 try { 15 mPreparedStatement.close(); 16 } catch (SQLException e) { 17 e.printStackTrace(); 18 } 19 } 20 if(mConnection != null) { //关闭Connection对象 21 try { 22 mConnection.close(); 23 } catch (SQLException e) { 24 e.printStackTrace(); 25 } 26 } 27 }