整合数据库.docx

上传人:b****3 文档编号:4583581 上传时间:2023-05-07 格式:DOCX 页数:26 大小:85.24KB
下载 相关 举报
整合数据库.docx_第1页
第1页 / 共26页
整合数据库.docx_第2页
第2页 / 共26页
整合数据库.docx_第3页
第3页 / 共26页
整合数据库.docx_第4页
第4页 / 共26页
整合数据库.docx_第5页
第5页 / 共26页
整合数据库.docx_第6页
第6页 / 共26页
整合数据库.docx_第7页
第7页 / 共26页
整合数据库.docx_第8页
第8页 / 共26页
整合数据库.docx_第9页
第9页 / 共26页
整合数据库.docx_第10页
第10页 / 共26页
整合数据库.docx_第11页
第11页 / 共26页
整合数据库.docx_第12页
第12页 / 共26页
整合数据库.docx_第13页
第13页 / 共26页
整合数据库.docx_第14页
第14页 / 共26页
整合数据库.docx_第15页
第15页 / 共26页
整合数据库.docx_第16页
第16页 / 共26页
整合数据库.docx_第17页
第17页 / 共26页
整合数据库.docx_第18页
第18页 / 共26页
整合数据库.docx_第19页
第19页 / 共26页
整合数据库.docx_第20页
第20页 / 共26页
亲,该文档总共26页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

整合数据库.docx

《整合数据库.docx》由会员分享,可在线阅读,更多相关《整合数据库.docx(26页珍藏版)》请在冰点文库上搜索。

整合数据库.docx

整合数据库

整合数据库

星辰樱

1、JDBC入门

JDBC是用于执行SQL的解决方案,开发人员使用JDBC的标准接口,数据库厂商则对接口进行实现。

1.1JDBC简介

应用程序通信协议JDBC标准API

程序库数据库JDBC驱动程序程序库

JDBC全名JavaDataBaseConnectivity,是Java数据库连接的标准规范。

具体而言,这定义一组标准类与接口,应用程序需要连接数据库时就调用这组标准API,而标准API中的接口会由数据库厂商实现,通常称为JDBC驱动程序(Driver)。

JDBC标准主要分为两个部分:

JDBC应用程序开发者接口(ApplicationDeveloperInterface)以及JDBC驱动程序开发者接口(DriverDeveloperInterface)。

厂商在实现JDBC驱动程序时,按方式可以将驱动程序分为四种类型。

·Type1:

JDBC-ODBCBridgeDriver。

优:

实现简单缺:

弹性不足,跨平台有限制

·Type2:

NativeAPIDriver。

优:

速度最快缺:

无法跨平台,是基于C/C++

·Type3:

JDBC-NetDriver。

优:

架构上有弹性,可跨平台。

缺:

速度慢。

·Type4:

NativeProtocolDriver。

优:

可跨平台。

缺:

没有弹性。

中庸型

1.2连接数据库

基本数据库操作相关的JDBC接口或类位于java.sql包中。

要取得数据库连接,必须有几个操作:

·注册Driver实现对象

·取得Connection实现对象

·关闭Connection实现对象

1.注册Driver实现对象

实现Driver接口的对象是JDBC进行数据库访问的起点,以MySQL实现的驱动程序为例,com.mysql.jdbc.Driver类实现了java.sql.Driver接口,管理Driver实现对象的类是java.sql.DriverManager,基本上,必须调用其静态方法registerDriver()进行注册:

DriverManager.registerDriver(newcom.mysql.jdbc.Driver());

不过实际上很少自行编写代码进行这个操作,只要想办法加载Driver接口的实现类.class文件,就会完成注册。

例如,可以通过java.lang.Class类的forName(),动态加载驱动程序类:

Class.forName("com.mysql.jdbc.Driver");

第二种方式直接编写代码:

java.sql.Driverdriver=newcom.mysql.jdbc.Driver();

第三种方式就是运行java命令时如下:

>java-Djdbc.drivers=com.mysql.jdbc.Driver;ooo.XXXDriverYourProgram

你有应用程序可能同时连接多个厂商的数据库,所以DriverManager也可以注册多个驱动程序实例。

以上方式如果需要指定多个驱动程序类时,就是用分号隔开。

第四种方式是JavaSE6之后JDBC4.0的新特性:

只要在驱动程序实现的JAR文件/services文件夹中,放置一个java.sql.Driver文件,当中编写Driver接口的实现类名称全名,DriverManager会自动读取这个文件并找到指定类进行注册。

