JDBC关键技术以及面试问题Word文档格式.docx

上传人:b****6 文档编号:19262794 上传时间:2023-01-04 格式:DOCX 页数:7 大小:27.84KB
下载 相关 举报
JDBC关键技术以及面试问题Word文档格式.docx_第1页
第1页 / 共7页
JDBC关键技术以及面试问题Word文档格式.docx_第2页
第2页 / 共7页
JDBC关键技术以及面试问题Word文档格式.docx_第3页
第3页 / 共7页
JDBC关键技术以及面试问题Word文档格式.docx_第4页
第4页 / 共7页
JDBC关键技术以及面试问题Word文档格式.docx_第5页
第5页 / 共7页
点击查看更多>>
下载资源
资源描述

JDBC关键技术以及面试问题Word文档格式.docx

《JDBC关键技术以及面试问题Word文档格式.docx》由会员分享,可在线阅读,更多相关《JDBC关键技术以及面试问题Word文档格式.docx(7页珍藏版)》请在冰豆网上搜索。

JDBC关键技术以及面试问题Word文档格式.docx

导包0.参数化StringdriverName="

com.mysql.jdbc.Driver"

;

注册驱动Stringurl="

jdbc:

mysql:

//localhost:

3306/test"

//协议;

库或服务器名称;

服务器IP,端口Stringusername="

root"

Stringpassword="

/*Oracle的连接StringdriverName="

oracle.jdbc.driver.OracleDriver"

Stringurl="

oracle:

thin:

@192.168.0.23:

1521:

ora10g"

Stringusername="

openlab"

open123"

*///以下这些都需要写在有异常的代码块里,所以需要提取出来。

Connectionconn=null;

Statementstmt=null;

ResultSetrs=null;

//建议用PreparedStatement1.加载和注册数据库驱动Class.forName(driverName);

//自动注册;

需要把驱动的jar包导进来;

需处理异常/*方法二:

实例化具体的Driver驱动,这写法一般不用(不能参数化驱动名,不够灵活)Driverdriver=newcom.mysql.jdbc.Driver();

DriverManager.registerDriver(driver);

//将驱动交于DriverManager托管*//*方法三:

Dos运行时,java-Djdbc.drives=oracle.jdbc.driver.OracleDriver;

--可多个*/2.连接数据库conn=DriverManager.getConnection(url,username,password);

//需处理异常//Connection返回数据库连接,如:

"

com.mysql.jdbc.Connection@1ffb8dc"

连接不成功则返回null3.创建Statement对象//为了类型安全和批量更新的效率,改用PreparedStatementstmt=conn.createStatement();

//需处理异常//返回其生成结果的对象"

oracle.jdbc.driver.OracleStatement@198dfaf"

4.操作数据库,执行SQL语句Stringsql="

select*fromtableName"

//SQL语句里不需要写分号rs=stmt.executeQuery(sql);

//executeQuery(sqlString)查询返回查询结果集/*Stringsql="

insertintotableNamevalues(?

?

)"

//?

占位符intnumber=stmt.executeUpdate(sql);

//更新,再返回int(更新、修改影响的条数)*/5.处理数据(游标)//创建索引StringBuffersb=newStringBuffer();

//缓存;

用它可提高读取速度。

当然,不用也可以。

ResultSetMetaDatamd=rs.getMetaData();

//ResultSetMetaData可获取列的类型和属性信息intcol=md.getColumnCount();

//获取列的数目while(rs.next()){//rs.next()使游标下移一位,返回boolean,没有下一个结果则返回falsefor(inti=1;

i<

=col;

i++){//index(JDBC的下标从1开始)sb.append(md.getColumnName(i)+"

="

+rs.getString(i)+"

"

);

}sb.append("

\n"

}System.out.println(sb);

//1.游标的初始位置在第一条记录的前面,使第一次调用next()后,刚好拿到第一个结果。

//2.游标的最终位置在最后一条记录的后面(结果集的前面和后面留空,真正存在)6.释放资源,断开与数据库的连接//先判断是否有引用资源,再释放(释放空资源会抛异常);

注意顺序if(rs!

=null)try{rs.close();

}catch(Exceptione){e.printStackTrace();

}if(stmt!

=null)try{stmt.close();

}if(conn!

=null)try{conn.close();

}//这些异常没法处理,处理只为方便调试。

所以这些异常处理也只是打印。

