JDBC讲解

SUN公司于1996年提供了一套访问数据库的标准Java类库,即JDBC。

一、什么是JDBC

JDBC的全称是Java数据库连接(Java Database Connectivity),它是一套用于执行SQL语句的Java API。应用程序可通过这套API连接到关系型数据库,并使用SQL语句来完成对数据库中数据的查询、更新、新增和删除的操作。

不同种类的数据库(如MySQL、Oracle等)在其内部处理数据的方式是不同的,如果直接使用数据库厂商提供的访问接口操作数据库,应用程序的可移植性就会变得很差。例如,用户当前在程序中使用的是MySQL提供的接口操作数据库,如果换成Oracle数据库,则需要重新使用Oracle数据库提供的接口,这样代码的改动量会非常大。有了JDBC后,这种情况就不复存在了,因为它要求各个数据库厂商按照统一的规范来提供数据库驱动,而在程序中是由JDBC和具体的数据库驱动联系,所以用户就不必直接与底层的数据库交互,这使得代码的通用性更强。

应用程序使用JDBC访问数据库的方式如下图所示。

从上图中可以看出,JDBC在应用程序与数据库之间起到了一个桥梁作用,当应用程序使用JDBC访问特定的数据库时,需要通过不同数据库驱动与不同的数据库进行连接,连接后即可对该数据库进行相应的操作。

二、JDBC常用API

2.1.Driver接口

Driver接口是所有JDBC驱动程序必须实现的接口,该接口专门提供给数据库厂商使用。需要注意的是,在编写JDBC程序时,必须要把所使用的数据库驱动程序或类库加载到项目的classpath中(这里指MySQL驱动JAR包)。

2.2.DriverManager类

DriverManager类用于加载JDBC驱动并且创建与数据库的连接。在DriverManager类中,定义了两个比较重要的静态方法,如下表所示。

 2.3.Connection接口

Connection接口代表Java程序和数据库的连接,只有获得该连接对象后才能访问数据库,并操作数据表。在Connection接口中,定义了一系列方法,其常用方法如下表所示。

2.4.Statement接口

Statement接口用于执行静态的SQL语句,并返回一个结果对象,该接口的对象通过Connection实例的createStatement()方法获得。利用该对象把静态的SQL语句发送到数据库编译执行,然后返回数据库的处理结果。在Statement接口中,提供了3个常用的执行SQL语句的方法,具体如下表所示。

 2.5.PreparedStatement接口

Statement接口封装了JDBC执行SQL语句的方法,可以完成Java程序执行SQL语句的操作。然而在实际开发过程中往往需要将程序中的变量作为SQL语句的查询条件,而使用Statement接口操作这些SQL语句会过于繁琐,并且存在安全方面的问题。针对这一问题,JDBC API 中提供了扩展的PreparedStatement接口。 PreparedStatement是Statement的子接口,用于执行预编译的SQL语句。该接口扩展了带有参数SQL语句的执行操作,应用该接口中的SQL语句可以使用占位符“?”来代替其参数,然后通过setXxx()方法为SQL语句的参数赋值。在PreparedStatement接口中,提供了一些常用方法,具体如下表所示。

需要注意的是,表中的 setDate()方法可以设置 日期内容,但参数Date 的类型是java.sql.Date, 而不是java.util.Date。 

在通过setXxx()方法为SQL语句中的参数赋值时,可以通过输入参数的已定义SQL类型兼容的方法(例如,如果参数具有SQL类型为Integer,那么应该使用setInt 方法),也可以通过setObject()方法设置多种类型的输入参数。具体如下所示:

2.6.ResultSet接口

ResultSet接口用于保存JDBC执行查询时返回的结果集,该结果集封装在一个逻辑表格中。在ResultSet接口内部有一个指向表格数据行的游标(或指针),ResultSet对象初始化时,游标在表格的第一行之前,调用next()方法可将游标移动到下一行。如果下一行没有数据,则返回false。在应用程序中经常使用next()方法作为while循环的条件来迭代ResultSet结果集。 ResultSet接口中的常用方法如下表所示。

 从表中可以看出,ResultSet接 口中定义了大量的getXxx()方 法,而采用哪种getXxx()方法 取决于字段的数据类型。程序 既可以通过字段的名称来获取 指定数据,也可以通过字段的 索引来获取指定的数据,字段 的索引是从1开始编号的。例如,数据表的第一列字段名为id,字段类型为int,那么既可以使用getInt(1)字段索引的方式获取该列的值,也可以使用getInt(“id”)字段名称的方式获取该列的值。

