一、JDBC基础
JDBC是Java应用与数据库管理系统进行交互的标准API,包括两个包:核心API---java.sql和扩展的API---javax.sql。应用程序通过核心API的接口实现数据库连接和数据处理,其主要接口如下:
接口名称 |
功能 |
java.sql.Driver |
驱动程序,连接应用程序和数据库,用于读取数据库驱动器的信息,提供连接方法,建立访问数据库所用的Connection对象。在加载某一Driver类时,它应该创建自己的实例并向DriverManager注册该实例。 |
java.sql.DriverManager |
驱动程序管理器,管理一组Driver对象,对程序中用到的驱动程序进行管理,包括加载驱动程序、获得连接对象、向数据库发送信息。在调用getConnection方法时,DriverManager会试着从初始化时加载的那些驱动程序以及使用与当前 |
java.sql.Connection |
连接Java数据库和Java应用程序之间的主要对象并创建所有的Statement对象。 |
java.sql.Statement |
语句对象,代表了一个特定的容器,对一个特定的数据库执行SQL语句。用于执行静态SQL语句并返回它所生成结果的对象。在默认情况下,同一时间每个 |
PreparedStatement |
表示预编译的SQL语句的对象。SQL语句被预编译并存储在PreparedStatement对象中。然后可以使用此对象多次高效地执行该语句。 |
java.sql.ResultSet |
用于控制对一个特定语句的行数据的存取,也就是数据库中记录或行组成的集合。 |
二、结果集及其常见方法
1.
结果集有三种类型,它的类型决定了能否对结果集中的游标进行操作,以及并发的数据源的改变能否反映到结果集中。具体描述如下:
类型 |
描述 |
TYPE_FORWARD_ONLY |
默认的结果集类型,这种类型的结果集对象的游标只能向前移动,从第1行的前面到最后一行的后面。 |
TYPE_SCROLL_INSENSITIVE |
这种类型的结果集对象的游标可以向前移动,也可以直接定位到某一行上,但是对结果集中对应数据的变化是不敏感的。 |
TYPE_SCROLL_SENSITIVE |
这种类型的结果集对象的游标可以向前移动,也可以直接定位到某一行上,并且对结果集中对应数据的变化是敏感的(如果)。 |
2.
结果集的并发性决定了结果集所支持的更新操作的层次,有两种并发性层次:
类型 |
描述 |
CONCUR_READ_ONLY |
默认的结果集并发类型,这种情况下的结果集对象不支持更新操作。 |
CONCUR_UPDATABLE |
这种情况下的结果集对象支持更新操作。 |
可以通过调用DatabaseMetaData的supportsResultSetConcurrency方法来看驱动是否支持结果集上的更新操作,该方法定义如下:
boolean 第一个数据表示结果集类型,第二个参数表示并发类型。 |
3.
结果集的延续性是指当事务提交时,在当前事务中创建的结果集是否关闭。默认情况下会关闭这个结果集对象。延续性可以通过如下两个静态属性来指定:
类型 |
描述 |
HOLD_CURSORS_OVER_COMMIT |
当提交事务时不关闭该结果集对象。 |
CLOSE_CURSORS_AT_COMMIT |
提交事务时关闭结果集对象,有时候会提高性能。 |
4.
结果集的类型、并发性和延续性可以通过Connection.createStatement、Connection.prepareStatement和Connection.prepareCall等方法指定,同时Statement、PreparedStatement和CallableStatement接口也提供了相应的setter方法和getter方法。如下代码是创建语句对象的时候指定结果集的类型、并发性和延续性。
Connection conn = Statement stmt = ResultSet. |
5.
结果集常用的游标操作方法如下表所示:
返回值 |
方法名 |
功能描述 |
boolean |
next() |
将游标从当前位置向前移一行,如果指向某行,返回true,如果指向最后一行的后面,返回false |
boolean |
previous() |
将游标从当前位置向后移一行,如果指向某行,返回true,如果指向第一行的前面,返回false |
boolean |
first() |
将游标移到此结果集的第一行。 |
boolean |
last() |
将游标移到些结果集的最后一行。 |
void |
beforeFirst() |
将游标移动到此结果集的开始处,正好位于第一行之前 |
void |
afterLast() |
将游标移动到此结果集的末尾,正好位于最后一行之后 |
boolean |
relative(int |
按相对行数移动游标。如果参数为0,游标无变化。如果参数是正的,游标向前移动rows行,如果rows太大,游标指向最后1条记录的后面。如果参数是负数,游标向后移动rows行,如果rows太小,游标指向第1条记录的前面。如果游标指向一个有效行,方法返回true,否则返回false |
boolean |
absolute(int |
将游标移动到参数所指定的行 |
6. 以下是示例代码:
//获取结果集中列的类型 ResultSet rs = ResultSetMetaData rsmd int [] colType = new for(int idx=0,int colType[idx] = //如果结果集支持更新操作,可以通过结果集完成更新、删除和插入操作。 Statement stmt = ResultSet rs = rs.next(); rs.updateString(“author”,”JerryChoi”); rs.updateRow(); //插入记录 ResultSet rs = rs.moveToInsertRow(); //设置每一列的值 rs.updateString(1,”aaa”); rs.updateString(2,”bbb”); rs.updateLong(3,1234); //插入一行 rs.insertRow(); rs.moveToCurrentRow(); //删除记录 rs.absolute(4); rs.deleteRow(); |
三、连接数据库的基本过程
基本过程如下:
l 建立数据源
l 导入用到的包
l 加载驱动程序
l 创建与数据库的连接
l 创建语句对象
l 编写SQL语句
l 执行SQL语句
l 处理数据
l 关闭相关对象
l 处理异常
1. 建立数据源
假设已经存在名为bookstore的MySQL数据库。
2. 导入用到的包
import |
3. 加载驱动程序
//如果驱动程序和名字是MyDriver,加载驱动程序的语句是: Class.forName(“MyDriver”); //或者 Class.forName(“MyDriver”).newInstance(); //本例中使用MySQL,刚加载的语句为: Class.forName(“com.mysql.jdbc.Driver”); |
4. 创建与数据库的连接
连接数据库需要知道如下信息:
l 数据库所在的主机,所使用的端口等
l 数据库的名字
l 用户信息,包括用户名和口令
//连接数据库的格式如下: //constr:连接字符串;user:用户名;passwd:口令 Connection con = //MySQL数据库的连接示例如下: Connection con = |
以下表格是常用的数据库驱动程序名字和URL格式:
数据库 |
驱动程序 |
URL |
Oracle |
oracle.jdbc.driver.OracleDriver |
jdbc:oracle:thin:@dbip:port:databasename dbip :数据库服务器的 port :数据库的监听端口,需要看安装时的配置,缺省为 databasename:数据库的 |
SQL Server |
com.microsoft.jdbc.sqlserver.SQLServerDriver |
jdbc:microsoft:sqlserver://dbip:port;DatabaseName=databasename dbip :数据库服务器的 port :数据库的监听端口,需要看安装时的配置,缺省为 databasename:数据库的 |
DB2 |
com.ibm.db2.jdbc.app.DB2Driver |
jdbc:db2://dbip:port/databasename dbip :数据库服务器的 port :数据库的监听端口,需要看安装时的配置。 databasename:数据库的 |
Informix |
com.informix.jdbc.IfxDriver |
jdbc:infoxmix-sqli://dbip:port dbip :数据库服务器的 port :数据库的监听端口,需要看安装时的配置。 databasename:数据库的 user:用户名 password:用户口令 |
Sybase |
com.sybase.jdbc.SybDriver |
jdbc:sybase:Tds:dbip:port/databasename dbip :数据库服务器的 port :数据库的监听端口,需要看安装时的配置。 databasename:数据库的 |
MySQL |
com.mysql.jdbc.Driver 或 org.gjt.mm.mysql.Driver |
jdbc:mysql://dbip:port/databasename 注:[] 是可选的选项 dbip :数据库服务器的IP地址,如果是本地可写成 port:数据库的监听端口,需要看安装时的配置,缺省为 databasename:数据库的 param1、param2、value1和value2:附加参数,常见参数如下: l user:用户名 l l l l l l l l l |
PostgreSQL |
org.postgresql.Driver |
jdbc:postgresql://dbip:port/databasename dbip :数据库服务器的IP地址,如果是本地可写成 port:数据库的监听端口,需要看安装时的配置。 databasename:数据库的 |
Access |
sun.jdbc.odbc.JdbcOdbcDriver |
jdbc:odbc:datasourcename datasourcename:数据库的 SID 注:该驱动只能工作在 Windows |
5. 创建语句对象
语句对象的作业就是执行SQL语句。语句对象的创建是通过连接对象创建的,所以在创建语句对象之前应该确保连接对象已经创建。以下代码是创建语句对象的代码,不管连接什么数据库,不管执行什么样的操作,这句代码不用改:
Statement stmt = |
6. 编写SQL语句
示例代码如下:
String sql = “select * |
7. 执行SQL语句
常用的执行SQL语句的方法有以下两个:
返回值 |
方法 |
说明 |
ResultSet |
executeQuery(String |
主要用于执行有结果集返回的SQL语句,典型的就是select查询语句。 |
int |
executeUpdate(String |
主要用于执行没有结果集返回的SQL语句,如果要在数据库中添加、修改或删除信息,它们都没有返回值,应该使用本方法。该方法的返回值是一个整数,表示影响数据库中记录的个数。 |
例如,要执行上面的查询语句,可以使用如下代码:
ResultSet rs = |
8. 处理结果集
可参照上面的“结果集及其常见方法”
注:对行的遍历,使用结果集的next()方法。要获取某一列,可以使用getXXX(int
columnIndex)或getXXX(String columnLabel)方法。以下是示例代码:
//以字符串的形式获取第1列或字段名为username的列 String userid = String userName = |
9. 关闭相关对象
代码如下:
//应该按以下顺序关闭相关对象,该顺序与创建对象的顺序相反 //关闭结果集 rs.close(); //关闭语句 stmt.close(); //关闭连接 con.close(); |
10. 异常处理
使用以下框架对异常进行处理:
try{ ……//要执行的可能出错的代码 }catch(Exception ……//出错后的处理代码 }finally{ ……//不管是否出错都要执行的代码 } |
以下是综合示例代码:
String className = String url = String username = String userpass = String tableName = Connection con = PreparedStatement pstmt ResultSet rs = try{ Class.forName(className); con = pstmt = rs = while(rs.next()) { for(int System.out.println(rs.getString(i+1)); System.out.println(); } }catch(Exception System.out.println(e.toString); }finally{ try{ try{ try{ } |