/*要按先ResultSet结果集,后Statement,最后Connection的顺序关闭资源,因为ResultSet需要Statement和Connection连接时才可以用的;

Statement也需要Connection才可用;

结束Statement之后有可能其它的Statement还需要连接,因此不能先关闭Connection。

ResultSet同理。

*/步骤1、2、6每次都一样,可以重构。

因为加载驱动是个一次性工作,所以可以采用静态初始化块来加载驱动;

连接数据库的方法应该自己负责,获取数据库连接信息和驱动的信息,并处理相关异常;

释放数据库资源的方法要考虑到ResultSet、Statement、Connection的不同情况,并处理相关异常。

三、JDBC几个重要接口重点讲解在JDBC中包括了两个包:

java.sql和javax.sql。

①java.sql基本功能。

这个包中的类和接口主要针对基本的数据库编程服务,如生成连接、执行语句以及准备语句和运行批处理查询等。

同时也有一些高级的处理,比如批处理更新、事务隔离和可滚动结果集等。

②javax.sql扩展功能。

它主要为数据库方面的高级操作提供了接口和类。

如为连接管理、分布式事务和旧有的连接提供了更好的抽象,它引入了容器管理的连接池、分布式事务和行集等。

API说明Connection与特定数据库的连接(会话)。

能够通过getMetaData方法获得数据库提供的信息、所支持的SQL语法、存储过程和此连接的功能等信息。

代表了数据库。

Driver每个驱动程序类必需实现的接口,每个数据库驱动程序也都应该提供一个实现Driver接口的类。

DriverManager(Class)管理一组JDBC驱动程序的基本服务。

作为初始化的一部分,此接口会尝试加载在"

jdbc.drivers"

系统属性中引用的驱动程序。

只是一个辅助类,是工具。

Statement用于执行静态SQL语句并返回其生成结果的对象。

PreparedStatement继承Statement接口,表示预编译的SQL语句的对象,SQL语句被预编译并且存储在PreparedStatement对象中。

然后可以使用此对象高效地多次执行该语句。

CallableStatement用来访问数据库中的存储过程。

它提供了一些方法来指定语句所使用的输入/输出参数。

ResultSet指的是查询返回的数据库结果集。

ResultSetMetaData可用于获取关于ResultSet对象中列的类型和属性信息的对象。

注:

除了标出的Class,其它均为接口。

每个都是"

java.sql."

包下的。

1.Statement--SQL语句执行接口代表了一个数据库的状态,在向数据库发送相应的SQL语句时,都需要创建Statement接口或PreparedStatement接口。

在具体应用中,Statement主要用于操作不带参数(可以直接运行)的SQL语句,比如删除语句、添加或更新。

2.PreparedStatement:

预编译的Statement第一步:

通过连接获得PreparedStatement对象,用带占位符(?

)的sql语句构造。

