好学IT学院:IT信息技术分享交流平台
标签:Java  来源:互联网  作者:本站整理  发布时间:2010-01-24  ★★★加入收藏〗〖手机版
详解Java开发的数据库连接编程(JDBC)技术
摘要:本文主要讲述JDBC、JDBC的工作原理,访问数据库的方法、Statement、PreparedStatement、CallableStatement,ResultSet等对象的编程使用…

9.5.2、预编译方式执行SQL语句PreparedStatement

由于Statement对象在每次执行SQL语句时都将该语句传给数据库,如果需要多次执行同一条SQL语句时,这样将导致执行效率特别低,此时可以采用PreparedStatement对象来封装SQL语句。如果数据库支持预编译,它可以将SQL语句传给数据库作预编译,以后每次执行该SQL语句时,可以提高访问速度;但如果数据库不支持预编译,将在语句执行时才传给数据库,其效果类同于Statement对象。

另外PreparedStatement对象的SQL语句还可以接收参数,可以用不同的输入参数来多次执行编译过的语句,较Statement灵活方便(详见后文介绍)。

1、创建PreparedStatement对象:从一个Connection对象上可以创建一个PreparedStatement对象,在创建时可以给出预编译的SQL语句。

PreparedStatement pstmt=con.prepareStatement("select * from DBTableName");

2、执行SQL语句:可以调用executeQuery()来实现,但与Statement方式不同的是,它没有参数,因为在创建PreparedStatement对象时已经给出了要执行的SQL语句,系统并进行了预编译。

ResultSet rs=pstmt.executeQuery(); // 该条语句可以被多次执行

3、关闭PreparedStatement

pstmt.close();  //其实是调用了父类Statement类中的close()方法

9.5.3、执行存储过程CallableStatement

CallableStatement类是PreparedStatement类的子类,因此可以使用在PreparedStatement类及Statement类中的方法,主要用于执行存储过程。

1、创建CallableStatement对象:使用Connection类中的prepareCall方法可以创建一个CallableStatement对象,其参数是一个String对象,一般格式为:

不带输入参数的存储过程“{call 存储过程名()}”。
  带输入参数的存储过程“{call存储过程名(?, ?)}”
  带输入参数并有返回结果参数的存储过程“{? = call 存储过程名(?, ?, ...)}”

CallableStatement cstmt=con.prepareCall("{call Query1()}");

2、执行存储过程:可以调用executeQuery()方法来实现。

ResultSet rs=cstmt.executeQuery();

3、关闭CallableStatement

cstmt.close();  //其实是调用了父类Statement类中的close()方法

(6)检索记录集以获得当前记录集中的某一记录的各个字段的值

9.5.4、ResultSet对象:

① 执行完毕SQL语句后,将返回一个ResultSet类的对象,它包含所有的查询结果。但对ResultSet类的对象方式依赖于光标(Cursor)的类型,而对每一行中的各个列,可以按任何顺序进行处理(当然,如果按从左到右的顺序对各列进行处理可以获得较高的执行效率);

ResultSet类中的Course方式主要有:
  ResultSet.TYPE_FORWARD_ONLY(为缺省设置):光标只能前进不能后退,也就是只能从第一个一直移动到最后一个。
  ResultSet.TYPE_SCROLL_SENSITIVE:允许光标前进或后退并感应到其它ResultSet的光标的移动情形。
  ResultSet.TYPE_SCROLL_INSENSITIVE:允许光标前进或后退并不能感应到其它ResultSet的光标的移动情形。
  ResultSet类中的数据是否允许修改主要有:
  ResultSet.CONCUR_READ_ONLY(为缺省设置):表示数据只能只读,不能更改。
  ResultSet.CONCUR_UPDATABLE:表示数据允许被修改。

可以在创建Statement或PreparedStatement对象时指定ResultSet的这两个特性。

Statement stmt=con.createStatement(ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_READ_ONLY);
  或
  PreparedStatement pstmt=con.PrepareStatement("insert into bookTable values (?,?,?)",
   ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);

② ResultSet类的对象维持一个指向当前行的指针,利用ResultSet类的next()方法可以移动到下一行(在JDBC中,Java程序一次只能看到一行数据),如果next()的返回值为false,则说明已到记录集的尾部。另外JDBC也没有类似ODBC 的书签功能的方法。
  ③ 利用ResultSet类的getXXX()方法可以获得某一列的结果,其中XXX代表JDBC中的Java数据类型,如 getInt()、getString()、getDate()等。访问时需要指定要检索的列(可以采用 int值作为列号(从1开始计数)或指定列(字段)名方式,但字段名不区别字母的大小写)。

while(rs.next())
  {
    String name=rs.getString("Name"); //采用“列名”的方式访问数据
   int age=rs.getInt("age");
   float wage=rs.getFloat("wage");
   String homeAddress=rs.getString(4); //采用“列号”的方式访问数据
  }

9.5.5、数据转换

利用ResultSet类的getXXX()方法可以实现将ResultSet中的SQL数据类型转换为它所返回的Java数据类型。

9.5.6、NULL结果值

要确定给定结果值是否是JDBC NULL,必须先读取该列,然后使用ResultSet.wasNull
  方法检查该次读取是否返回JDBC NULL。
  当使用ResultSet.getXXX方法读取JDBC NULL时,方法wasNull将返回下列值之一:

(1)Javanull值

对于返回Java对象的getXXX方法(例如getString、getBigDecimal、getBytes、getDate、getTime、getTimestamp、getAsciiStream、getUnicodeStream、getBinaryStream、getObject等)。

(2)零值:对于getByte、getShort、getInt、getLong、getFloat和getDouble。
  (3)false值:对于getBoolean

9.5.6、获得结果集中的结构信息:利用ResultSet类的getMetaData()方法来获得结果集中的一些结构信息(主要提供用来描述列的数量、列的名称、列的数据类型。利用ResulSetMetaData类中的方法)。

ResultsetMetaData  rsmd=rs.getMetaData();
  rsmd.getColumnCount();   //返回结果集中的列数      
  rsmd.getColumnLabel(1); //返回第一列的列名(字段名)

例如:

Statement stmt=con.createStatement();

ResultSet rs=stmt.executeQuery("select * from TableName");

for(int i=1; i<=rs.getMetaData().getColumnCount(); i++)   //跟踪显示各个列的名称
  {
  System.out.print(rs. getColumnName (i)+"\t");
  }
  while(rs.next())
  {  //跟踪显示各个列的值
   for(int j=1; j<=rs.getMetaData().getColumnCount(); j++)
  {
   System.out.print(rs.getObject(j)+"\t");
  }
  }