`
lianxiangbus
  • 浏览: 534182 次
文章分类
社区版块
存档分类
最新评论

JDBC高级应用一

 
阅读更多
关于数据库连结

我们所说有JDBC高级应用,并不是说它的技术含量很高(也许JAVA平台上不存在什么"技术含量"的说
法,因为JAVA是给大家用的而不是给某些人用的).说它是高级应用,是因为它是对于JDBC基础应用来
说的扩展,也就是可以优化你的应用性能,或方便于应用的实现.所以说它是一种高级应用而不叫高级
技术.

JDBC中,java.sql包是基础的,也是核心的功能,javax.sql包则是高级的,扩展的功能.所以
为了交流的方便,我们把它们区分为coreAPI和optionalAPI.

但是仍然然有一些coreAPI中的功能,我把它归纳到高级应用中.象存储过程的调用,多结果集
的处理,我之所以要把这些东西拿出来说明,是目前你在网上找不到任何一份详细的文档和例程,可以
说有95%以上的开发人员都不知道真正如何处理这些工作.所以我会在回上海后详细写这一段的内容.
现在我们还是来看看optionalAPI给我们带来的好处:

我们已经了解,执行一个SQL语句,要经过如下几步:
1.Connction
2.Statement
3.Statement.executeXXXXX();
4.可选的对结果集的处理
5.必要的Connction的关闭.(再次提醒如果你想成为中级水平以上的程序员,请你把关闭语
句写在finally块中,在通过下面的介绍后我介绍一个方法可以用来验证你的程序是否有连结
泄漏)

这其中,生成Connction对象是最最重要的工作,也是最消耗资源的,因为连结对象要驱动底层
的SOCKET,调用物理连结和数据库进行通信,所以生成,关闭,再生成这种连结对象就相当于我们在二十
世纪八十年代(1980年以后出身的不了解吧?)喝易拉罐饮料一样.你买一瓶饮料是一块二角钱,你可知道
那罐子(Connection)值一块零八分.而你喝下去的东西只值一角二分钱,这是我们那儿一个饮料厂的真实
数据.
在javax.sql包出来以前,我们只能买这样的饮料来喝,除非你不喝.也有一些人不服气自己生
产饮料(poolman),可是消费者很快发现,它只是把原来单卖的易拉罐现在打包卖给了我们,因为它还是
用原来的包装原料来生产的,poolman这种类型的连结池,其根本是从DriverManager中getConnection
出来的.真正的效率如果不是你心理作用的话,也许比单个连结还要低!!!以及一些江湖好汉的"杰作",
都无法跳出这个框框.我自己在那一段时间也曾醉心于研究这些"连结池",因为谁都可以把别人的原码
读过后,再加上其他人的优点写出一个更好的来,可是,大家可以看到,我写出了好用的Upload,DownLoad,
HtmlUtil,Encoder,Decoder等一系列工具.可是我没有写出成功的连结池.......

我们再来深入一步,为什么DriverManager生成的连结和基于它的连结池不能真正提高性能.
DriverManager对象中,绝大多数的JDBC是封装了一个物理连结,也就是它抓住了一个和数据库通信的
Socket,当你使用DriverManager.getConnection()时也就是有一个和数据库连结的Socket让你占用了.
而且这个方法是同步的.大家知道这样的物理连结对于任何系统是有限制的,比如一个WEB服务器一般
最大并发是150到250之间,数据库服务器也是这样的道理,你不仅要考虑你的程序不能用光连结,还要
考虑不同Runtime中或其它应用程序也在同时和你一起使用这些物理连结,如果一台服务器上有JAVA
WEBSERVER,还有一个C的应用程序也访问数据库,你不能那么无礼地要求人家C程序员他的程序必须
等你的JAVA调用空闲才能访问数据库吧.所以物理连结是极其宝贵的.
基于DriverManager.getConnection()的连结池只不过是预先生成这样的物理连结放在一个
pool中,然后编号等你调用,它省略的是生成这样的连结的时间.注意你得到的连结在你没有释放之前,
它无法处理别的工作,因为连结句柄在用户手中,另外这种连结池调用时是由程序调用者初始化的,
每一次调用都必须有初始化工作,而调用者是否以优化的方法去运行它,完成还要看每个人的编程水
平.另一方面,如果这种连结池是如果用于WEB容器管理,那简单是垃圾,因为它强迫使用静态变量来
保持连结,容器根本无法做到访问控制.而且它不能在不同Runtime中被调用.

而javax.sql的实现采用了在用户连结和物理连结中间加一个缓冲的中间层,它虽然也只生
成30个物理连结,但用户本身不能访问它,DataSource返回给用户的是一个JAVA抽象对象,客户程序把
连结请求放回缓冲中由DataSource统一调度物理连结来处理,这样可以最大程序利用宝贵的物理连结
也许现在的30个物理连结仍然不够负载,你仍然需要修改实际连结数,但我们知道,我们现在的这种连
结方式已经不是DriverManager.getConnection()能比的了.也就是说,在同样多的物理连结下,
DataSource可以给我们更多(是多得多的)的调用机会,其实,正常情况下一个从DriverManager中
getConnection()出来物理连结的负载量只有百分之几,就是因为你的调用抓住了它的句柄而不能让
它很好地工作.另外程序员只能返回它而不能关闭它,因为传统连结池中连结对象一旦由用户关闭,
就要再次重新生成物理新的连结,所以用户只能释放,对于非连结池和连结池得到的连结对象,
要用不同的代码编程,简单是一种痛苦.一旦没有注意,在处理完数据后不是释放而是关闭,这个错误
到底是谁的过错?????????????

我上面说java.sql实现绝大多数是得到物理连结,也有例外,但不是那些以前的连结池,而是
OSE,就是oracle的servlet环境,它是把servlet服务器实现在数据库的地址空间上,servlet服务去调
用数据库根本没有通过传统的连结,因为数据是"敞开"的,这就象通过网络访问其它计算机文件和访问
本地文件的区别.虽然它也提供标准的JDBC接口让你调用,但它底层根本不是用JDBC封装的.

DataSource的另外一个优点就是它完全实现数据库和应用程序的分离,如何配置服务器生成
DataSource的引用和程序开发无关,你在程序开发中,只要通过JDNI查找DataSource的逻辑名称就行.
而DriverManager.getConnection()中,你不得不把数据库驱动程序名,访问地址,用户,密码写在你的
应用程序中,即使可以从配置文件中读取这些属性串,而不同的服务器配置文件的路径你都要修改.而
DataSource提供了标准的配置.

说来说去,如何用DataSource来连结数据库?

非常简单:

DataSourceds=(DataSource)newInitialContext().lookup("jdbc/mydb");
Connectionconn=ds.getConnection();

当然我是为了说明它简单故意把它的异常给忽略了.实际应用中.你应该捕获它的异常.

如果你还不明白什么是JDNI,我劝你先找一些这方面的资料看看,这可以是网编程方面的
基础协议啊.

关于DataSourceds=(DataSource)newInitialContext().lookup("jdbc/mydb");有几点
需要说明的是,你只要配置好你的服务器(tomcat,resin,weblogic)这些服务器中都有一个例子,如果
你不是很懂,你先把那个例子改动几个字就行了.用一段时间你就会慢慢理解它们代表什么了.
然后你在容器环境下调用newInitialContext().lookup("jdbc/mydb")容器就会自动找到那个
DataSource对象给你调用,这个过程对用户来说是透明的.
那边那个聪明的朋友已经问了,因为DataSource的属性是已经配置好的放在容器中的,那我
不在容器环境下,比如一个独立的application,我如何能取到DataSource呢?
其实,如果你能知道newInitialContext()时,容器调用了哪些默认的配置,你就可以把
这些配置参数手工加进去而不依赖容器环境了.好在InitialContext可以getEnvironment(),在生
成这个对象后你可以get一下看看,把这些参数记下来,以后在没有这些参数的环境下put进去.
这里多几句话,谈一下学习方法,我在国内主持几个论坛(不多,两三个),从没有问过别人什
么问题,java技术又不是我发明的,不可能我什么都懂,一是问了好象有损于"高手"风范(哈哈,其实
真正的高手还是要问别人的,只有我这种假高手才不会问别人).另一方面是我根本不必问别人,比如
象application下,连结不同厂家的DataSource要put什么东西进去呢?一是去他们的网站看资料,虽然
我的英语水平只有大家的10%,但我上英文网站的次数可能比你们多.二是看有没有什么共用的API能
得到,好在可以getEnvironment(),但假如没有这个方法呢?这就要看你的学习态度了,有人会这论坛
叫"高手球命",还有什么"急用,在线等待"什么的.而我,会把newInitialContext()反编译出来看看
它调用了什么(孔子说,为了学习的目的,反编译是允许的,甚至说是伟大的,光明的,正确的思想,是有
道德的,脱离了低级趣味的,有益于人民的行为!!!----孔子语录补集第123页第4行,1989年10月版)
如果一个对象在构造时要求有参数,而它又有一个没有参数的重载的构造方法,你想想它肯定在没有
参数的构造方法中调用了默认参数,你要做的就是把它们打印出来.有多少人是这样做的?

jdbcoptionalAPI的其它扩展功能:
javax.sql不仅仅是在性能上的提高,而且它还支持分布式事务,在传统的连结过程中,我们
可以在一个连结过程中,setAutoCommit()为fasle,然后通过rollback()或commit()那回滚和提交事
务,这种在一个连结过程中的事务称为本地事务,但假如在一个事务中要对多个数据库操作,或多过
Servlet参与操作,那就必须使用分布式事务.

关于JDBC的事务我会放在下面来介绍,一个值得庆贺的功能出来了,就是事务保存点已经
JDBC3.0中实现,以前,如果我们把事务原子A,B,C放在一个事务中,如果A,B执行了,C失败,我们只能
把A,B都回滚了,但现在我们可以先把A,B保存为一个点,然后以这个点为回滚或提交,这就象在用WORD
编写文章时我们可以在不同的时候保存一个副本,而不会要么一字没有了,要么就是当前编辑的状态.

现在我们来优化我们在基础知识中实现的Bean,今天在家,没法上论坛,上次写的连结部分
叫什么名字忘记了,现在我们就叫它PooledDB吧.
当时我们已经把那个Bean分为三个部分,把生成连结部分独立出来了,而业务方法部份和扩
展部分根本不要动它,这就是继承的好处:)


packagecom.inmsg.beans;

importjavax.naming.*;
importjavax.sql.*;

publicclassPooledDB{

Connectioncon=null;
privateStringsource="";
publicPooledDB()throwsException{//默认构造方法,如果构造时不加参数,连结jdbc/office
source="java:comp/env/jdbc/office";
Contextct=newInitialContext();
DataSourceds=(DataSource)ct.lookup(source);
con=ds.getConnection();
}

//然后增加重载方法,用来连结其它的数据源
publicPooledDB(Stringsource)throwsException{
this.source=source;
Contextct=newInitialContext();
DataSourceds=(DataSource)ct.lookup(source);
con=ds.getConnection();
}
//注意一定要先把source赋给成员变量this.source,因为下面还有一个makeConnection()
//辅助方法,如果不把source赋给this.source,则makeConnection()调用默认的source字符串

privatevoidmakeConnection()throwsException{
Contextct=newInitialContext();
DataSourceds=(DataSource)ct.lookup(source);
con=ds.getConnection();
}

//现在我们把close()方法拿到父类来实现,这是经过综合考虑的,它是一个业务方法,无论是什么
//方式取得连结,它本身不会修改,但为什么还封装到父类中呢?因为这样可以用一个独立的父类来
//做连结测试,如果我只想试一下数据库能不能连结,我就不必再引用子类,直接用这个父类就行了
publicvoidclose()throwsException{
if(con!=null&&!con.isClosed())con.close();
}
}

一般来说,构造方法尽量捕获异常处理而不要抛出异常,但作为Bean的实现,捕获异常调用者不容易
看到异常信息,所以抛给调用者处理,另外这个类又要在应用程序中调用,又要考虑作为Bean调用,所以一定
要有一个无参数的构造方法,否则不能作为javaBean调用.把异常抛出给调用者的另一目的,我在设计时是这
样考虑的,就是强迫你一定在使用try{}catch(){}块,这样你就会想到再加一个finally{},再次提醒,一定要
以下面的形式来调用你数据库连结的Bean或封装类:
PooledDBpd=null;
try{
pd=newPooledDB();
....................
}
catch(Exceptione){}
finally{try{pd.close();}catch(Exceptionex){}}

如果要测试你的数据库连结是否有泄漏,请你把DataSource中最大连结数设为1,只用一个连结的情
况下,如果你的程序中哪一处没有关闭连结,则下面的程序就不能再访问,然后从头到尾测试你的程序吧,一旦
发现不能访问数据库了,就查看刚才访问的代码,这样所有程序测试后,就可以放心了,一般来说我是不用这么
测试的,因为我在写数据库连结时是没有生成对象就写好close:

PooledDBpd=null;
try{}
catch(Exceptione){}
finally{try{pd.close();}catch(Exceptionex){}}
然后原在try{}的花括号中回车加上pd=PooledDB();和业务代码的:)当然,你们都比我聪明用不
着这样死套也不会忘记close()的.
不要太高兴,到目前为止你仍然还没得到一个最好的解决方案,以下我们还会对这个数据库连结的
Bean(类)不断优化的..................................

好了,javax.sql的连结先说到这儿吧,今天是周六,出去玩一会了(广州街头上没有什么美女!)
分享到:
评论

相关推荐

    JDBCJDBC高级应用

    JDBC高级应用JDBC高级应用JDBC高级应用JDBC高级应用

    你不知道的JDBC高级应用

    1.批处理:对数据库的CRUD速度会有质的飞跃.经常在对批量CUD的时候进行. 2.数据库连接池:把对数据库的连接放入一个容器中,要的时候就取,不需要的时候就还会去.程序启动的时候慢点,后期对数据库CRUD大幅度提升.(常用...

    使用JDBC的高级数据库操作

    本教程旨在向您介绍几种高级数据库操作, 包括存储过程和高级数据类型,它们可以通过使用 JDBC 的 ...我们推荐您先完成使用 JDBC 管理数据库连接这一教程。 其中的链接参考资料包括关于 JDBC 的补充信息的参考。

    加深难度-对标大厂SpringBoot高级应用特训 SpringBoot开发实践与高级应用

    课程内容在以往SpringBoot案例课程之上,再次加深了难度和深度,直接对标一线大厂的高级应用实践。课程围绕着SpringBoot开发实践和SpringBoot高级应用两个主题展开,是真正意义上的大厂级开发技术,同时技术拥有很强...

    jdbc的详细介绍

    1. 应用程序连接数据库的方式? 2. JDBC 能完成的功能: 3. JDBC API 包含的内容? 4. JDBC driver 5. JDBC Driver的种类. 6. JDBC 编程人员使用到的接口? 7. JDBC 编程中主要的接口和类 8. 使用唯一的URL确定数据库 9....

    完整版 Java高级教程 Java语言程序设计 第8章 JDBC(共24页).ppt

    完整版 Java高级教程 Java语言程序设计 第1章 输入输出流(共42页).ppt 完整版 Java高级教程 Java语言程序设计 第2章 Java多线程(共24页).ppt 完整版 Java高级教程 Java语言程序设计 第2章 哲学家的故事(共7页)...

    JAVA学习使用JDBC的高级特征创建应用程序PPT教案学习.pptx

    JAVA学习使用JDBC的高级特征创建应用程序PPT教案学习.pptx

    《JDBC API数据库编程实材作教材》[PDF]

    这是一本关于JDBC API数据库编程的书,主要介绍Java程序设计基础、 SQL基础知识、JDBC(Java数据库连接)应用、接口和类,以及如何在JSP和Servlet中使用JDBC,并以完整的实例程序说明 JDBC API(应用程序编程接口)...

    一本糊涂账-基于Swing和JDBC开发的图形界面桌面应用

    本项目是基于Swing和JDBC开发的图形界面桌面应用,涵盖了J2SE的绝大部分基础知识,通过这个项目能运用和锻炼几乎大部分的J2SE知识和技能。 基础内容: 面向对象 字符串数字 日期 中级内容: 异常 ,集合,JDBC,...

    JDBC 3.0数据库开发与设计

    第1章 JDBC概述 1.1 JDBC简介 1.2 JDBC3.0规范 1.3 JDBC3.0 API的新特点 1.3.1 JDBC 3.0 API的一致性 1.3.2 不赞成的API 1.4 JDBC 3.0中的类和接口 1.4.1 java.sql包中的类和接口及其使用 1.4.2 javax.sql...

    jdbc编程[归纳].pdf

    作为一名软件开发者,掌握 JDBC 编程是非常重要的,因为 JDBC 是 Java 应用程序与数据库交互的桥梁。JDBC 提供了一个通用的接口,允许 Java 应用程序与不同的数据库管理系统交互。 在本文档中,我们将从基础开始,...

    jdbc笔记(自写)

    JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序. ​ JDBC为访问不同的数据库提供了一种统一的途径,为开发者屏蔽了一些细节问题。 JDBC的目标是使Java程序员...

    JDBC专题(一)-JDBC入门.md

    JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序。 **JDBC需要连接驱动**,驱动是两个设备要进行通信,满足一定通信数据格式,数据格式由设备提供商规定,设备提供商...

    什么是 jdbc,及其的作用.md

    JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序。 以下是关于JDBC的详细解析: 一、JDBC的组成 JDBC主要由两部分组成:JDBC API和JDBC Driver API。 1. JDBC API...

    JDBC API教程与参考手册part3

    然后,本书转向更高级的主题,集中介绍JDBC 3.0API的一些高级功能,如可滚动和可更新的结果集、批量更新、SQL99数据类型、定制映射、保存点、语句池以及自动生成键等。 除了深入介绍JDBC元数据API之外,本书还给出了...

    java jdbc 项目实战

    JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供...JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序.

    JDBC API教程与参考手册part4

    然后,本书转向更高级的主题,集中介绍JDBC 3.0API的一些高级功能,如可滚动和可更新的结果集、批量更新、SQL99数据类型、定制映射、保存点、语句池以及自动生成键等。 除了深入介绍JDBC元数据API之外,本书还给出了...

    JDBC精讲非扫描版

    JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句...JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序,该书精讲JDBC,不要你去一本超厚的书。

    jdbc api数据库编程实作教材

    jdbc api数据库编程实作教材 java高级应用 数据库编程

    JDBC API教程与参考手册part2

    然后,本书转向更高级的主题,集中介绍JDBC 3.0API的一些高级功能,如可滚动和可更新的结果集、批量更新、SQL99数据类型、定制映射、保存点、语句池以及自动生成键等。 除了深入介绍JDBC元数据API之外,本书还给出了...

Global site tag (gtag.js) - Google Analytics