2.取得Connection实现对象

Connection接口的实现对象,是数据库连接代表对象。

要取得Connection实现对象,可以通过DriverManager的getConnection();

Connectionconn=DriverManager.getConnection(jdbcUrl,username,password);

提供JDBCURL,其定义了连接数据库时的协议、子协议、数据源标识:

协议:

子协议:

数据源标识

以MySQL的JDBCURL编写方式如下:

jdbc:

mysql:

//主机名称:

连接端口/数据库名称?

参数=值&参数=值

主机名称可以是本机(localhost)或其他连接主机名称、地址,MySQL连接端口默认认为3306。

以连接demo数据库为例:

jdbc:

mysql:

//localhost:

3306/demo?

user=root&password=123

如果要使用中文访问,还必须给定参数useUnicode及characterEncoding,表明是否使用Unicode,并指定字符编码方式。

例:

jdbc:

mysql:

//localhost:

3306/demo?

user=root&password=123&useUnicode=true&characterEncoding=UTF-8

SQLException是在处理JDBC时经常遇到的一个异常对象,为数据库操作过程发生错误时的代表对象。

SQLException是受检异常(CheckedException),必须使用try...catch明确处理,在异常发生时尝试关闭相关资源。

SQLException有个子类SQLWarning,如果数据库执行过程中发生了一些警示信息,会创建SQLWarning但不会抛出(throw),而是以链接方式收集起来,可以使用Connection、Statement、ResultSet的getWarnings()来取得第一个SQLWarning,使用这个对象的getNextWaring()可以取得下一个SQLWarning。

由于它是SQLException的子类,所以必须时也可以当作异常抛出。

3.关闭Connection实现对象

取得Connection对象之后,可以使用isClosed()方法测试与数据库的连接是否关闭。

在操作完数据库之后,若确定不需要连接,则必须使用close()来关闭与数据库的连接,以释放连接时相关的必要资源,如连接相关对象、授权资源等。

在底层,DriverManager如何进行连接呢?

DriverManager会在循环中逐一取出注册的每个Driver实例,使用指定的JDBCURL来调用Driver的connect()方法,尝试取得Connection实例。

重点源代码节录:

SQLExceptionreason=null;

for(inti=0;i

...

DriverInfodi=(DriverInfo)drivers.elementAt(i);

try{

Connectionresult=di.driver.connect(url,info);//尝试连接

if(result!

=null){

return(result);//取得Connection就返回

}

}catch(SQLExceptionex){

if(reason==null){//记录第一个发生的异常

reason=ex;

}

}

}