PreparedStatementpstm=con.preparedStatement("

select*fromtestwhereid=?

第二步:

设置参数pstm.setString(1,"

ganbin"

//第一个字段是"

需一个个字段写第三步:

执行sql语句Rs=pstm.excuteQuery();

statement发送完整的Sql语句到数据库不是直接执行而是由数据库先编译,再运行。

每次都需要编译。

而PreparedStatement是先发送带参数的Sql语句,由数据库先编译,再发送一组组参数值。

(同构时不需重复编译)如果是同构的sql语句,PreparedStatement的效率要比statement高。

而对于异构的sql则两者效率差不多。

一般都用PreparedStatement代替Statement,因为它是类型安全的。

Statement对参数类型不作检查,故不够安全。

同构:

两个Sql语句可编译部分是相同的,只有参数值不同。

异构:

整个sql语句的格式是不同的注意点:

1、使用预编译的Statement编译多条Sql语句一次执行2、可以跨数据库使用,编写通用程序3、能用预编译时尽量用预编译4、如果第二个SQL语句与前一个是异构的,需要再次编译"

ps=con.prepareStatement(sql);

3.ResultSet--结果集操作接口ResultSet接口是查询结果集接口,它对返回的结果集进行处理。

ResultSet是程序员进行JDBC操作的必需接口。

4.ResultSetMetaData--元数据操作接口ResultSetMetaData是对元数据进行操作的接口,可以实现很多高级功能。

Hibernate运行数据库的操作,大部分都是通过此接口。

可以认为,此接口是SQL查询语言的一种反射机制。

ResultSetMetaData接口可以通过数组的形式,遍历数据库的各个字段的属性,对于开发者来说,此机制的意义重大。

JDBC通过元数据(MetaData)来获得具体的表的相关信息,例如,可以查询数据库中有哪些表,表有哪些字段,以及字段的属性等。

MetaData中通过一系列getXXX将这些信息返回给我们。

数据库元数据DatabaseMetaData用connection.getMetaData()获得;

包含了关于数据库整体元数据信息。

结果集元数据ResultSetMetaData用resultSet.getMetaData()获得;

比较重要的是获得表的列名,列数等信息。

结果集元数据对象:

ResultSetMetaDatameta=rs.getMetaData();

字段个数:

meta.getColomnCount();

字段名字:

meta.getColumnName();

字段JDBC类型:

meta.getColumnType();

字段数据库类型:

meta.getColumnTypeName();

数据库元数据对象:

DatabaseMetaDatadbmd=con.getMetaData();

数据库名:

dbmd.getDatabaseProductName();

数据库版本号:

dbmd.getDatabaseProductVersion();

数据库驱动名:

dbmd.getDriverName();

数据库驱动版本号:

dbmd.getDriverVersion();

数据库Url:

dbmd.getURL();

该连接的登陆名:

dbmd.getUserName();

四、JDBC中使用Transaction编程(事务编程)1.事务是具备以下特征(ACID)的工作单元:

原子性(Atomicity)--如果因故障而中断,则所有结果均被撤消;

一致性(Consistency)--事务的结果保留不变;

孤立性(Isolation)--中间状态对其它事务是不可见的;

持久性(Durability)--已完成的事务结果上持久的。

原子操作,也就是不可分割的操作,必须一起成功一起失败。

2.事务处理三步曲:

(事务是一个边界)①connection.setAutoCommit(false);

//把自动提交关闭;

在创建Statement对象之前。

②正常的DB操作//若有一条SQL语句失败了,自动回滚③mit()//主动提交和connection.rollback()//主动回滚,一般写在catch语句里,而前三

个都写在try语句里/*********事务的代码片段:

*************/try{con.setAutoCommit(false);

//step①把自动提交关闭Statementstm=con.createStatement();

//step②正常的DB操作stm.executeUpdate("

insertintoperson(id,name,age)values(520,'

X-Man'

18)"

stm.executeUpdate("

insertintoPerson(id,name,age)values(521,'

Super'

19)"

mit();

//step③成功主动提交}catch(SQLExceptione){try{con.rollback();

//如果中途发生异常,则roolback;

这语句也会抛异常}catch(Exceptione){e.printStackTrace();

}//step③失败则主动回滚/************************************/3.JDBC事务并发产生的问题和事务隔离级别(难,建议用例子学习)JDBC事务并发产生的问题:

PS:

重点①脏读(DirtyReads)一个事务读取了另一个并行事务还未提交的数据。

(产生原因:

读-写)②不可重复读(UnPrpeatableRead)一个事务前后两次读取数据时,得到的数据不一致,被另一个已提交的事务修改。

③幻读(PhantomRead)一个事务再次查询,记录中的量变化了。

(仅对统计有影响)为了避免以上三种情况的出现,则采用事务隔离级别:

TRANSACTION_NONE不使用事务(不可能用,只是理论的)TRANSACTION_READ_UNCOMMITTED可以读取未提交数据(允许脏读,也不可能)TRANSACTION_READ_COMMITTED只读提交的数据:

可防止脏读;

大部分数据库的默认隔离级别TRANSACTION_REPEATABLE_READ重复读取;

只可以避免脏读TRANSACTION_SERIALIZABLE事务串行化:

可以避免脏读,重复读取和幻读,但会降低数据库效率(最常用)以上的五个事务隔离级别都是在Connection类中定义的静态常量。

隔离级别越高,数据越安全,并发能力越差。

使用setTransactionIsolation(intlevel)方法可以设置事务隔离级别。

比如:

con.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);

五、JDBC2.0新特性:

1、Scrollability结果集可滚动滚动:

可双向支持绝对与相对滚动,对结果集可进行多次迭代。

Con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);

//上句的SCROLL再到CONCUR;

不可以写反,编译器无法检测到,因为他们都是int类型的。

TYPE_FORWARD_ONLY:

(单向,一般不用)该常量指示指针只能向前移动的ResultSet对象的类型。

TYPE_SCROOL_INSENSITIVE:

(双向、不敏感)可滚动但不受其他更改影响的ResultSet对象的类型。

TYPE_SCROLL_SENSITIVE:

(双向、敏感)该常量指示可滚动并且通常受其他的更改影响的ResultSet对象的类型。

CONCUR_READ_ONLY:

(只读)该常量指示只可以读取的ResultSet对象的并发模式。

CONCUR_UPDATABLE:

(可更新)该常量指示可以更新的ResultSet对象的并发模式。

绝对定位:

booleanabsolute(introw)将游标移动到指定位置。

(row指记录的序号,没有这位置则返回false)voidafterLast()将游标指向最后一条记录的后一位(有这位置,但记录为空)。

voidbeforeFirst()将游标指向最前一条记录的前一位。

booleanfirst()将游标移动到结果集最前。

booleanlast()将游标移动到结果集末尾。

相对定位:

booleannext()指向下一个。

booleanprevious()指向前一个。

booleanrelative(int)向next()方向移动int位(int可负)。

判位函数:

booleanisAfterLast()是否在最后一条的后一位。

booleanisBeforeFirst()是否最前一条记录的前一位。

booleanisFirst()是否最前位置。

booleanisLast()是否最后位置。

2、Updatability结果集可更新。

(主要应用于桌面应用)更新:

rs.updateString("

name"

"

Tony"

//前面一个是字段的名字或者序号rs.updateInt(1,"

122323"

修改rs.deleteRow();

删除rs.updateRow();

只有在必要的时候(如桌面应用)才用结果集更新数据库,因为使用结果集更新数据库效率低下。

可更新结果集还要看数据库驱动程序是否支持,如Oracle就支持,MySql不支持。

并且只能针对一张表做结果集更新(不能子查询)。

而且不能有join操作。

必须有主健,必须把所有非空没有默认值的字段查出。

处理可更新结果集时不能用select*来查询语句,必须指出具体要查询的字段。

(不能使用通配符)3、Batchupdates可批量更新。

将多组对数据库的更新操作发送到数据库统一执行(数据库支持并发执行操作),以提高效率。

主要是通过减少数据(Sql语句或参数)在网络上传输的次数来节省时间。

//数据有两组以上都应该用这批量更新

(1)对于Statement的批量更新处理:

stm.addBatch(Sql);

int[]ResultSet=stm.executeBatch();

`

(2)对于PreparedStatement的批量跟新处理pstm.setInt(1,12);

pstm.setString(2,"

gaga"

........pstm.addBatch();

if(i%100==0)int[]ResultSet=pstm.executeBatch();

//每个包50~200组数据,包太大也影响速度注:

int[]中每一个数表示该Sql语句影响到的记录条数。

PreparedStatement的更新操作比Statement的更新操作多了一个设置参数的过程。

六、SQL3.0规范中的新类型:

Blob,大的二进制数据文件,最多存储2G。

Clob,大文本文件对象,最多存储2G。

在使用上述大对象的时候,在使用JDBC插入记录时要先插入一个空的占位对象,"

insertintotableNamevaluse(?

empty_blob())"

//在数据库制造一个空的blob对象字段值然后使用"

selectblobdatafromt_blobwhereid=?

forupdate"

对获得的大对象进行实际的写入操作Blod通过getBinaryOutputStream()方法获取流进行写入。

getBinaryStream()方法获得流来获取Blob中存储的数据。

Clob的操作也和、Blob相同。

getAsciiStream()用于读取存储的文本对象,getAsciiOutputStream()方法之获得流用来向文件对象写入的。

BLOB与CLOB的异同点:

①都可以存储大量超长的数据;

②BLOB(BinaryLargeObject)以二进制格式保存,特别适合保存图片、视频文件、音频文件、程序文件等;

③CLOB(CharacterLargeObject)以Character格式保存于数据库中,适合保存比较长的文本文件。

七、JDBC2.0扩展

(一)JNDI(命名目录服务器):

定义:

是Java的命名目录服务器。

而JDBC是Java的数据库访问接口。

跟JDBC是平级的关系,是两个独立的JNDI;

JDBC存储的数据都是以二维表的接口来大规模存储数据。

而JNDI存储的是差异性比较大的Java对象。

JDBC取数据时用Sql语言访问数据。

JNDI只用lookup和bind读写JDBCAPI依赖于驱动程序,而JNDI依赖于服务提供者。

JDBC一般把数据存储到关系型数据库,而JNDI一般把数据存储到小型数据库、文件、甚至是注册表中。

JNDI相当于一个电话本。

允许程序将一个对象和一个命名绑定到目录树上。

(JNDI的方法是在jav

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

当前位置:首页 > 表格模板 > 合同协议

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1