Java JDBC由浅入深.docx

上传人:b****3 文档编号:5063398 上传时间:2022-12-12 格式:DOCX 页数:128 大小:340.61KB
下载 相关 举报
Java JDBC由浅入深.docx_第1页
第1页 / 共128页
Java JDBC由浅入深.docx_第2页
第2页 / 共128页
Java JDBC由浅入深.docx_第3页
第3页 / 共128页
Java JDBC由浅入深.docx_第4页
第4页 / 共128页
Java JDBC由浅入深.docx_第5页
第5页 / 共128页
点击查看更多>>
下载资源
资源描述

Java JDBC由浅入深.docx

《Java JDBC由浅入深.docx》由会员分享,可在线阅读,更多相关《Java JDBC由浅入深.docx(128页珍藏版)》请在冰豆网上搜索。

Java JDBC由浅入深.docx

JavaJDBC由浅入深

目录

第一节整理目的3

第二节jdbc的概念3

2.1概念3

2.2Jdbc与应用程序的关系3

2.3数据库的连接步骤4

2.4QuickStart4

第三节如何与数据库建立连接6

3.1注册驱动6

3.2建立数据库的连接8

3.3规范QuickStart中的例子10

第四节Statement接口的使用详解12

4.1Statement的常用方法12

4.2CRUD操作16

4.3Statement有那些缺点19

第五节ResultSet接口的使用详解20

第六节JDBC中数据类型详解30

6.1基本数据类型30

6.2日期类型34

6.3CLOB类型36

6.4BLOB类型39

6.5其他数据类型41

第七节DAO设计模式详解41

7.1实际项目中如何使用JDBC41

7.2DAO设计模式简介42

7.3DAO设计模式的实现42

7.4DAO设计模式与工厂模式的整合49

7.5DAO设计模式测试52

第八节JDBC对事务的支持52

8.1模拟转账53

8.2jdbc默认事务54

8.3事务提交与回滚54

8.4设置保存点55

8.5JTA事务的介绍56

8.6数据库的隔离级别介绍56

8.6.1未提交读57

8.6.2提交读58

8.6.3重复读59

8.6.4序列化读60

8.7小结62

第九节PreparedStatement接口的使用62

第十节CallableStatement接口的使用62

9.1无参无返回值存储过程调用63

9.2有参无返回值存储过程调用63

9.3有参有返回值存储过程调用64

9.4JDBC其他API65

第十一节元数据信息66

11.1数据库元数据信息66

11.2参数元数据信息67

第十二节批处理的使用67

12.1普通方式插入一千条数据68

12.2批处理方式插入一千条数据69

第十三节JDBC其他API70

13.1可滚动结果集70

13.2分页技术72

13.3可更新结果集73

第十四节编写一个简单的数据库连接池74

14.1为什么要使用数据库连接池74

14.2数据库连接池雏形74

14.2数据库连接池优化77

14.2.1对线程池加锁77

14.2.2连接不够用时抛出异常77

14.3数据库连接池之代理模式78

14.3.1静态代理78

14.3.2动态代理84

14.4DBCP数据库连接池的使用87

第十五节jdbc轻量级封装88

15.1将结果集封装为Map88

15.1.1ResultSetMetaData演示88

15.1.2解决多行记录的问题89

15.1.3Map结果集的封装90

15.2将结果集封装为对象91

15.2.1user表POJO的编写91

15.2.2Bean结果集的封装92

15.3将结果集封装为List94

15.4策略模式的应用96

15.4.1Map结果集策略模式应用96

15.4.2Bean结果集策略模式应用97

15.4.3List结果集策略模式应用98

15.4.4单元测试99

15.5模板模式的应用100

第十六节近期推出101

第一节整理目的

当今orm等全自动针对对象持久化的框架越来越多并且也越来越成熟(ibatis,hibernate,ejb的jpa),但是无奈新东家需要使用jdbc(原始手工作坊)的模式和数据库打交道,用了几年的ibatis,再次使用jdbc发现有些细节和底层的东西自己并不是十分清楚,所以就啰理啰嗦的整理出一份学习笔记,第一作为自己对jdbc重新的复习,第二如果有可能希望给初学jdbc的朋友带来一定的便利,这样也不枉我点点滴滴的记录。

