JDBC层次结构和基本构成

Posted 亮亮-AC米兰

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JDBC层次结构和基本构成相关的知识,希望对你有一定的参考价值。

本文转载自http://blog.csdn.net/luanlouis/article/details/30060755,感谢分享

前言

       最近在研究Mybatis框架,由于该框架基于JDBC,想要很好地理解和学习Mybatis,必须要对JDBC有较深入的了解。所以便把JDBC 这个东东翻出来,老调重弹,好好总结一番,作为自己的笔记,也是给读者一个参考~~~本篇博文是我的上篇博文 老调重弹:JDBC系列 之 <驱动加载原理全面解析> 的续文,主要梳理一下JDBC的层次结构和基本构成。以下是本文的组织内容(用户可以点击上面的目录栏查看):


JDBC的层次结构

总体而言,JDBC包含以下几大角色 : Driver、DriverManager、Connection、Statement、ResultSet。这几大角色之间的层次关系如下图所示:



      其中,DriverManager 和 Driver 这两个角色已经在我的上一篇文章:老调重弹:JDBC系列 之 <驱动加载原理全面解析>阐述过了,读者可以点击查看。

Connection:Driver 或者 DriverManager根据连接的url 和参数信息创建Connection实例,用来维持和数据库的数据通信,如果没有销毁或者调用close()对象,此对象和数据库的对象会一直保持连接;

Statement:Connection创建Statement对象,表示需要执行的sql语句或者存储过程;

ResultSet: 表示Statement执行完SQL语句后返回的结果集。

基本构成分析

Connection角色

      Connection表示与特定数据库的连接,可以获取到数据库的一些信息,这些信息包括:其表信息,应该支持的SQL语法,数据库内有什么存储过程,此链接功能的信息等等。

      在一般实际使用情况下,我们关注的Connection的功能有以下几点:

1.创建可以执行sql语句或者存储过程的对象statement,用来和数据库进行交互;

比如,以下代码创建了几种不同类型的Statement:

[java]  view plain  copy  print ?
  1. //加载Oracle数据库驱动  
  2. Class.forName("oracle.jdbc.driver.OracleDriver");  
  3.   
  4. //根据特定的URL,返回可以接受此URL的数据库驱动对象  
  5. Driver driver = DriverManager.getDriver(URL);  
  6.   
  7. //使用数据库驱动创建数据库连接Connection会话  
  8. Connection connection = driver.connect(URL, props);  
  9.      
  10. //创建静态的sql语句  Statement 对象来将 SQL 语句发送到数据库。  
  11. Statement staticStatement= connection.createStatement();  
  12.   
  13. //创建CallableStatement 对象来调用数据库存储过程。  
  14. CallableStatement callableStatement = connection.prepareCall(sqlString);  
  15.   
  16. //创建参数化的Statement对象  
  17. PreparedStatement preparedStatement = connection.prepareStatement(sqlString);  

2. 控制sql语句的事务;

        Connection默认情况下,对于创建的statement执行的sql语句都是自动提交的,即在statement语句执行完后,自动执行commit操作,将结果影响到物理数据库。为了满足更好地事务控制需求,我们也可以手动地控制事务,手动地对statement 的sql语句执行进行提交(commit)或者回滚(rollback)。

        具体事务控制,请关注我的 后续博文老调重弹:JDBC系列

       下面通过一个简单的例子演示connection的事务控制:

[java]  view plain  copy  print ?
  1. String sqlString="insert into tableName(column1,column2) values(value1,value2)";  
  2. //加载Oracle数据库驱动  
  3. Class.forName("oracle.jdbc.driver.OracleDriver");  
  4.   
  5. //根据特定的URL,返回可以接受此URL的数据库驱动对象  
  6. Driver driver = DriverManager.getDriver(URL);  
  7.   
  8. //使用数据库驱动创建数据库连接Connection会话  
  9.    connection = driver.connect(URL, props);  
  10.    //使用自定义的事务,要设置connection不自动提交  
  11.    connection.setAutoCommit(false);  
  12.      
  13. //创建静态的sql语句  Statement 对象来将 SQL 语句发送到数据库。  
  14. Statement staticStatement= connection.createStatement();  
  15. try  
  16.     //执行插入操作  
  17.     staticStatement.execute(sqlString);  
  18.     staticStatement.getConnection().commit();//和上面的connection等价,statement只有一个创建自身的connection的引用  
  19. catch(Exception e)  
  20.   
  21.     //有异常,则rollback  
  22.     staticStatement.getConnection().rollback();  
  23.   


3.获取数据库连接的元数据,即数据库的整体综合信息。

连接的数据库整体信息被封装在了一个 DatabaseMetaData类型的对象上,可以通过以下代码获得:

[java]  view plain  copy  print ?
  1. DatabaseMetaData databaseMetaData = connection.getMetaData();  
具体DatabaseMetaData内包含了什么信息,请查看 JDK 的API对DatabaseMetaData的描述。

Statement角色

      Statement 的功能在于根据传入的sql语句,将传入sql经过整理组合成数据库能够识别的sql语句(对于静态的sql语句,不需要整理组合;而对于预编译sql语句和批量语句,则需要整理),然后传递sql请求,之后会得到返回的结果。对于查询sql,结果会以ResultSet的形式返回。


SQL语句可以分为增删改查(CRUD,Create,Read,Update,Delete)四种形式,JDBC 从对数据更新与否的角度上看,将上面的四种形式分为两类:查询类别和更新类别。即:

查询类别:select 语句

更新类别:Insert 、update、delete语句

对应地,Statement执行sql的几种形式:

