JDBC规范二-JDBC API中的类与接口
yuyutoo 2024-10-12 00:48 9 浏览 0 评论
通过前面学习,我们了解了使用JDBC API操作数据源的步骤,并以一个案例介绍了如何使用JDBC API操作关系型数据库。JDBC API中的内容远不止这些,本节我们就来全面地学习JDBC API中的一些类和接口。JDBC API由java.sql和javax.sql两个包构成,接下来会分两个小节对这两个包的内容进行详细介绍。
1.java.sql包详解
java.sql包中涵盖JDBC最核心的API,下面是java.sql包中的所有接口、枚举和类:
#数据类型
java.sql.Array
java.sql.Blob
java.sql.Clob
java.sql.Date
java.sql.NClob
java.sql.Struct
java.sql.Time
java.sql.Timestamp
java.sql.SQLXMI
java.sql.Ref
java.sql.RowId
java.sql.SQLOutput
java.sql.SQLData
java.sql.SQLInput
#枚举
java.sql.SQLType
java.sql.JDBCType
java.sql.Types
java.sgl.RowIdLifeTime
java.sal.PseudoColumnUsage
java.sql.ClientinfoStatus
#API相关
java.sql.Wrapper
java.sgl.Connection
java.sgl.Statement
java.sql.CallableStatement
java.sql.PreparedStatement
java.sql.DatabaseMetaData
java.sql.ParameterMetaData
ava.sql.ResultSet
ava.sql.ResultSetMetaData
#驱动相关
java.sql.Driver
java.sql.DriverAction
java.sql.DriverManager
java.sql.DriverPropertyInfo
java.sql.SOLPermission
java.sql.Savepoint
#异常
java.sgl.BatchUpdateException
java.sql.DataTruncation
java.sql.SQLClientInfoException
java.sql.SQLDataException
java.sql.SQLException
java.sql.SQLFeatureNotSupportedException
java.sql.SQLIntegrityConstraintViolationExceptionava.sql.SOLInvalidAuthorizationSpecException
java.sql.SOLNonTransientConnectionException
java.sql.SOLNonTransientException
java.sql.SOLSyntaxErrorException
java.sgl.SQLTimeoutException
java.sql.SOLTransactionRollbackException
java.sql.SQLTransientConnectionException
java.sql.SOLTransientException
java.sgl.SQLWarning
如上面的列表所示,java.sql包中的内容不多,大致可以分为数据类型接口、枚举类、驱动相关类和接口、异常类。
除这几部分外,剩下的就是作为Java开发人员需要掌握的API,主要包括下面几个接口:
java.sql.Wrapper
java.sql.Connection
java.sql.Statement
java.sql.CallableStatement
java.sql.PreparedStatement
java.sql.DatabaseMetaData
java.sql.ParameterMetaData
java.sql.ResultSet
java.sql.ResultSetMetaData
这些接口都继承了java.sql.Wrapper接口。许多JDBC驱动程序提供超越传统JDBC的扩展,为了符合JDBC API规范,驱动厂商可能会在原始类型的基础上进行包装,Wrapper接口为使用JDBC的应用程序提供访问原始类型的功能,从而使用JDBC驱动中一些非标准的特性。
java.sql.Wrapper接口提供了两个方法,具体如下:
public interface Wrapper {
/**
* Returns an object that implements the given interface to allow access to
* non-standard methods, or standard methods not exposed by the proxy.
*
* If the receiver implements the interface then the result is the receiver
* or a proxy for the receiver. If the receiver is a wrapper
* and the wrapped object implements the interface then the result is the
* wrapped object or a proxy for the wrapped object. Otherwise return the
* the result of calling <code>unwrap</code> recursively on the wrapped object
* or a proxy for that result. If the receiver is not a
* wrapper and does not implement the interface, then an <code>SQLException</code> is thrown.
*
* @param <T> the type of the class modeled by this Class object
* @param iface A Class defining an interface that the result must implement.
* @return an object that implements the interface. May be a proxy for the actual implementing object.
* @throws java.sql.SQLException If no object found that implements the interface
* @since 1.6
*/
<T> T unwrap(java.lang.Class<T> iface) throws java.sql.SQLException;
/**
* Returns true if this either implements the interface argument or is directly or indirectly a wrapper
* for an object that does. Returns false otherwise. If this implements the interface then return true,
* else if this is a wrapper then return the result of recursively calling <code>isWrapperFor</code> on the wrapped
* object. If this does not implement the interface and is not a wrapper, return false.
* This method should be implemented as a low-cost operation compared to <code>unwrap</code> so that
* callers can use this method to avoid expensive <code>unwrap</code> calls that may fail. If this method
* returns true then calling <code>unwrap</code> with the same argument should succeed.
*
* @param iface a Class defining an interface.
* @return true if this implements the interface or directly or indirectly wraps an object that does.
* @throws java.sql.SQLException if an error occurs while determining whether this is a wrapper
* for an object with the given interface.
* @since 1.6
*/
boolean isWrapperFor(java.lang.Class<?> iface) throws java.sql.SQLException;
}
其中,unwrap()方法用于返回未经过包装的JDBC驱动原始类型实例,我们可以通过该实例调用JDBC驱动中提供的非标准的方法。
sWrapperFor()方法用于判断当前实例是否是JDBC驱动中某一类型的包装类型。
Statement stmt = conn.createStatement ();
Class clzz = Class.forName("oracle.jdbc.OracleStatement");
if(stmt.isWrapperFor(clzz)) {
OracleStatement os = (OracleStatement)stmt.unwrap(clzz);
os.defineColumnType(1, Types.NUMBER);
}
如上面的代码所示,Oracle数据库驱动中提供了一些非JDBC标准的方法,如果需要使用这些非标准的方法,则可以调用Wrapper接口提供的unwrap()方法获取Oracle驱动的原始类型,然后调用原始类型提供的非标准方法就可以访问Oracle数据库特有的一些特性了。
JDBC API中的Connection、Statement、ResultSet等接口都继承自Wrapper接口,这些接口都提供了对JDBC驱动原始类型的访问能力。
Connection、Statement、ResultSet之间的关系如图所示。
2.javax.sql包详解
javax.sql包中的类和接口最早是由JDBC 2.0版本的可选包提供的,这个可选包最早出现在J2SE 1.2版本中,这个包中的内容不多,主要包括下面几个类和接口:
#数据源
javax.sgl.DataSource
javax.sql.CommonDataSource
#连接池相关
javax.sgl.ConnectionPoolDataSource
javax.sql.PooledConnection
javax.sgl.ConnectionEvent
javax.sgl.ConnectionEventListener
javax.sgl.StatementEvent
javax.sgl.StatementEventListener
#ResultSet 扩展
javax.sql.RowSet
javax.sgl.RowSetEvent
javax.sgl.RowSetInternal
javax.sgl.RowSetListener
javax.sgl.RowSetMetaData
javax.sgl.RowSetReader
javax.sgl.RowSetWriter
#分布式扩展
javax.sgl.XAConnection
javax.sql.XADataSource
JDBC 1.0中使用DriverManager类来产生一个与数据源连接的Connection对象。相对于DriverManager,JDBC 2.0提供的DataSource接口是一个更好的连接数据源的方式。
首先,应用程序不需要像使用DriverManager一样对加载的数据库驱动程序信息进行硬编码。开发人员可以选择通过JNDI注册这个数据源对象,然后在程序中使用一个逻辑名称来引用它,JNDI会自动根据我们给出的名称找到与这个名称绑定的DataSource对象。然后我们就可以使用这个DataSource对象来建立和具体数据库的连接了。
其次,使用DataSource接口的第二个优势体现在连接池和分布式事务上。连接池通过对连接的复用,而不是每次需要操作数据源时都新建一个物理连接来显著地提高程序的效率,适用于任务繁忙、负担繁重的企业级应用。
javax.sql.DataSource与java.sql.Connection之间的关系如图所示。
javax.sql包下还提供了一个PooledConnection接口。PooledConnection和Connection的不同之处在于,它提供了连接池管理的句柄。一个PooledConnection表示与数据源建立的物理连接,该连接在应用程序使用完后可以回收而不用关闭它,从而减少了与数据源建立连接的次数。
应用程序开发人员一般不会直接使用PooledConnection接口,而是通过一个管理连接池的中间层基础设施使用。当应用程序调用DataSource对象的getConnection()方法时,它返回一个Connection对象。但是当我们使用数据库连接池时(例如Druid),该Connection对象实际上是到PooledConnection对象的句柄,这是一个物理连接。连接池管理器(通常为应用程序服务器)维护所有的PooledConnection 对象资源。如果在池中存在可用的PooledConnection对象,则连接池管理器返回作为到该物理连接的句柄的Connection对象。如果不存在可用的PooledConnection对象,则连接池管理器调用ConnectionPoolDataSource对象的getConnection()方法创建新的物理连接。
连接池实现模块可以调用PooledConnection对象的addConnectionEventListener()将自己注册成为一个PooledConnection对象的监听者,当数据库连接需要重用或关闭的时候会产生一个ConnectionEvent对象,它表示一个连接事件,连接池实现模块将会得到通知。
javax.sql.PooledConnection与java.sql.Connection之间的关系如图所示。
另外,javax.sql包中还包含XADataSource、XAResource和XAConnection接口,这些接口提供了分布式事务的支持,具体由JDBC驱动来实现。更多分布式事务相关细节可参考JTA(Java Transaction API)规范文档。
XAConnection接口继承了PooledConnection接口,因此它具有所有PooledConnection的特性,我们可以调用XAConnection实例的getConnection()方法获取java.sql.Connection对象,它们与java.sql.Connection之间的关系如图所示。
javax.sql包中还提供了一个RowSet接口,该接口继承自java.sql包下的ResultSet接口。RowSet用于为数据源和应用程序在内容中建立一个映射。RowSet对象可以建立一个与数据源的连接并在其整个生命周期中维持该连接,在这种情况下,该对象被称为连接的RowSet。RowSet对象还可以建立一个与数据源的连接,从其获取数据,然后关闭它,这种RowSet被称为非连接RowSet。非连接Rowset可以在断开时更改其数据,然后将这些更改写回底层数据源,不过它必须重新建立连接才能完成此操作。
相较于java.sql.ResultSet而言,RowSet的离线操作能够有效地利用计算机越来越充足的内存减轻数据库服务器的负担。由于数据操作都是在内存中进行的,然后批量提交到数据源,因此灵活性和性能都有了很大的提高。
RowSet默认是一个可滚动、可更新、可序列化的结果集,而且它作为一个JavaBean组件,可以方便地在网络间传输,用于两端的数据同步。通俗来讲,RowSet就相当于数据库表数据在应用程序内存中的映射,我们所有的操作都可以直接与RowSet对象交互。RowSet与数据库之间的数据同步,作为开发人员不需要关注。
javax.sql.RowSet与java.sql.ResultSet之间的关系如图所示。
相关推荐
- 网络规划建设原来也可以这么简单!
-
废话少说,直接上干货。天气炎热,请各位看官老爷静心阅读。整体思路下图是关于网络建设的所有相关领域,接下来我为大家逐一讲解。网络分层...
- 网络规划设计师笔记-第 1 章 计算机网络原理
-
计算机网络原理1.1计算机网络概论(P1-10)...
- 别输在远见上,网工这样做职业规划,比啥都强
-
01职业中的规划,人生中的buff“职业规划“这个词,其实对很多年轻人,包括曾经年轻的我来说,都不屑一提。...
- 网络规划设计师学习中(个人自学笔记分享1),有一起学习的吗?
-
网络规划设计师,上午考试内容学习:第一章:计算机网络概述(上部分):如果你也在一起学习,那么我们来一起学习吧!坚持1年,争取明年一次性通过!...
- 在微服务中使用 ASP.NET Core 实现事件溯源和 CQRS
-
概述:事件溯源和命令查询责任分离(CQRS)已成为解决微服务设计的复杂性的强大架构模式。基本CQRS表示形式在本文中,我们将探讨ASP.NETCore如何使你能够将事件溯源和CQRS...
- 用 Nginx 部署 ASP.NET Core 应用程序
-
用Nginx部署ASP.NETCore应用程序步骤如下:在Linux中安装.NETCore运行时和Nginx:...
- Asp.net Core启动流程讲解(一)(asp.net core 入门)
-
asp.netcore默认项目包括项目根目录级的Startup.cs、Program.cs、appsettings.json(appsettings.Development.json)launch...
- 十天学会ASP之第五天(十天学会asp教程)
-
学习目的:学会数据库的基本操作1(写入记录)数据库的基本操作无非是:查询记录,写入记录,删除记录,修改记录。今天我们先学习写入记录。先建立一个表单:<formname="form1"met...
- ASP.NET Core 的 WebApplication 类
-
ASP.NETCore提供了3个主机类(Host)。这些类用于配置应用、管理生命周期和启动Web服务。...
- ASP.NET Core中的键控依赖注入(.net依赖注入原理)
-
大家好,我是深山踏红叶,今天我们来聊一聊ASP.NETCore中的FromKeyedServices,它是在.Net8中引入的。这一特性允许通过键(如字符串或枚举)来注册和检索依赖注入(D...
- Asp.net常用方法及request和response-a
-
asp.net教程asp.net常用方法:1、Request.UrlReferrer请求的来源,可以根据这个判断从百度搜的哪个关键词、防下载盗链、防图片盗链,可以伪造(比如迅雷)。(使用全局一般处理...
- asp.net常考面试题(aspnet题库)
-
asp.net常考面试题一,列举ASP.Net页面之间传递值的几种方式?1,使用QueryString,如:......?id=1;response.Redirect()......2,使用Sessi...
- 在Windows系统搭建.NET Core环境并创建运行ASP.NET网站
-
微软于6月27日在红帽DevNation峰会上正式发布了.NETCore1.0、ASP.NET1.0和EntityFrameworkCore1.0,其将全部支持Windows、OSX和...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- mybatis plus (70)
- scheduledtask (71)
- css滚动条 (60)
- java学生成绩管理系统 (59)
- 结构体数组 (69)
- databasemetadata (64)
- javastatic (68)
- jsp实用教程 (53)
- fontawesome (57)
- widget开发 (57)
- vb net教程 (62)
- hibernate 教程 (63)
- case语句 (57)
- svn连接 (74)
- directoryindex (69)
- session timeout (58)
- textbox换行 (67)
- extension_dir (64)
- linearlayout (58)
- vba高级教程 (75)
- iframe用法 (58)
- sqlparameter (59)
- trim函数 (59)
- flex布局 (63)
- contextloaderlistener (56)