随着对jdbc整理和学习的逐渐深入,发现原先使用orm框架时忽略了那么多的细节,这样在出现问题或者学习orm更加深入知识时则会显得力不从心,在本文档将jdbc如何入门阐述清楚之后,增加了如下的内容:

Ø数据库连接池,以及常用连接池的使用(dbcp,c3p0等)

Ø编写一套基于jdbc轻量级的api,方便使用;

Ø如何将查询结果封装为对象;

Ø如何将查询结果封装为Map;

Ø如何将查询结果封装为List;

Ø如何在JDBC的使用中加入策略,模板等模式;

Ø在后面的JDBC高级部分将会讲解到Dbutils源码,Spring对JDBC的强大封装

第二节jdbc的概念

2.1概念

我最不喜欢替别人整理某个名词的概念了,只要是概念性的东西基本上在任何地方都可以查得到,所以我就通俗的写一些自己对jdbc的理解,所谓jdbc就是java与数据库之间进行通讯的api,也就是一个标准,所以如果一个java应用程序想要和数据库打交道基本上都离不开jdbc,众所周知,一些优秀的orm框架的底层也是采用jdbc进行封装的。

2.2Jdbc与应用程序的关系

JdbcAPI所处的位置和它与应用程序之间的关系,下面的一张图再也明显不过了,其中绿色的部分代表jdbcAPI,它提供了很多接口,并且本身也实现了很多方法,可以看到蓝色的部分就是各个数据库厂商自己对jdbcAPI的一些实现,这就是我们常见的数据库连接驱动,这是使用jdbc程序进行开发必不可少的东西。

2.3数据库的连接步骤

1.注册驱动(Driver)

2.建立连接(创建Connection)

3.创建执行sql语句(通常是创建Statement或者其子类)

4.执行语句

5.处理执行结果(在非查询语句中,该步骤是可以省略的)

6.释放相关资源

在后文中,将会对上述几个步骤一一进行讲解,希望读者能够仔细阅读;

2.4QuickStart

好了,了解了一下jdbc的基本概念,相比对jdbc已经有了一个感性的认识,现在我们为了直观期间,直接来上一段代码了解一下jdbc最简单的程序如何进行开发的。

在该小节中,我们以一个简单的增删改查为例进行说明,然后会将该章节中涉及的各个常用以及关键的API进行详细的讲解;

首先我们创建一个数据表,在test数据库下,见表语句为

createtableuser(idintegerprimarykey,

namevarchar(30),

birthdaydate,

moneyfloat);

插入两条语句

●insertintouservalues(2,'zhangsan','2010-01-01',15000);

●insertintouservalues(1,'wangwenjun','1984-06-09',8500.00);

好了,数据准备好了,我们通过一个完整的例子讲上述中数据库的连接步骤进行一个演示,在本例子中,初学者可能有些地方会觉得陌生,看不明白,不用着急,在后文中会对涉及的知识点逐个进行讲解

@Test