if(reason!

=null){

println("getConnectionfailed:

"+reason);

throwreason;//如果有异常对象就抛出

}

//没有适用的Driver实例,抛出异常

thrownewSQLException("Nosuitabledriverfoundfor"+url,"08001");

实际上Web应用程序很少直接从DriverManager中取得Connection,而是会通过JNDI从服务器上取得设置好的DataSource,再从DataSource取得Connection。

1.3使用Statement、ResultSet

Connection是数据库接连的代表对象,接下来若要执行SQL,必须取得java.sql.statement对象,它是SQL语句的代表对象,可以使用Connection的createStatement()来创建Statement对象:

Statementstmt=conn.createStatement();

取得Statement对象之后,可以使用executeUpdate()、executeQuery()等方法来执行SQL。

executeUpdate()主要是用来执行CREATETABLE、INSERT、DROPTABLE、ALTERTABLE等会改变数据库内容的SQL。

executeQuery()方法则是用于SELECT等查询数据库的SQL,executeUpdate()会返回int结果,表示数据变动的笔数,executeQuery()会返回java.sql.ResultSet对象,代表查询的结果,查询的结果会是一笔一笔的数据。

可以使用ResultSet的next()来移动至下一笔数据,它会返回true或false表示是否有一笔数据,接着可以使用getXXX()来取得数据,如getString()、getInt()、getFloat()等方法,分别取得相应的字段类型数据。

getXXX()方法都提供有依据字段名称取得数据,或是依据字段顺序取得数据的方法。

例:

ResultSetrs=stmt.executeQuery("select*fromtable");

//用指定字段名称

while(rs.next()){

intid=ts.getInt("id");

 ...

}

//用查询结果的字段顺序

while(rs.next()){

intid=ts.getInt

(1);

 ...

}

Statement的execute()可以用来执行SQL,并可以测试所执行的SQL是执行查询或更新,返回true的话表示SQL执行将返回ResultSet表示查询结果,此时可以使用getResultSet()取得ResultSet对象。

如果execute()返回false,表示SQL执行会返回更新笔数或没有结果,此时可以使用getUpdateCount()取得更新笔数。

如果事先无法得知是进行查询或更新,就可以使用execute()。

例:

if(stmt.execute(sql)){

ResultSetrs=stmt.getResultSet();//取得查询结果ResultSet

...

}else{

intupdated=stmt.getUpdateCount();//取得更新笔数

 ...

}

1.4使用PreparedStatement、CallableStatement

Statement在执行executeQuery()、executeUpdate()等方法时,如果有些部分是动态的数据,必须使用+运算子串接字符以组成完整的SQL语句,十分方便。

例:

statement.executeUpdate("insertintotable(id,...)values(

'"+对象.getName()+"',...)");

如果有些操作只是SQL语句中某些参数会有所不同,其余的SQL子句皆相同,则可以使用java.sql.PreparedStatement。

可以使用Connection的preparedStatement()方法创建好一个预编译(precompile)的SQL语句,当中参数会变动的部分,先指定“?

”这个占位字符。

例:

PreparedStatementstmt=conn.prepareStatement("insertintotablevalues(?

)");

等到需要真正指定参数执行时,再使用相对应的setInt()、setString()等方法,指定“?

”处真正应该有的参数。

例:

stmt.setInt(1,2);或stmt.setInt(1,对象.getId());

让SQL执行生效:

stmt.executeUpdate();或stmt.executeQuery();

在这次的SQL执行完毕后,可以调用clearParameters()清除所设置的参数,之后就可以再使用这个PreparedStatement实例,所以使用PreparedStatement,可以让你先准备好一段SQL,并重复使用这段SQL语句。

如果编写数据库的存储过程(StoredProcedure),并想使用JDBC来调用,则可使用java.sql.CallableStatement。

调用的基本语法如下:

{?

=call<程序名称>[<自变量1>,<自变量2>,...]}

{call<程序名称>[<自变量1>,<自变量2>,...]}

CallableStatement的API使用,基本上与PreparedStatement差别不大,除了必须调用prepareCall()创建CallableStatement时异常,一样是使用setXXX()设置参数,如果是查询操作,使用executeQuery();如果是更新操作,使用executeUpdate()。

另外,可以使用registerOutParameter()注册输出参数等。

在使用PreparedStatement或CallableStatement时,必须注意SQL类型与Java数据类型的对应。

Java类型与SQL类型对应

Java类型

SQL类型

boolean

BIT

byte

TINYINT

short

SMALLINT

int

INTEGER

long

BINGNT

float

FLOAT

double

BOUBLE

byte[]

BINARY、VARBINARY、LONGBINARY

java.lang.String

CHAR、VARCHAR、LONGVARCHAR

java.math.BigDecimal

NUMRIC、DECIMAL

java.sql.Date

DATE日期格式:

年、月、日

java.sql.Time

TIME时间格式:

时、分、秒

java.sql.Timestamp

TIMESTAMP时间格式:

时、分、秒、微秒

2、JDBC进阶

2.1使用DataSource取得连接

要取得数据库连接,必须打开网络连接(中间经过实体网络),连接至数据库服务器后,进行协议交换(当然也就是数次的网络数据往来)以进行验证名称、密码等确认动作。

也就是取得数据库连接是件耗时间及资源的动作。

尽量利用已打开的连接,也就是重复利用取得的Connection实例,是改善数据库连接性能的一个方式,采用连接池是基本做法。

在JavaEE的环境中,将取得连接等与数据库来源相关的行为规范在javax.sql.DataSource接口,实际如何取得Connection则由实现接口的对象来负责。

所以问题简化到如何取得DataSource实例。

为了让应用程序在需要取得某些与系统相关的资源对象时,能与实际的系统源配置、实体机器位置、环境架构等无关,在Java应用程序中可以通过JNDI(JavaNamingDirectoryInterface)来取得所需的资源对象。

例:

try{

ContextinitContext=newInitialContext();

ContextenvContext=(Context)initContext.lookup("java:

/comp/env");

dataSource=(DataSource)envContext.lookup("jdbc/demo");

}catch(NamingExceptionex){...}

在创建Context对象的过程中会收集环境相关数据,之后根据JNDI名称:

jdbc/demo向JNDI服务器查找DataSource实例并返回。

在这个代码段中,不会知道实际的资源配置、实体机器位置、环境架构等信息,应用程序不会与这些信息发生相关。

例:

web.xml中设置

...

jdbc/demo

javax.sql.DataSource

Container

Shareable

...

在web.xml中设置的目的,是要让web容器提供JNDI查找时所需的相关环境信息,这样创建Context对象时就不用设置一堆参数。

2.2使用ResultSet卷动、更新数据

在ResultSet时,默认可以使用next(()移动数据光标至下一个数据,而后使用getXXX()方法来取得数据。

实际上,从JDBC2.0开始,ResultSet并不仅可以使用previous()、first()、last()等方法前后移动数据光标,还可以调用updateXXX()、updateRow()等方法进行数据修改。

在使用Connection的createStatement()或prepareStatement()方法创建Statement或PreparedStatement实例时,可以指定结果集类型与并列方式:

createStatement(intresultSetType,intresultSetConcurrency)

prepareStatement(Stringsql,intresultSetType,intresultSetConcurrency)

结果集类型可以指定三种设置:

·ResultSet.TYPE_FORWARD_ONLY(默认)

·ResultSet.TYPE_SCROLL_INSENSITIVE

·ResultSet.TYPE_SCROLL_SENSITIVE

指定为TYPE_FORWARD_ONLY,ResultSet就只能前进数据光标,指定为TYPE_SCROLL_INSENSITIVE或TYPE_SCROLL_SENSITIVE,则ResultSet可以前后移动数据光标。

两者差别在于TYPE_SCROLL_INSENSITIVE设置下,取得的ResultSet不会反应数据库中的数据修改,而TYPE_SCROLL_SENSITIVE会反应数据库中的数据修改。

更新设置可以有两种指定:

·ResultSet.CONCUR_READ_ONLY(默认)

·ResultSet.CONCUR_UPDATABLE

指定为CONCUR_READ_ONLY,则只能用ResultSet进行数据读取,无法进行更新。

指定为CONCUR_UPDATABLE,就可以使用ResultSet进行数据更新。

在使用Connection的createStatement()或prepareStatement()方法创建Statement或PreparedStatement实例时,若没有指定结果集类型与并行方式,默认就是TYPE_FORWARD_ONLY与CONCUR_READ_ONLY。

如果想前后移动数据光标并想使用ResultSet进行更新,则以下是个Statement指定例子:

Statementstmt=conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);

以下是个PreparedStatement指定的例子:

PreparedStatementstmt=conn.prepareStatement("SQL语句",ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);

在数据光标移动的API上,可以使用absolute()、afterLast()、beforeFirst()、first()、last()进行绝对位置移动,使用relative()、previous()、next()进行相对位置移动,这些方法如果成功移动就会返回true。

也可以使用isAfterLast()、isBeforeFirst()、isFirst()、isLast()判断目前位置。

以下下个简单的程序范例片段:

Statementstmt=conn.createStatement("SQL语句",ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);

ResultSetrs=stmt.executeQuery();

rs.absolute

(2);//移至第2行

rs.next();//移至第3行

rs.first();//移至第1行

booleanb1=rs.isFirst();//b1是true

如果要使用ResultSet进行数据修改,则有些条件限制:

·必须选择单一表格

·必须选择主键

·必须选择所有NOTNULL的值

在取得ResultSet之后要进行数据更新,必须移动至要更新的行(Row),调用updateXxx()方法(Xxx是类型),而后调用updateRow()方法完成更新。

如果调用cancelRowUpdates()可取消更新,但必须在调用updateRow()前进更新的取消。

一个使用ResultSet更新数据的例子:

Statementstmt=conn.prepareStatement("SQL语句",ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);

ResultSetrs=stmt.executeQuery();

rs.next();

rs.updateString(3,"lsx@com.cc");

rs.updateRow();

如果取得ResultSet后想直接进行数据的新增,则要先调用moveToInsertRow(),之后调用updateXxx()设置要新增的数据的各个字段,然后调用insertRow()新增数据。

一个使用ResultSet新增数据的例子如下:

Statementstmt=conn.prepareStatement("SQL语句",ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);

ResultSetrs=stmt.executeQuery();

rs.moveToInsertRow();

rs.updateString(2,"");

rs.updateString(3,"");

rs.updateString(4,"");

rs.insertRow();

rs.moveToCurrentRow();

如果取得ResultSet后想直接进行数据的删除,则要移动数据光标至想删除的列,调用deleteRow()删除数据列。

一个使用ResultSet删除数据的例子:

Statementstmt=conn.prepareStatemen

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 法律文书 > 调解书

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2