JDBC基础(一)
来,我们认识一下!
JDBC,Java平台的DATABASE的连通性.白话一句,什么意思啊?
就是JAVA平台上和数据库进行连结的"工具".
还是先一起来回顾一下接口吧:从下向上,接口是对"案例"的抽象,由一个案例抽象出一些规则.
反过来,从上向下,被抽象出来的接口是对案例的一种承诺和约束.
也就是说,只要你实现我规定的接口,你的类就已经具有了接口对外承诺的方法,只要"客户"会
操作接口,不需要重新学习就会操作实现了该接口的新类!
好了,用行话来说:
1.通过接口可以实现不相关的类的相同行为.
2.通过接口可以指明多个类需要实现的方法.
3.通过接口可以了解对象的交互方法而不需要了解对象所对应的类蓝本.
这几句话很明白吧?好象有一本什么模式的书把这段话用了30多页写出来,结果别人看了还不如
我这几句话明白,不过我明白了为什么有些人要写书了.
搞懂了以上这东西,JDBC就好明白了.
为了通用,JAVA中要求有一种机制,在操作不同厂商数据库时有相同的方法去操作,而不是每接
触一种数据库就要学习新的方法.完成这种机制的"东西"就叫"JDBC"了.
简单地分,JDBC有两部分组成,JDBC API和JDBC Driver Interface.
JDBC API就是提供给"客户"(就是象你我这种菜鸟级程序员来用的,如果是高手都自己写JDBC了,
哈哈)的一组独立于数据库的API,对任何数据库的操作,都可以用这组API来进行.那么要把这些通用的API
翻译成特定数据库能懂的"指令",就要由JDBC Driver Interface来实现了,所以这部份是面向JDBC驱动程
序开发商的编程接口,它会把我们通过JDBC API发给数据库的通用指令翻译给他们自己的数据库.
还是通过实际操作来看看JDBC如何工作的吧.
因为JDBC API是通用接口,那么程序是如何知道我要连结的是哪种数据库呢?所以在和数据库连
结时先要加载(或注册可用的Driver),其实就是JDBC签名.加载驱动程序和好多方法,最常用的就是先把驱
动程序类溶解到内存中,作为"当前"驱动程序.注意"当前"是说内存中可以有多个驱动程序,但只有现在加
载的这个作为首选连结的驱动程序.
Class.forName("org.gjt.mm.MySQL.Driver");
Class.forName方法是先在内存中溶解签名为"org.gjt.mm.mysql.Driver"的Driver类,Driver类
就会把相应的实现类对应到JDBC API的接口中.比如把org.gjt.mm.mysql.Connection的实例对象赋给
java.sql.Connection接口句柄,以便"客户"能通过操作java.sql.Connection句柄来调用实际的
org.gjt.mm.mysql.Connection中的方法.之于它们是如果映射的,这是厂商编程的,"客户"只要调用
Class.forName("org.gjt.mm.mysql.Driver");方法就可以顺利地操作JDBC API了.
一个普通数据库的连结过程为:
1.加载驱动程序.
2.通过DriverManager到得一个与数据库连结的句柄.
3.通过连结句柄绑定要执行的语句.
4.接收执行结果.
5.可选的对结果的处理.
6.必要的关闭和数据库的连结.
JDBC基础(二)
因为是基础篇,所以还是对每一步骤简单说明一下吧:
前面说是,注册驱动程序有多方法,Class.forName();是一种显式地加载.当一个驱
动程序类被Classloader装载后,在溶解的过程中,DriverManager会注册这个驱动类的实例.
这个调用是自动发生的,也就是说DriverManager.registerDriver()方法被自动调用了,当然
我们也可以直接调用DriverManager.registerDriver()来注册驱动程序,但是,以我的经验.
MS的浏览中APPLET在调用这个方法时不能成功,也就是说MS在浏览器中内置的JVM对该方法的
实现是无效的.
另外我们还可以利用系统属性jdbc.drivers来加载多个驱动程序:
System.setProperty("jdbc.drivers","driver1:driver2:.....:drivern");多个驱动程序之
间用":"隔开,这样在连结时JDBC会按顺序搜索,直到找到第一个能成功连结指定的URL的驱动
程序.
在基础篇里我们先不介绍DataSource这些高级特性.
在成功注册驱动程序后,我们就可以用DriverManager的静态方法getConnection来得
到和数据库连结的引用:
Connection conn = DriverManager.getConnection(url);
如果连结是成功的,则返回Connection对象conn,如果为null或抛出异常,则说明没有
和数据库建立连结.
对于getConnection()方法有三个重载的方法,一种是最简单的只给出数据源即:
getConnection(url),另一种是同时给出一些数据源信息即getConnection(url,Properties),
另外一种就是给出数据源,用户名和密码:getConnection(url,user,passwod),对于数据源信息.
如果我们想在连结时给出更多的信息可以把这些信息压入到一个Properties,当然可以直接压
入用户名密码,别外还可以压入指定字符集,编码方式或默认操作等一些其它信息.
在得到一个连结后,也就是有了和数据库找交道的通道.我们就可以做我们想要的操
作了.
还是先来介绍一些一般性的操作:
如果我们要对数据库中的表进行操作,要先缘故绑定一个语句:
Statement stmt = conn.createStatement();
然后利用这个语句来执行操作.根本操作目的,可以有两种结果返回,如果执行的查询
操作,返回为结果集ResultSet,如果执行更新操作,则返回操作的记录数int.
注意,SQL操作严格区分只有两个,一种就是读操作(查询操作),另一种就是写操作(更
新操作),所以,create,insert,update,drop,delete等对数据有改写行为的操作都是更新操作.
ResultSet rs = stmt.executeQuery("select * from table where xxxxx");
int x = stmt.executeUpdate("delete from table where ......");
如果你硬要用executeQuery执行一个更新操作是可以的,但不要把它赋给一个句柄,
当然稍微有些经验的程序员是不会这么做的.
至于对结果集的处理,我们放在下一节讨论,因为它是可操作的可选项,只有查询操作
才返回结果集,对于一次操作过程的完成,一个非常必要的步骤是关闭数据库连结,在你没有了
解更多的JDBC知识这前,你先把这一步骤作为JDBC操作中最最重要的一步,在以后的介绍中我会
不断地提醒你去关闭数据库连结!!!!!!!!!!!
按上面介绍的步骤,一个完成的例子是这样的:(注意,为了按上面的步骤介绍,这个例
子不是最好的)
try{
Class.forName("org.gjt.mm.mysql.Driver");
}catch(Exception e){
System.out.println("没有成功加载驱动程序:"+e.toString());
return;
}//对于象我这样的经验,可以直接从e.toString()的简单的几个字判断出异常原因,
//如果你是一个新手应该选捕获它的子类,如何知道要捕获哪几个异常呢?一个简单
//的方法就是先不加try{},直接Class.forName("org.gjt.mm.mysql.Driver");,编
//译器就会告诉你要你捕获哪几个异常了,当然这是偷机取巧的方法,最好还是自己
//去看JDK文档,它会告诉你每个方法有哪些异常要你捕获.
Connection conn = null;
try{
conn = DriverManager.getConnection(
"jdbc:mysql://host:3306/mysql",
"user",
"passwd");
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from table");
//rs 处理
[rs.close();]
[stmt.close();]
}
catch(Exception e){
System.out.println("数据库操作出现异常:"+e.toString());
}
finally{
try{conn.close();}catch(Exception){}
}//不管你以前是学习到的关于数据库流程是如何操作的,如果你相信我,从现在开始,
//请你一定要把数据库关闭的代码写到finally块中,切切!
JDBC基础(三)
关于Statement对象:
前面说过,Statement对象是用来绑定要执行的操作的,在它上面有三种执行方法:
即用来执行查询操作的executeQuery(),用来执行更新操作的executeUpdate()和用来执行
动态的未知的操作的execute().
JDBC在编译时并不对要执行的SQL语句检测,只是把它看着一个String,只有在驱动
程序执行SQL语句时才知道正确与否.
一个Statement对象同时只能有一个结果集在活动.这是宽容性的,就是说即使没有
调用ResultSet的close()方法,只要打开第二个结果集就隐含着对上一个结果集的关闭.所以
如果你想同时对多个结果集操作,就要创建多个Statement对象,如果不需要同时操作,那么可
以在一个Statement对象上须序操作多个结果集.
这里我不得不特别说明一下,很多人会用一个Statement进行嵌套查询,然后就来问
我说为什么不能循环?道理上面已经说清楚了.我们来详细分析一下嵌套查询:
Connection conn = null;
Statement stmt = null;
conn = .......;
stmt = conm.createStatement(xxxxxx);
ResultSet rs = stmt.executeQuery(sql1);
while(rs.next()){
str = rs.getString(xxxxx);
ResultSet rs1 = stmt.executeQuery("select * from 表 where 字段=str");
}
当stmt.executeQuery("select * from 表 where 字段=str");赋给rs1时,这时隐含的操作
是已经关闭了rs,你还能循环下去吗?
所以如果要同时操作多个结果集一定要让它他绑定到不同的Statement对象上.好在一个connection
对象可以创建任意多个Statement对象,而不需要你重新获取连结.
关于获取和设置Statement的选项:只要看看它的getXXX方法和setXXX方法就明白了,这儿
作为基础知识只提一下以下几个:
setQueryTimeout,设置一个SQL执行的超时限制.
setMaxRows,设置结果集能容纳的行数.
setEscapeProcessing,如果参数为true,则驱动程序在把SQL语句发给数据库前进行转义替
换,否则让数据库自己处理,当然这些默认值都可以通过get方法查询.
Statement的两个子类:
PreparedStatement:对于同一条语句的多次执行,Statement每次都要把SQL语句发送给数据
库,这样做效率明显不高,而如果数据库支持预编译,PreparedStatement可以先把要执行的语句一次发
给它,然后每次执行而不必发送相同的语句,效率当然提高,当然如果数据库不支持预编译,
PreparedStatement会象Statement一样工作,只是效率不高而不需要用户工手干预.
另外PreparedStatement还支持接收参数.在预编译后只要传输不同的参数就可以执行,大大
提高了性能.
PreparedStatement ps = conn.prepareStatement("select * from 表 where 字段=?");
ps.setString(1,参数);
ResultSet rs = ps.executeQuery();
CallableStatement:是PreparedStatement的子类,它只是用来执行存储过程的.
CallableStatement sc = conn.prepareCall("{call query()}");
ResultSet rs = cs.executeQuery();
关于更高级的知识我们在JDBC高级应用中介绍.
JDBC基础(四)
作为基础知识的最后部分,我们来说一说结果集的处理,当然是说对一般结果集的处理.
至于存储过程返回的多结果集,我们仍然放在高级应用中介绍.
SQL语句如何执行的是查询操作,那就要返回一个ResultSet对象,要想把查询结果最后
明白地显示给用户,必须对ResultSet进行处理.ResultSet返回的是一个表中符合条件的记录,对
ResultSet的处理要逐行处理,而对于每一行的列的处理,则可以按任意顺序(注意,这只是JDBC规
范的要求,有些JDBC实现时对于列的处理仍然要求用户按顺序处理,但这是极少数的).事实上,虽
然你可以在处理列的时候可以按任意顺序,但如果你按从左到右的顺序则可以得到较高的性能.
这儿从底层来讲解一下ResultSet对象,在任何介绍JDBC的书上你是不会获得这样的知
识的,因为那是数据库厂商的事.ResultSet对象实际维护的是一个二维指针,第一维是指向当前
行,最初它指向的是结果集的第一行之前,所以如果要访问第一行,就要先next(),以后每一行都
要先next()才能访问,然后第二维的指针指向列,只要当你去rs.getXXX(列)时,才通过
Connection再去数据库把真实的数据取出来,否则没有什么机器能真的把要取的数据都放在内
存中.
所以,千万要记住,如果Connection已经关闭,那是不可能再从ResultSet中取到数据的.
有很多人问我,我可不可以取到一个ResultSet把它写到Session中然后关闭Connection,这样就
不要每次都连结了.我只能告诉你,你的想法非常好,但,是错误的!当然在javax.sql包中JDBC高
级应用中有CacheRow和WebCacheRow可以把结果集缓存下来,但那和我们自己开一个数据结构把
ResultSet的行集中所有值一次取出来保存起来没有什么两样.
访问行中的列,可以按字段名或索引来访问.下面是一个简单的检索结果的程序:
ResultSet rs = stmt.executeQuery("select a1,a2,a3 from table");
while(rs.next()){
int i = rs.getInt(1);
String a = rs.getString("a2");
..............
}
对于用来显示的结果集,用while来进行next()是最普通的,如果next()返回false,则
说明已经没有可用的行了.但有时我们可能连一行都没有,而如果有记录又不知道是多少行,这时
如果要对有记录和没有记录进行不同的处理,应该用以下流程进行判断:
if(rs.next()){
//因为已经先next()了,所经对记录应该用do{}while();来处理
do{
int i = rs.getInt(1);
String a = rs.getString("a2");
}while(rs.next());
}
esle{
System.out.println("没有取得符合条件的记录!");
}
类型转换:
ResultSet的getXXX方法将努力把结果集中的SQL数据类型转换为JAVA的数据类型,事实
大多数类型是可以转换的,但仍然有不少糊弄是不能转换的,如你不能将一个SQL的float转换成
JAVA的DATE,你无法将 VARCHAR "我们"转换成JAVA的Int.
较大的值:
对于大于Statement中getMaxFieldSize返回值的值,用普通的getBytes()或getString()
是不能读取的,好在JAVA提供了读取输入浪的方法,对于大对象,我们可以通过rs.getXXXStream()
来得到一个InputStream,XXX的类型包括Ascii,Binay,Unicode.根据你存储的字段类型来使用不
同的流类型,一般来说,二进制文件用getBinayStream(),文本文件用getAsciiStyream(),对于
Unicode字符的文本文件用getUnicodeStream(),相对应的数据库字段类型应该为:Blob,Clob和
Nlob.
获取结果集的信息:
大多数情况下编程人员对数据库结构是了解的,可以知道结果集中各列的情况,但有时并
不知道结果集中有哪些列,是什么类型.这时可以通过getMetaData()来获取结果集的情况:
ResulSetMetaData rsmd = rs.getMetaData();
rsmd.getColumnCount()返回列的个数.
getColumnLabel(int)返回该int所对应的列的显示标题
getColumnName(int)返回该int所对应的列的在数据库中的名称.
getColumnType(int)返回该int所对应的列的在数据库中的数据类型.
getColumnTypeName(int)返回该int所对应的列的数据类型在数据源中的名称.
isReadOnly(int)返回该int所对应的列是否只读.
isNullable(int)返回该int所对应的列是否可以为空
FROM:http://blog.csdn.net/mayfar/article/details/1559797
相关推荐
JDBC基础JDBC基础JDBC基础JDBC基础JDBC基础JDBC基础JDBC基础JDBC基础JDBC基础
"jdbc 基础的详解与总结" jdbc 是一套协议,由 Sun 公司定义的一组接口,由数据库厂商来实现,并规定了 Java 开发人员访问数据库所使用的方法的调用规范。jdbc 的实现是由数据库厂商提供,以驱动程序形式提供。jdbc...
**JDBC基础实例详解** Java Database Connectivity (JDBC) 是Java平台中用于与关系数据库进行交互的一种标准接口。它是Java编程语言的一部分,允许应用程序通过Java代码执行SQL语句,实现数据的增删改查操作。对于...
**JDBC基础知识** Java Database Connectivity (JDBC)是Java编程语言中用于标准地访问数据库的API。它由一组Java类和接口组成,允许Java应用程序连接到各种类型的数据库系统,包括Oracle、MySQL、SQL Server等。...
JDBC基础.chmJDBC基础.chm
**JDBC基础学习目标:** 1. **理解Java中的数据库连接**:了解Java如何通过JDBC API与各种类型的数据库(如关系型、面向对象关系型和面向对象数据库)建立连接。 2. **掌握JDBC API**:熟悉java.sql包中的核心类和...
**JDBC基础知识详解** Java Database Connectivity (JDBC) 是Java平台上的一个标准API,用于与关系型数据库进行交互。它是Java开发者访问数据库的唯一、统一的接口,由Sun Microsystems(现已被Oracle收购)定义,...
jdbc基础篇教程md版:这份markdown格式的教程详细介绍了jdbc的基础概念、配置方法以及如何通过jdbc进行数据库的增删改查(crud)操作。教程内容涵盖了jdbc驱动的加载、数据库连接的建立、sql语句的执行以及结果集的...
了解JDBC的概念及必要性 了解JDBC驱动程序类型 理解JDBC 程序的结构 运用JDBC进行数据库编程
### JDBC基础知识总结 #### 一、概述 JDBC(Java Database Connectivity)是一种标准的Java API,用于连接并操作各种类型的数据库。它从物理结构上说就是一套Java语言访问数据库的接口集合,本质上则是调用者...
### JDBC基础教程之ResultSet对象详解 #### 一、ResultSet对象概览 `ResultSet`对象是Java Database Connectivity (JDBC) API中的一个核心组件,用于处理SQL查询结果。它充当了一个临时的数据存储,其中包含了所有...
### JDBC基础教程之连接知识点详解 #### 一、Connection对象及其作用 - **Connection对象**:在JDBC中,`Connection`对象代表了一个与数据库之间的连接。通过这个连接,应用程序可以执行SQL语句并获取结果集。 - *...
**JDBC基础入门详解** Java Database Connectivity(JDBC)是Java平台中用于与数据库交互的一组接口和类,它是Java标准API的一部分,使得Java开发者能够访问各种类型的数据库系统。本篇将详细介绍JDBC的基础知识,...
### JDBC基础教程之概述 #### 一、JDBC简介与概念理解 JDBC(Java Database Connectivity)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC的...
【JDBC基础】 JDBC(Java Database Connectivity)是Java编程语言中用于访问数据库的标准Java API,它允许Java开发者在程序中执行SQL语句并与各种数据库进行交互。JDBC为Java程序员提供了一种统一的方式来连接和操作...
在学习JDBC基础时,主要涉及以下几个关键知识点: 1. **快速入门**: - 安装Java和JDBC:确保你拥有与JDBC兼容的JDK版本,通常JDBC会随JDK一起安装。 - 安装驱动程序:根据选择的数据库,安装相应的JDBC驱动,如...
Java操作数据库JDBC基础demo是Java开发者必备的技能之一,JDBC(Java Database Connectivity)是Java语言连接数据库的标准API,它允许Java程序与各种不同类型的数据库进行交互。在这个基础demo中,我们将涵盖JDBC的...
**JDBC基础——深入理解与实践** Java Database Connectivity(JDBC)是Java平台中用于与关系型数据库交互的标准API,它允许Java程序通过编写Java代码来执行SQL语句,进行数据查询、插入、更新和删除等操作。了解并...