publicvoidwholeExample(){

try{

//1.注册驱动

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

//2.获取数据库连接

Connectionconn=DriverManager.getConnection("jdbc:

mysql:

//localhost:

3306/test","root","r66t");

//3.创建执行句柄

Statementstmt=conn.createStatement();

//4.执行sql语句

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

//5.处理执行结果

while(rs.next()){

System.out.println("id:

"+rs.getInt

(1)+"\tname:

"+rs.getString

(2)+"\tbirthday:

"+rs.getDate(3)+"\tmoney:

"+rs.getFloat(4));

}

//6.释放资源

rs.close();

stmt.close();

conn.close();

}catch(SQLExceptione){

e.printStackTrace();

}catch(ClassNotFoundExceptione){

e.printStackTrace();

}

}

执行结果如下

id:

1name:

wangwenjunbirthday:

1984-06-09money:

8500.0

id:

2name:

zhangsanbirthday:

2010-01-01money:

15000.0

第三节如何与数据库建立连接

3.1注册驱动

●第一种注册方式

通常来说,注册驱动的方式有三种,下面我们将一一进行介绍,首先来看看直接调用DriverManager的registerDriver方法进行加载驱动,在本文中所有的程序均是在mysql数据库上进行演示的。

示例代码如下

@Test

publicvoidregistDriver1(){

try{

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

Connectionconn=DriverManager.getConnection("jdbc:

mysql:

//localhost:

3306/test","root","r66t");

Assert.assertEquals(false,conn.isClosed());

}catch(SQLExceptione){

e.printStackTrace();

}

}

执行结果为

可以看到,当前我们的程序与数据库的连接是正常的。

●第二种注册方式

@Test

publicvoidregistDriver2(){

try{

System.setProperty("jdbc.drivers","com.mysql.jdbc.Driver");

Connectionconn=DriverManager.getConnection("jdbc:

mysql:

//localhost:

3306/test","root","r66t");

Assert.assertEquals(false,conn.isClosed());

}catch(SQLExceptione){

e.printStackTrace();

}

}

执行结果为

可以看到,当前我们的程序与数据库的连接是正常的。

●第三种注册方式

@Test

publicvoidregistDriver3(){

try{

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

Connectionconn=DriverManager.getConnection("jdbc:

mysql:

//localhost:

3306/test","root","r66t");

Assert.assertEquals(false,conn.isClosed());

}catch(SQLExceptione){

e.printStackTrace();

}catch(ClassNotFoundExceptione){

//TODOAuto-generatedcatchblock

e.printStackTrace();

}

}

执行结果为

可以看到,当前我们的程序与数据库的连接是正常的。

一般来说注册驱动的方式大致上有上述三个,但是最常用的是最后一个,通过我们的代码演示可以看出,数据库都是完全可以被访问成功的。

3.2建立数据库的连接

其实在上文中的代码演示中,我们都会看到如何获取一个数据库连接,就是通过DriverManager.getConnection()方法获取数据库的链接,该方法大致有三个重载的方法,都是可以进行数据库连接的获取的,下面我们将会一一进行演示

StaticConnection

getConnection(String url)

试图建立到给定数据库URL的连接。

staticConnection

getConnection(String url,Properties info)

试图建立到给定数据库URL的连接。

staticConnection

getConnection(String url,Stringuser,String password)试图建立到给定数据库URL的连接。

●getConnection(String url)

该实例中,登录数据库的所有信息都编写在url中,实例代码如下

@Test

publicvoidgetConn1(){

try{

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

Connectionconn=DriverManager.getConnection("jdbc:

mysql:

//localhost:

3306/test?

user=root&password=r66t");

Assert.assertEquals(false,conn.isClosed());

}catch(SQLExceptione){

e.printStackTrace();

}catch(ClassNotFoundExceptione){

//TODOAuto-generatedcatchblock

e.printStackTrace();

}

}

●getConnection(String url,Properties info)

该方法则是将用户名和密码的信息存放在一个Properties键值对中,示例代码如下

@Test

publicvoidgetConn2(){

try{

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

Propertiesprops=newProperties();

props.put("user","root");

props.put("password","r66t");

Connectionconn=DriverManager.getConnection("jdbc:

mysql:

//localhost:

3306/test",props);

Assert.assertEquals(false,conn.isClosed());

}catch(SQLExceptione){

e.printStackTrace();

}catch(ClassNotFoundExceptione){

//TODOAuto-generatedcatchblock

e.printStackTrace();

}

}

●getConnection(String url,Stringuser,String password)

该方法则是我们在上文中演示了很多次的方式,也是最常用的一种方式,在这里再次进行一下赘述

@Test

publicvoidgetConn3(){

try{

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

Connectionconn=DriverManager.getConnection("jdbc:

mysql:

//localhost:

3306/test","root","r66t");

Assert.assertEquals(false,conn.isClosed());

}catch(SQLExceptione){

e.printStackTrace();

}catch(ClassNotFoundExceptione){

//TODOAuto-generatedcatchblock

e.printStackTrace();

}

}

3.3规范QuickStart中的例子

其中,我们在QuickStart中写了一个较为完整的代码示例,但是在该代码中存在很多的问题,我们通过本节的介绍,一一进行规范和优化,并且说明一下优化的好处是什么

使用数据库时,涉及数据库的资源都是非常奇缺的,我们在使用的过程中务必保证我们将使用过的资源释放,供别人再次使用或者自己下次再次使用,还有,创建数据库连接时可能存在各种各样的问题导致数据库连接获取失败,这个时候你的应用应该有义务告知上一层使用者到底出现了什么问题,这样就需要一个异常传递的过程(异常是一个比较复杂的机制,笔者在另一篇文章中有详细的讲解,希望读者能够关注)

@Test

publicvoidregularWhole()throwsException{//抛出异常

Connectionconn=null;

Statementstmt=null;

ResultSetrs=null;

try{

//1.注册驱动

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

//2.获取数据库连接

conn=DriverManager.getConnection("jdbc:

mysql:

//localhost:

3306/test","root","r66t");

//3.创建执行句柄

stmt=conn.createStatement();

//4.执行sql语句

rs=stmt.executeQuery("select*fromuser");

//5.处理执行结果

while(rs.next()){

System.out.println("id:

"+rs.getInt

(1)+"\tname:

"+rs.getString

(2)+"\tbirthday:

"+rs.getDate(3)+"\tmoney:

"+rs.getFloat(4));

}

}finally{

try{

//6.释放资源

if(null!

=rs){

rs.close();

}

if(null!

=stmt){

stmt.close();

}

if(null!

=conn){

conn.close();

}

}finally{

if(null!

=rs){

rs.close();

}

if(null!

=stmt){

stmt.close();

}

if(null!

=conn){

conn.close();

}

}

}

}

在该实例中,可以看出确保了资源的完全释放,也将异常抛出告知上一层使用者,那块出现了问题,但是可以看到代码明显写的很罗嗦,而且有很多地方还是值得考究的

其中,注册驱动,数据库的驱动注册,只需要一次即可,重复注册是没有任何意义的,并且资源的释放,在每次使用的时候都进行资源的释放(写资源释放的代码)显得非常罗嗦,所以我们进行再一次的一个优化,代码如下

packagecom.wangwenjun.jdbc;

importjava.sql.Connection;

importjava.sql.DriverManager;

importjava.sql.ResultSet;

importjava.sql.SQLException;

importjava.sql.Statement;

publicfinalclassConnCreate{

static{

try{

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

}catch(ClassNotFoundExceptione){

e.printStackTrace();

}

}

publicstaticConnectiongetConnection(Stringurl,Stringuser,Stringpwd){

Connectionconn=null;

try{

conn=DriverManager.getConnection(url,user,pwd);

}catch(SQLExceptione){

e.printStackTrace();

}

returnconn;

}

publicstaticvoidclose(Connectionconn,Statementstmt,ResultSetrs)

throwsSQLException{

if(null!

=rs){

rs.close();

}

if(null!

=stmt){

stmt.close();

}

if(null!

=conn){

conn.close();

}

}

}

可以看出,驱动只会被注册一次,并且对资源释放的代码进行了抽取,在以后的使用过程中则会简单许多,当然上述的代码如果还需要追究问题,肯定还是存在的,在接下来的章节中我们也会进行深入的说明。

第四节Statement接口的使用详解

Statement是应用与数据库打交道最关键的一个接口,该接口包括了我们常用的CRUD操作,还可以设置抓取策略,比如设置数据库的游标是多少,可以根据数据量进行调优,也可以进行批量处理等,总之,该接口是非常关键的一个接口,包括后文中的预处理命令接口以及执行存储过程的接口。

4.1Statement的常用方法

下面的列表是从jdkAPI文档上粘贴出来的,当然很多方法我们并不是都能碰到,但是了解一下还是会有好处的

方法摘要

 void

addBatch(String sql)

          将给

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

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

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

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