整合数据库Word格式文档下载.docx
- 文档编号:6749102
- 上传时间:2023-05-07
- 格式:DOCX
- 页数:26
- 大小:85.24KB
整合数据库Word格式文档下载.docx
《整合数据库Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《整合数据库Word格式文档下载.docx(26页珍藏版)》请在冰点文库上搜索。
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数据库为例:
//localhost:
3306/demo?
user=root&
password=123
如果要使用中文访问,还必须给定参数useUnicode及characterEncoding,表明是否使用Unicode,并指定字符编码方式。
例:
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<
drivers.size();
i++){//逐一取得Driver实例
...
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!
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");
...
//用查询结果的字段顺序
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<
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中设置
<
web-app>
resource-ref>
res-ref-name>
jdbc/demo<
/res-ref-name>
res-type>
javax.sql.DataSource<
/res-type>
res-auth>
Container<
/res-auth>
res-sharing-scope>
Shareable<
/res-sharing-scope>
/resource-ref>
/web-app>
在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);
rs.updateString(3,"lsx@com.cc");
rs.updateRow();
如果取得ResultSet后想直接进行数据的新增,则要先调用moveToInsertRow(),之后调用updateXxx()设置要新增的数据的各个字段,然后调用insertRow()新增数据。
一个使用ResultSet新增数据的例子如下:
rs.moveToInsertRow();
rs.updateString(2,"");
rs.updateString(3,"");
rs.updateString(4,"");
rs.insertRow();
rs.moveToCurrentRow();
如果取得ResultSet后想直接进行数据的删除,则要移动数据光标至想删除的列,调用deleteRow()删除数据列。
一个使用ResultSet删除数据的例子:
Statementstmt=conn.prepareStatemen
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 整合 数据库