三、 实现第一个JDBC程序

3.1.加载并注册数据库驱动

Class.forName("DriverName");

或者DriverManager.registerDriver(java.sql.Driver driver)

3.2.通过DriverManager获取数据库连接

Connection conn = DriverManager.getConnection(String url, String username, String      password);

从上述代码可以看出,getConnection()方法中有3个参数,它们分别表示连接数据库的URL地址、登录数据库的用户名和密码。以MySQL数据库为例,其URL地址的书写格式如下:

jdbc:mysql://hostname:port/databasename

上面代码中,jdbc:mysql:是固定的写法,mysql指的是MySQL数据库。hostname指的是主机的名称(如果数据库在本机中,hostname可以为localhost或127.0.0.1;如果要连接的数据库在其他电脑上hostname为所要连接电脑的IP),port指的是连接数据库的端口号(MySQL端口号默认为3306),而databasename指的是MySQL中相应数据库的名称。

3.3.通过Connection对象获取Statement对象

Connection创建Statement的方式有如下三种:

createStatement():创建基本的Statement对象。

prepareStatement():创建PreparedStatement对象。

prepareCall():创建CallableStatement对象。

以创建基本的Statement对象为例,创建方式如下:

Statement stmt = conn.createStatement();

3.4.使用Statement执行SQL语句

所有的Statement都有如下三种执行SQL语句的方法:

execute():可以执行任何SQL语句。

executeQuery():通常执行查询语句,执行后返回代表结果集的ResultSet对象。 executeUpdate():主要用于执行DML和DDL语句。执行DML语句,如 INSERT、UPDATE或DELETE时,返回受SQL语句影响的行数,执行DDL语句返回0。

以executeQuery()方法为例,其使用方式如下:

ResultSet rs = stmt.executeQuery(sql);

3.5.操作ResultSet结果集

如果执行的SQL语句是查询语句,执行结果将返回一个ResultSet对象,该对象里保存了SQL语句查询的结果。程序可以通过操作该ResultSet对象来取出查询结果。

3.6.关闭连接,释放资源(倒关原则)

每次操作数据库结束后都要关闭数据库连接,释放资源,包括关闭ResultSet、Statement和Connection等资源。

案例:演示JDBC的使用

四、PreparedStatement对象

参考:预编译语句(Prepared Statements)介绍,以MySQL为例_51CTO博客_什么叫预编译语句

为什么用PreparedStatement

在上面的案例中,SQL语句的执行是通过Statement对象实现的。Statement对象每次执行SQL语句时,都会对其进行编译。当相同的SQL语句执行多次时,Statement对象就会使数据库频繁编译相同的SQL语句,从而降低数据库的访问效率。 为了解决上述问题,Statement提供了一个子类PreparedStatement。PreparedStatement对象可以对SQL语句进行预处理,使用编译预处理就是为了提高数据存取的效率。当数据库收到一个SQL语句后,数据库引擎会解析这个语句,检查其是否含有语法错误,如果没有错误,数据库会选择执行语句的最佳途径。数据库对所执行过的语句,以一个存取方案(Access Plan)保存在缓冲区中,如果下一个要执行的语句在缓冲区中找到一致的存取方案,就直接调用这个存取方案执行,省去了SQL语句编译的时间。这就是执行该语句的最佳途径。这个存取方案类似函数,每次给函数传递不同的参数,而被调函数的代码和逻辑早已存在。

很明显,编译预处理就是为了使同类SQL语句执行同一存取方案。同类语句如果不用Prepared Statement,虽然彼此差别很小,还是不同的存取方案。

案例:演示PreparedStatement对象的使用

五、ResultSet对象

ResultSet主要用于存储结果集,可以通过next()方法由前向后逐个获取结果集中的数据,如果想获取结果集中任意位置的数据,则需要在创建Statement对象时,设置两个ResultSet定义的常量,具体设置方式如下:

Statement st =conn.createStatement(
                        ResultSet.TYPE_SCROLL_INSENSITIVE, 
                        ResultSet.CONCUR_READ_ONLY);

在上述方式中,常量“ResultSet.TYPE_SCROLL_INSENITIVE”表示结果集可滚动,常量“ResultSet.CONCUR_READ_ONLY”表示以只读形式打开结果集。

案例:演示如何使用ResultSet对象滚动读取结果集中的数据

六、使用JDBC完成数据的增删改查

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值