《JDBC数据库编程.ppt》由会员分享,可在线阅读,更多相关《JDBC数据库编程.ppt(36页珍藏版)》请在三一办公上搜索。
1、Java实用教程,第11章 JDBC数据库编程,第11章 JDBC数据库编程,11.1 JDBC概述11.2 JDBC中的常用接口11.3 连接数据库11.4 操作数据库10.5 网 络 聊 天11.5 应用JDBC事务,11.2 JDBC中的常用接口,JDBC提供了众多的接口和类,通过这些接口和类,可以实现与数据库的通信,本节将详细介绍一些常用的JDBC接口和类。,11.2.1 Driver接口,每种数据库的驱动程序都应该提供一个实现java.sql.Driver接口的类,简称Driver类,在加载某一驱动程序的Driver类时,它应该创建自己的实例并向java.sql.DriverMana
2、ger类注册该实例。通常情况下通过java.lang.Class类的静态方法forName(String className),加载欲连接数据库的Driver类,该方法的入口参数为欲加载Driver类的完整路径。成功加载后,会将Driver类的实例注册到DriverManager类中,如果加载失败,将抛出ClassNotFoundException异常,即未找到指定Driver类的异常。,11.2.2 DriverManager类,java.sql.DriverManager类负责管理JDBC驱动程序的基本服务,是JDBC的管理层,作用于用户和驱动程序之间,负责跟踪可用的驱动程序,并在数据库和
3、驱动程序之间建立连接;另外,DriverManager类也处理诸如驱动程序登录时间限制及登录和跟踪消息的显示等工作。成功加载Driver类并在DriverManager类中注册后,DriverManager类即可用来建立数据库连接。当调用DriverManager类的getConnection()方法请求建立数据库连接时,DriverManager类将试图定位一个适当的Driver类,并检查定位到的Driver类是否可以建立连接,如果可以则建立连接并返回,如果不可以则抛出SQLException异常。,DriverManager类,DriverManager类提供的常用静态方法如下表所示:,1
4、1.2.3 Connection接口,java.sql.Connection接口代表与特定数据库的连接,在连接的上下文中可以执行SQL语句并返回结果,还可以通过getMetaData()方法获得由数据库提供的相关信息,例如数据表、存储过程和连接功能等信息。Connection接口提供的常用方法如下表所示。,11.2.4 Statement接口,java.sql.Statement接口用来执行静态的SQL语句,并返回执行结果。例如,对于INSERT、UPDATE和DELETE语句,调用executeUpdate(String sql)方法;对于SELECT语句,则调用executeQuery(S
5、tring sql)方法,并返回一个永远不能为null的ResultSet实例。Statement接口提供的常用方法如下表所示。,11.2.5 PreparedStatement接口,java.sql.PreparedStatement接口继承并扩展了Statement接口,用来执行动态的SQL语句,即包含参数的SQL语句。通过PreparedStatement实例执行的动态SQL语句将被预编译并保存到PreparedStatement实例中,从而可以反复并且高效地执行该SQL语句。需要注意的是,在通过setXxx()方法为SQL语句中的参数赋值时,建议利用与参数类型匹配的方法,也可以利用se
6、tObject()方法为各种类型的参数赋值。PreparedStatement接口的使用方法如下:PreparedStatement接口提供的常用方法如下表所示。,PreparedStatement ps=connection.prepareStatement(select*from table_name where id?and(name=?or name=?);ps.setInt(1,6);ps.setString(2,马先生);ps.setObject(3,李先生);ResultSet rs=ps.executeQuery();,11.2.6 CallableStatement接口,ja
7、va.sql.CallableStatement接口继承并扩展了PreparedStatement接口,用来执行SQL的存储过程。JDBC API定义了一套存储过程SQL转义语法,该语法允许对所有RDBMS通过标准方式调用存储过程。该语法定义了两种形式,分别是包含结果参数和不包含结果参数的形式,如果使用结果参数,则必须将其注册为OUT型参数,参数是根据定义位置按顺序引用的,第一个参数的索引为1。为参数赋值的方法使用从PreparedStatement类中继承来的setXXX()方法。在执行存储过程之前,必须注册所有OUT参数的类型,它们的值是在执行后通过getXxx()方法获得的。Callab
8、leStatement接口可以返回一个或多个ResultSet对象。处理多个ResultSet对象的方法是从Statement中继承来的。,11.2.7 ResultSet接口,java.sql.ResultSet接口类似于一个数据表,通过该接口的实例可以获得检索结果集,以及对应数据表的相关信息,例如列名和类型等,ResultSet实例通过执行查询数据库的语句生成。ResultSet实例具有指向当前数据行的指针,最初,指针指向第一行记录,通过next()方法可以将指针移动到下一行,如果存在下一行该方法则返回true,否则返回false,所以可以通过while循环来迭代ResultSet结果集。
9、默认情况下ResultSet实例不可以更新,只能移动指针,所以只能迭代一次,并且只能按从前向后的顺序。如果需要,可以生成可滚动和可更新的ResultSet实例。,ResultSet接口,ResultSet接口提供了从当前行检索不同类型列值的getXxx()方法,均有两个重载方法,分别根据列的索引编号和列的名称检索列值,其中以列的索引编号较为高效,编号从1开始。对于不同的getXxx()方法,JDBC驱动程序尝试将基础数据转换为与getXxx()方法相应的Java类型并返回。在JDBC 2.0 API之后,为该接口添加了一组更新方法updateXxx(),均有两个重载方法,分别根据列的索引编号和
10、列的名称指定列。可以用来更新当前行的指定列,也可以用来初始化要插入行的指定列,但是该方法并未将操作同步到数据库,需要执行updateRow()或insertRow()方法完成同步操作。ResultSet接口提供的常用方法如下表所示,11.3 连接数据库,在访问数据库时,首先要加载数据库的驱动程序,不过只需在第一次访问数据库时加载一次;然后在每次访问数据库时创建一个Connection实例;紧接着执行操作数据库的SQL语句,并处理返回结果;最后在完成此次操作时销毁前面创建的Connection实例,释放与数据库的连接。,11.3.1 加载JDBC驱动程序,在与数据库建立连接之前,必须先加载欲连接
11、数据库的驱动程序到JVM(Java虚拟机)中,加载方法为通过java.lang.Class类的静态方法forName(String className);成功加载后,会将加载的驱动类注册给DriverManager类;如果加载失败,将抛出ClassNotFoundException异常,即未找到指定的驱动类,所以需要在加载数据库驱动类时捕捉可能抛出的异常。通常情况下将负责加载数据库驱动的代码放在static块中,因为static块的特点是只在其所在类第一次被加载时执行,即第一次访问数据库时执行,这样就可以避免反复加载数据库驱动,减少对资源的浪费,同时提高了访问数据库的速度。【例11-1】,11
12、.3.2 创建数据库连接,java.sql.DriverManager(驱动程序管理器)类是JDBC的管理层,负责建立和管理数据库连接。通过DriverManager类的静态方法getConnection(String url,String user,String password)可以建立数据库连接,3个参数依次为欲连接数据库的路径、用户名和密码,该方法的返回值类型为java.sql.Connection。【例11-2】,11.3.3 执行SQL语句,建立数据库连接(Connection)的目的是与数据库进行通信,实现方法为执行SQL语句,但是通过Connection实例并不能执行SQL语句
13、,还需要通过Connection实例创建Statement实例,Statement实例又分为3种类型:(1)Statement实例:该类型的实例只能用来执行静态的SQL语句;(2)PreparedStatement实例:该类型的实例增加了执行动态SQL语句的功能;(3)CallableStatement实例:该类型的实例增加了执行数据库存储过程的功能。上面给出三种不同的类型中Statement是最基础的;PreparedStatement继承Statement,并做了相应的扩展;而CallableStatement继承了PreparedStatement,又做了相应的扩展。在11.4节将详细介
14、绍各种类型实例的使用方法。,11.3.4 获得查询结果,通过Statement接口的executeUpdate()或executeQuery()方法,可以执行SQL语句,同时将返回执行结果,如果执行的是executeUpdate()方法,将返回一个int型数值,代表影响数据库记录的条数,即插入、修改或删除记录的条数;如果执行的是executeQuery()方法,将返回一个ResultSet型的结果集,其中不仅包含所有满足查询条件的记录,还包含相应数据表的相关信息,例如每一列的名称、类型和列的数量等。,11.3.5 关闭连接,在建立Connection、Statement和ResultSet实例
15、时,均需占用一定的数据库和JDBC资源,所以每次访问数据库结束后,应该及时销毁这些实例,释放它们占用的所有资源,方法是通过各个实例的close()方法,执行close()方法时建议按照如下的顺序:resultSet.close();statement.close();connection.close();建议按上面的顺序关闭的原因在于Connection是一个接口,close()方法的实现方式可能多种多样。,关闭连接,如果是通过DriverManager类的getConnection()方法得到的Connection实例,在调用close()方法关闭Connection实例时会同时关闭Stat
16、ement实例和ResultSet实例。但是通常情况下需要采用数据库连接池,在调用通过连接池得到的Connection实例的close()方法时,Connection实例可能并没有被释放,而是被放回到了连接池中,又被其他连接调用,在这种情况下如果不手动关闭Statement实例和ResultSet实例,它们在Connection中可能会越来越多,虽然JVM的垃圾回收机制会定时清理缓存,但是如果清理得不及时,当数据库连接达到一定数量时,将严重影响数据库和计算机的运行速度,甚至导致软件或系统瘫痪。,11.4 操作数据库,访问数据库的目的是操作数据库,包括向数据库插入记录或修改、删除数据库中的记录,
17、或者是从数据库中查询符合一定条件的记录,这些操作既可以通过静态的SQL语句实现,也可以通过动态的SQL语句实现,还可以通过存储过程实现,具体采用的实现方式要根据实际情况而定。在增、删、改数据库中的记录时,分为单条操作和批量操作,单条操作又分为一次只操作一条记录和一次只执行一条SQL语句,批量操作又分为通过一条SQL语句(只能是UPDATE和DELETE语句)操作多条记录和一次执行多条SQL语句。,11.4.1 添加数据,在添加记录时,一条INSERT语句只能添加一条记录。如果只需要添加一条记录,通常情况下通过Statement实例完成。【例11-3】【例11-4】【例11-5】【例11-6】【
18、例11-7】,11.4.2 查询数据,在查询数据时,既可以利用Statement实例通过执行静态SELECT语句完成,也可以利用PreparedStatement实例通过执行动态SELECT语句完成,还可以利用CallableStatement实例通过执行存储过程完成。(1)利用Statement实例通过执行静态SELECT语句查询数据的典型代码如下:(2)利用PreparedStatement实例通过执行动态SELECT语句查询数据的典型代码如下:,ResultSet rs=statement.executeQuery(select*from tb_record where sex=男);,
19、String sql=select*from tb_record where sex=?;PreparedStatement prpdStmt=connection.prepareStatement(sql);prpdStmt.setString(1,男);ResultSet rs=prpdStmt.executeQuery();,查询数据,(3)利用CallableStatement实例通过执行存储过程查询数据的典型代码如下:无论利用哪个实例查询数据,都需要执行executeQuery()方法,这时才真正执行SELECT语句,从数据库中查询符合条件的记录,该方法将返回一个ResultSet型
20、的结果集,在该结果集中不仅包含所有满足查询条件的记录,还包含相应数据表的相关信息,例如每一列的名称、类型和列的数量等。【例11-8】【例11-9】,String call=call pro_record_select_by_sex(?);CallableStatement cablStmt=connection.prepareCall(call);cablStmt.setString(1,男);ResultSet rs=cablStmt.executeQuery();,11.4.3 修改数据,在修改数据时,即可以利用Statement实例通过执行静态UPDATE语句完成,也可以利用Prepar
21、edStatement实例通过执行动态UPDATE语句完成,还可以利用CallableStatement实例通过执行存储过程完成。(1)利用Statement实例通过执行静态UPDATE语句修改数据的典型代码如下:(2)利用PreparedStatement实例通过执行动态UPDATE语句修改数据的典型代码如下:,String sql=update tb_record set salary=3000 where duty=部门经理;statement.executeUpdate(sql);,String sql=update tb_record set salary=?where duty=?
22、;PreparedStatement prpdStmt=connection.prepareStatement(sql);prpdStmt.setInt(1,3000);prpdStmt.setString(2,部门经理);prpdStmt.executeUpdate();,修改数据,(3)利用CallableStatement实例通过执行存储过程修改数据的典型代码如下:无论利用哪个实例修改数据,都需要执行executeUpdate()方法,这时才真正执行UPDATE语句,修改数据库中符合条件的记录,该方法将返回一个int型数,为被修改记录的条数。【例11-10】【例11-11】,String
23、 call=call pro_record_update_salary_by_duty(?,?);CallableStatement cablStmt=connection.prepareCall(call);cablStmt.setInt(1,3000);cablStmt.setString(2,部门经理);cablStmt.executeUpdate();,11.4.4 删除数据,在删除数据时,既可以利用Statement实例通过执行静态DELETE语句完成,也可以利用PreparedStatement实例通过执行动态DELETE语句完成,还可以利用CallableStatement实例通
24、过执行存储过程完成。(1)利用Statement实例通过执行静态DELETE语句删除数据的典型代码如下:,String sql=delete from tb_merchandise where date2008-2-14;statement.executeUpdate(sql);,删除数据,(2)利用PreparedStatement实例通过执行动态DELETE语句删除数据的典型代码如下:注意:当需要为日期型参数赋值时,如果已经存在java.sql.Date型对象,可以通过setDate(int parameterIndex,java.sql.Date date)方法为日期型参数赋值;如果不存
25、在java、sql、Date型对象,也可以通过setString(int parameterIndex,String x)方法为日期型参数赋值。,String sql=delete from tb_merchandise where date?;PreparedStatement prpdStmt=connection.prepareStatement(sql);prpdStmt.setString(1,2008-2-14);/为日期型参数赋值prpdStmt.executeUpdate();,删除数据,(3)利用CallableStatement实例通过执行存储过程删除数据的典型代码如下:无
26、论利用哪个实例删除数据,都需要执行executeUpdate()方法,这时才真正执行DELETE语句,删除数据库中符合条件的记录,该方法将返回一个int型数,为被删除记录的条数。【例11-12】【例11-13】,String call=call pro_merchandise_delete_by_date(?);CallableStatement cablStmt=connection.prepareCall(call);cablStmt.setString(1,2008-2-14);/为日期型参数赋值cablStmt.executeUpdate();,11.5 应用JDBC事务,所谓事务,是
27、指一组相互依赖的操作单元的集合,用来保证对数据库的正确修改,保持数据的完整性,如果一个事务的某个单元操作失败,将取消本次事务的全部操作。例如银行交易、股票交易和网上购物等,都需要利用事务来控制数据的完整性,比如将A账户的资金转入B账户,在A中扣除成功,在B中添加失败,导致数据失去平衡,事务将回滚到原始状态,即A中没少,B中没多。,应用JDBC事务,数据库事务必须具备以下特征(简称ACID):(1)原子性(Atomic):每个事务是一个不可分割的整体,只有所有的操作单元执行成功,整个事务才成功;否则此次事务就失败,所有执行成功的操作单元必须撤销,数据库回到此次事务之前的状态;(2)一致性(Con
28、sistency):在执行一次事务后,关系数据的完整性和业务逻辑的一致性不能被破坏。例如A与B转账结束后,他们的资金总额是不能改变的;,应用JDBC事务,(3)隔离性(Isolation):在并发环境中,一个事务所做的修改必须与其他事务所做的修改相隔离。例如一个事务查看的数据必须是其他并发事务修改之前或修改完毕的数据,不能是修改中的数据;(4)持久性(Durability):事务结束后,对数据的修改是永久保存的,即使系统故障导致重启数据库系统,数据依然是修改后的状态。数据库管理系统采用锁的机制来管理事务。当多个事务同时修改同一数据时,只允许持有锁的事务修改该数据,其他事务只能“排队等待”,直到前一个事务释放其拥有的锁。【例11-14】,