1. 对sql语句类型不进行区分,执行sql语句的方法

statement提供了execute(String sql)方法支持此种形式,定义如下:

 booleanexecute(String sql) 
          执行给定的 SQL 语句,该语句可能返回多个结果。
如果是执行的sql是查询类型的select语句,此方法会返回true,需要自己再调用 statement.getResultSet() 方法来获取 Resultset结果集;

如果是执行的更新类的sql语句如 update,delete,insert语句,此方法会返回false,自己调用statement.getUpdateCount()  返回sql语句影响的行数。

2. 对查询类型的sql语句的执行方法

statement提供了executeQuery(String sql)方法支持此形式,定义如下:

 ResultSetexecuteQuery(String sql) 
          执行给定的 SQL 语句,该语句返回单个 ResultSet 对象。

3. 对更新类的sql语句 的执行方法

statement提供了executeQuery(String sql)方法支持此形式,定义如下:

 intexecuteUpdate(String sql) 
          执行给定 SQL 语句,该语句可能为 INSERTUPDATE 或 DELETE 语句,或者不返回任何内容的 SQL 语句(如 SQL DDL 语句)。

4.批量sql的执行方法

有时候需要将一些sql语句一起提交给数据库,批量执行,statement提供了一些方法,对批量sql的支持:

 voidaddBatch(String sql) 
          将给定的 SQL 命令添加到此 Statement 对象的当前命令列表中。
 int[]executeBatch() 
          将一批命令提交给数据库来执行,如果全部命令执行成功,则返回更新计数组成的数组。

这里只讨论一般性的Statement,不包含其子接口PreparedStatement和CallableStatement,这两个类型的Statement将会在后续的   老调重弹:JDBC系列 中继续讨论。

ResultSet角色

      当Statement查询sql执行后,会得到ResultSet对象,ResultSet对象是sql语句查询的结果,作为数据库结果的映射,其映射关系如下图所示。ResultSet对从数据库返回的结果进行了封装,使用迭代器的模式逐条取出结果集中的记录。其遍历结果集的基本形式如下:

[java]  view plain  copy  print ?
  1. while(resultSet.next())  
  2.   
  3.     //传入列明或者列索引获取记录中对应列的值  
  4.     resultSet.getXXX(param);  
  5.   


ResultSet游标的移动和定位

Resultset 提供了很多游标定位的方法,部分方法已经在下面列出:

 booleanabsolute(int row) 
          将光标移动到此 ResultSet 对象的给定行编号。
 voidafterLast() 
          将光标移动到此 ResultSet 对象的末尾,正好位于最后一行之后。
 voidbeforeFirst() 
          将光标移动到此 ResultSet 对象的开头,正好位于第一行之前。
 booleanfirst() 
          将光标移动到此 ResultSet 对象的第一行。
 intgetRow() 
          获取当前行编号。
 booleanisAfterLast() 
          获取光标是否位于此 ResultSet 对象的最后一行之后。
 booleanisBeforeFirst() 
          获取光标是否位于此 ResultSet 对象的第一行之前。
 booleanisFirst() 
          获取光标是否位于此 ResultSet 对象的第一行。
 booleanisLast() 
          获取光标是否位于此 ResultSet 对象的最后一行。
 booleanlast() 
          将光标移动到此 ResultSet 对象的最后一行。
 booleannext() 
          将光标从当前位置向前移一行。
 booleanprevious() 
          将光标移动到此 ResultSet 对象的上一行。
 booleanrelative(int rows) 
          按相对行数(或正或负)移动光标。

ResultSet结果集的元数据信息

元信息是指关于 ResultSet 对象中列的类型和属性信息的对象。可以通过以下方法获取:

 ResultSetMetaDatagetMetaData() 
          获取此 ResultSet 对象的列的编号、类型和属性。

ResultSet.getXXX(param) 、ResultSet.updateXXX()的XXX问题

        JDBC中定义了数据库中的数据类型和java数据类型的映射,用于数据库和Java数据类型之间的转换。在使用ResultSet去记录中的某一列值的时候,用户要根据数据库对应列的数据类型地应的java数据类型,否则的话有可能抛出异常。下图定义了数据库和Java类型之间的映射:

SQL JDBC/Java setXXX updateXXX
VARCHARjava.lang.StringsetStringupdateString
CHARjava.lang.StringsetStringupdateString
LONGVARCHARjava.lang.StringsetStringupdateString
BITbooleansetBooleanupdateBoolean
NUMERICjava.math.BigDecimalsetBigDecimalupdateBigDecimal
TINYINTbytesetByteupdateByte
SMALLINTshortsetShortupdateShort
INTEGERintsetIntupdateInt
BIGINTlongsetLongupdateLong
REALfloatsetFloatupdateFloat
FLOATfloatsetFloatupdateFloat
DOUBLEdoublesetDoubleupdateDouble
VARBINARYbyte[ ]setBytesupdateBytes
BINARYbyte[ ]setBytesupdateBytes
DATEjava.sql.DatesetDateupdateDate
TIMEjava.sql.TimesetTimeupdateTime
TIMESTAMPjava.sql.TimestampsetTimestamp以上是关于JDBC层次结构和基本构成的主要内容,如果未能解决你的问题,请参考以下文章

JDBC原理之层次结构

[四] JavaIO之类层次体系结构横向比对

网页HTML的基本结构是啥?

思维科学的层次和学科构成

9Bridge 桥梁模式 将类的功能层次结构与实现层结构分离 结构型设计模式

DOM节点关系

(c)2006-2024 SYSTEM All Rights Reserved IT常识