百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程网 > 正文

JDBC规范二-JDBC API中的类与接口

yuyutoo 2024-10-12 00:48 3 浏览 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之间的关系如图所示。

相关推荐

史上最全的浏览器兼容性问题和解决方案

微信ID:WEB_wysj(点击关注)◎◎◎◎◎◎◎◎◎一┳═┻︻▄(页底留言开放,欢迎来吐槽)●●●...

平面设计基础知识_平面设计基础知识实验收获与总结
平面设计基础知识_平面设计基础知识实验收获与总结

CSS构造颜色,背景与图像1.使用span更好的控制文本中局部区域的文本:文本;2.使用display属性提供区块转变:display:inline(是内联的...

2025-02-21 16:01 yuyutoo

写作排版简单三步就行-工具篇_作文排版模板

和我们工作中日常word排版内部交流不同,这篇教程介绍的写作排版主要是用于“微信公众号、头条号”网络展示。写作展现的是我的思考,排版是让写作在网格上更好地展现。在写作上花费时间是有累积复利优势的,在排...

写一个2048的游戏_2048小游戏功能实现

1.创建HTML文件1.打开一个文本编辑器,例如Notepad++、SublimeText、VisualStudioCode等。2.将以下HTML代码复制并粘贴到文本编辑器中:html...

今天你穿“短袖”了吗?青岛最高23℃!接下来几天气温更刺激……

  最近的天气暖和得让很多小伙伴们喊“热”!!!  昨天的气温到底升得有多高呢?你家有没有榜上有名?...

CSS不规则卡片,纯CSS制作优惠券样式,CSS实现锯齿样式

之前也有写过CSS优惠券样式《CSS3径向渐变实现优惠券波浪造型》,这次再来温习一遍,并且将更为详细的讲解,从布局到具体样式说明,最后定义CSS变量,自定义主题颜色。布局...

柠檬科技肖勃飞:大数据风控助力信用社会建设

...

你的自我界限够强大吗?_你的自我界限够强大吗英文

我的结果:A、该设立新的界限...

行内元素与块级元素,以及区别_行内元素和块级元素有什么区别?

行内元素与块级元素首先,CSS规范规定,每个元素都有display属性,确定该元素的类型,每个元素都有默认的display值,分别为块级(block)、行内(inline)。块级元素:(以下列举比较常...

让“成都速度”跑得潇潇洒洒,地上地下共享轨交繁华
让“成都速度”跑得潇潇洒洒,地上地下共享轨交繁华

去年的两会期间,习近平总书记在参加人大会议四川代表团审议时,对治蜀兴川提出了明确要求,指明了前行方向,并带来了“祝四川人民的生活越来越安逸”的美好祝福。又是一年...

2025-02-21 16:00 yuyutoo

今年国家综合性消防救援队伍计划招录消防员15000名

记者24日从应急管理部获悉,国家综合性消防救援队伍2023年消防员招录工作已正式启动。今年共计划招录消防员15000名,其中高校应届毕业生5000名、退役士兵5000名、社会青年5000名。本次招录的...

一起盘点最新 Chrome v133 的5大主流特性 ?

1.CSS的高级attr()方法CSSattr()函数是CSSLevel5中用于检索DOM元素的属性值并将其用于CSS属性值,类似于var()函数替换自定义属性值的方式。...

竞走团体世锦赛5月太仓举行 世界冠军杨家玉担任形象大使

style="text-align:center;"data-mce-style="text-align:...

学物理能做什么?_学物理能做什么 卢昌海

作者:曹则贤中国科学院物理研究所原标题:《物理学:ASourceofPowerforMan》在2006年中央电视台《对话》栏目的某期节目中,主持人问过我一个的问题:“学物理的人,如果日后不...

你不知道的关于这只眯眼兔的6个小秘密
你不知道的关于这只眯眼兔的6个小秘密

在你们忙着给熊本君做表情包的时候,要知道,最先在网络上引起轰动的可是这只脸上只有两条缝的兔子——兔斯基。今年,它更是迎来了自己的10岁生日。①关于德艺双馨“老艺...

2025-02-21 16:00 yuyutoo

取消回复欢迎 发表评论: