在web开发中,不可避免的地要使用数据库来存储和管理数据。为了在java语言中提供数据库访问的支持,Sun公司于1996年提供了一套访问数据的标准Java类库,即JDBC。
JDBC的全称是Java数据库连接(Java Database connect),它是一套用于执行SQL语句的Java API。应用程序可通过这套API连接到关系数据库,并使用SQL语句来完成对数据库中数据的查询、更新和删除等操作。应用程序使用JDBC访问数据库的方式如下图所示。
从上图可以看出,应用程序使用JDBC访问特定的数据库时,需要与不同的数据库驱动进行连接。由于不同数据库厂商提供的数据库驱动不同,因此,为了使应用程序与数据库真正建立连接,JDBC不仅需要提供访问数据库的API,还需要封装与各种数据库服务器通信的细节为了帮助大家更好地理解应用程序如何通过JDBC访问数据库,下面通过一张图来描述JDBC的具体实现细节,如下图。
从上图中可以看出,JDBC的实现包括三部分。
(1)JDBC驱动管理器:负责注册特定的JDBC驱动器,主要通过java.sql. Driver Manager类实现。
(2)JDBC驱动器API:由Sun公司负责制定,其中最主要的接口是java.sql. Driver接口。
(3)JDBC驱动器:它是一种数据库驱动,由数据库厂商创建,也称为JDBC驱动程序JDBC驱动器实现了JDBC驱动器API,负责与特定的数据库连接,以及处理通信细节。
2、JDBC常用API
在开发JDBC程序前,首先了解一下JDBC常用的API。JDBC API主要位于java.sql包中,该包定义了一系列访问数据库的接口和类,具体如下。
1. Driver接口
Driver接口是所有JDBC驱动程序必须实现的接口,该接口专门提供给数据库厂商使用。在编写JDBC程序时,必须要把指定数据库驱动程序或类库加载到项目的classpath中。
2. DriverManager类
Driver Manager类用于加载JDBC驱动并且创建与数据库的连接。在Driver Manager类中,定义了两个比较重要的静态方法。如表所示:
registerDriver(Driver driver)
该方法用于向 DriverManager中注册给定的JDBC驱动程程序
getConnection(String url,String user,String pwd)
该方法用于建立和数据库的连接,并返回表示连接的 Connection对象
3、Connection接口
Connection接口代表Java程序和数据库的连接,在Connection接口中,定义了一系列方法,具体如表所示。
getMetaData()
该方法用于返回表示数据库的元数据的 DatabaseMetaData对象
createStatement()
用于创建一个Statement对象来将SQL语句发送到数据库
prepareStatement(String sql)
用于创建一个PreparedStatement对象来将参数化的SQL语句发送到数据库
prepareCall(String sql)
用于创建一个CallableStatement对象来调用数据库存储过程
4、Statement接口
Statement接口用于向数据库发送SQL语句,在Statement接口中,提供了三个执行SQL语句的方法,具体如表所示。
execute(String sql)
用于执行各种SQL语句,该方法返回一个boolean类型的值,如果为true,表示所执行的SQL语句具备查询结果,可通过Statement的getResultSet方法获得查询结果。
executeUpdate(String sql)
用于执行SQL中的Insert、update和delete语句。该方法返回一个int类型的值,表示数据库中受该SQL语句影响的记录的数目。
executeQuery(String sql)
用于执行SQL中的select语句,该方法返回一个表示查询结果的ResultSet对象
5. PreparedStatement接口
PreparedStatement是Statement的子接口,用于执行预编译的SQL语句。在PreparedStatement接口中,提供了一些基本操作的方法,具体如表下所示。
executeUpdate()
在此PreparedStatement对象中执行SQL语句,该语句必须是个DML语句或者是无返回内容的SQL语句,比如DDL语句。
executeQuery()
在此PreparedStatement对象中执行SQL查询,该方法返回的ResultSet对象
setInt(int parameterIndex, int x)
将指定参数设置为给定的int值
setFloat(int parameterIndex, float x)
指定参数设置为给定的float值
setString(int parameterIndex, String x)
将指定参数设置为给定的String值
setDate(int parameterIndex, Date x)
将指定参数设置为给定的Date值
addBatch()
将一组参数添加到此PreparedStatement对象的批处理命令中
setCharacterStream(parameterIndex, reader, length)
将指定的输入流写入数据库的文本字段
setBinaryStream(parameterIndex, x, length)
将二进制的输入流数据写入到二进制字段中
需要注意的是,上表中的setDate()方法可以设置日期内容,但参数Date的类型是java.sq.Date,而不是java.util.Date。
6、CallableStatement接口
CallableStatement是PreparedStatement的子接口,用于执行SQL存储过程。在Callablestatement按接口中,提供了一些基本操作的方法,具体下表所示:
registerOutParameter(int parameterIndex,int sqlType)
按顺序位置将OUT参数注册为SQL类型。其中,parameterIndex表示顺序位置,sqlType表示SQL类型
setNull(String parameter Name, int sqlType)
将指定参数设置为SQL类型的NULL
setString(String parameterName, String x)
查询最后一个读取的OUT参数是否为SQL类型的NULL
wasNull()
查询最后一个读取的OUT参数是否为SQL类型的NULL
getlnt(int parameterIndex)
以Java语言中int值的形式获取指定的数据库中INTEGER类型参数的值
需要注意的是,由于 CallableStatement接口继承PreparedStatement,PreparedStatement接口又继承了 Statement,因此CallableStatement接口中除了拥有自己特有的方法,也同时拥有了这两个父接口中的方法。
7、ResultSet接口
ResultSet接口表示 select查询语句得到的结果集,该结果集封装在一个逻辑表格中。在 ResultSet接口内部有一个指向表格数据行的游标,ResultSet对象初始化时,游标在表格的第一行之前。下表中列举了ResultSet接口中的常用方法。
getString(int columnIndex)
用于获取指定字段的String类型的值,参数columnIndex代表字段的索引
getString(String columnName)
用于获取指定字段的String类型的值,参数column Name代表字段的名称
getInt(int columnIndex)
用于获取指定字段的int类型的值,参数columnIndex代表字段的索引
getInt(String columnName)
用于获取指定字段的int类型的值,参数columnName代表字段的名称
getDate(int columnIndex)
用于获取指定字段的Date类型的值,参数columnIndex代表字段的索引
getDate(String columnName)
用于获取指定字段的Date类型的值,参数column Name代表字段的名称
next()
将游标从当前位置向下移一行
absolute(int row)
将游标移动到此Resultset对象的指定行
afterLast()
将游标移动到此ResultSet对象的末尾,即最后一行之后
beforeFirst()
将游标移动到此Resultset对象的开头,即第一行之前
previous()
将游标移动到此ResultSet对象的上一行
last()
将游标移动到此ResultSet对象的最
从上表中可以看出,ResultSet接口中定义了大量的getXxx()方法,采用哪种getXxx()方法取决于字段的数据类型。程序既可以通过字段的名称来获取指定数据,也可以通过字段的索引来获取指定的数据,字段的索引是从1开始编号的。
3、实现第一个JDBC程序
通过前面的学习,我们对JDBC及其常用API有了大致的了解,接下来就开始介绍JDBC编程,JDBC编程大致按照以下几个步骤进行。
(1) 加载并注册数据库驱动,具体方式如下。
DriverManager.registerDriver(Driver driver);
(2) 通过Driver Manager获取数据库连接,具体方式如下。
Connection conn= DriverManager.getConnection(String url, String user, String pass);
从上述方式可以看出,getConnection()方法中有三个参数,它们分别表示数据库url、登录数据库的用户名和密码。数据库山通常遵循如下形式的写法。
jdbc:subprotocol:subname
上面的URL写法中jdbc部分是固定的,subprotocol指定链接达到特定数据库的驱动程序,而subname部分则很不固定,也没有什么规律,不同数据库的形式可能存在较大差异,一Mysql数据库为例,其形式如下:
jdbc:mysql://hostname:port/databasename
(3)通过Connection对象获取Statement对象。Connection创建Statement的方式有如下三种。
① createStatement(): 创建基本的Statement对象
② prepareStatement(): 创建PreparedStatement对象。
③ preparCall(): 创建CallableStatement对象。
以创建基本的Statement对象为例,具体方式如下。
Statement stmt=conn.createStatement();
(4)使用Statement执行SQL语句。所有的Statement都有如下三种方法来执行语句。
①execute():可以执行任何SQL语句。
②executeQuery():通常执行查询语句,执行后返回代表结果集的Resultset对象。
③executeUpdate():主要用于执行DML和DDL语句。执行DML语句,如INSERT、UPDATE或 DELETE时,返回受SQL语句影响的行数,执行DDL语句返回0。
以executeQuer()方法为例,具体方式如下。
//执行SQL语句,获取结果集ResulSet
ResultSet rs=stmt.executQuery(sql);
(5)操作ResultSet结果集。如果执行的SQL语句是查询语句,执行结果将返回Resultset对象,该对象里保存了SQL语句查询的结果。程序可以通过操作该ResultSet对象来取出查询结果。 ResultSet对象提供的方法主要可以分为以下两类。
①next()、previous()、first()、last()、beforeFirst()、afterLast()、absolute()等移动记录指针的方法
②getXxx()获取指针指向行,特定列的值。
(6)回收数据库资源。关闭数据库连接,释放资源,包括关闭ResultSet、Statement和Connection等资源。
至此,JDBC编程的大致步骤已经完成,为了帮助读者快速学习如何开发JDBC程序,接下来,编写第一个JDBC程序,改程序从user表中读取数据,并将结果结果打印在控制台,具体步骤入戏所示。
1、搭建实验环境
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 COOLLATE utf8_genneral_ci;
数据库和表创建成功后,再向users表中插入三条数据,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,1isi@sina.com,'1981-12-04');
INSERT INTO users(NAME,PASSWORD,email,birthday)
VALUES('wangwu',123456,'wangwu@sina.com','1979-12-04');
2、导入数据库驱动
新建Java工程chapter01,将要访问的数据库驱动文件添加到classpath中。由于应用程序访问的是MySQL数据库,因此,将MySQL的数据库驱动文件mysql-connector-java-5.0.8-bin.jar添加到classpath中即可。
3、编写JDBC程序
在工程chapter01中,新建Java类Example01,该类用于读取数据库中的users表,并将结果输出,如例下面案例所示。
package cn.itcast.jdbc.example;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Date;
public class Example01 {
public static void main(String[] args) throws SQLException {
//1.注册数据库的驱动
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
//2.通过 DriverManager获取数据库连接
String url="jdbc:mysql://localhost:3306/chapter01";
String usernames="root";
String password="itcast";
Connection conn=DriverManager.getConnection(url, username, password);
//3.通过 Connection对象获取 Statement对象
Statement stmt= conn.createStatement();
//4.使用 Statement执行SQL语句
String sql="select * from users";
ResultSet rs=stmt.executeQuery(sql);
//5、操作 ResultSet结果集
System.out.println("id|name|password|email|birthday");
while (rs.next()) {
int id=rs.getInt("id"); //通过列名获取指定字段的值
String name=rs.getString("name");
String psw=rs.getString("password");
String email=rs.getString("email");
Date birthday=rs.getDate("birthday");
System.out.println(id+"|"+name+"|"+psw+"|"+email+"|"+birthday);
}
//6.回收数据库
rs.close();
stmt.close();
conn.close();
}
}程序执行后,会讲从users表中读取到的数据打印到控制台。
在上面案例中演示了JDBC访问数据库的步骤。首先注册MySQL的数据库驱动器类,通过 DriverManager获取一个Connection对象,然后使用Connection对象创建了一个Statement对象,Statement对象能够通过executeQuery()方法执行SQL语句,并返回结果集ResultSet对象。最后,通过遍历Resultset对象便可得到最终的查询结果需要注意的是,在实现第一个JDBC程序时,还有两个方面需要改进,具体如下。
1、注册驱动
在注册数据库驱动时,虽然DriverManager.registerDriver(new com. mysql.jdbc.Driver())方法可以完成,但会使数据库驱动被注册两次。这是因为Driver类的源码中,已经在静态代码块中完成了数据库驱动的注册。所以,为了避免数据库驱动被重复注册,只需要在程序中加载驱动类即可,具体加载方式如下所示。
Class.forName("com.mysqk.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;
} |
|