• 1. 第六章 JDBC高级应用本章主要内容有 程序操作预编译 事务管理 存储过程
  • 2. 第五章 实现JDBC API 访问数据库本章主要内容有 JDBC的对象及其关系 用JDBC连接数据库 用JDBC实现数据库查询 用JDBC实现数据库更新
  • 3. 第四章 JDBC技术应用主要内容有: JDBC的发展与应用 JDBC设计方案 JDBC的典型应用
  • 4. 4.1 JDBC的发展与应用1996年夏天,SUN公司发布了JDBC1.0工具包,它包含在JDK1.1中。 1998年在SUN发布JAVA2时,JDBC2.0随着JDK1.2问世。 JDBC能够让Java应用与各种各样的数据库连接,JDBC和Java的结合使Java应用真正实现了“一次编写,处处运行”。
  • 5. 4.2 JDBC设计方案JDBC包含两层: 第一层是JDBC API,这个API和JDBC驱动程序管理器API通信,向它发送各种不同的SQL语句; 第二层即JDBC驱动器管理器API,这个管理器和各种不同的第三方驱动程序通信,由它们负责连接数据库,返回查询信息或执行查询语句指定的动作。
  • 6. 4.2 JDBC设计方案JDBC和数据库的通信路径 JDBC Driver APIJDBC APIJava应用程序JDBC驱动程序管理器 JDBC/ODBC桥 供应商提供的JDBC驱动程序ODBC驱动程序数据库数据库
  • 7. 4.2 JDBC设计方案JDBC驱动程序分成四类: 第一类驱动程序是JDBC-ODBC桥 第二类驱动程序由两部分组成, 一部分是Java语言代码, 另一部分是本地代码 第三类驱动程序是一个纯Java客户库 第四类驱动程序是一个纯Java库
  • 8. 4.3 JDBC的典型应用在两层模型中 ,称为Client/Server结构 数据库协议客户端JDBC数据库 服务器
  • 9. 4.3 JDBC的典型应用在三层模型中,分开了视觉图像(在客户端)、事务逻辑(在中间层)和源数据(在数据库中) 客户端 (可视的演示)中间层 (商业逻辑)JDBC数据库 服务器HTTP、RMI等数据协议
  • 10. 4.4 JDBC的安装在一个开发平台上安装JDBC大致可以分成以下三个步骤: 第一,在开发平台上安装JDK和JDBC 第二,在开发平台上安装一个驱动程序 第三,在开发平台上安装数据库管理系统
  • 11. 5.1 JDBC的对象及其关系几个比较常用的JDBC对象包括: Connection对象 DriverManager对象 Statement对象 ResultSet对象
  • 12. 5.1 JDBC的对象及其关系JDBC类体系层次 ResultSetStatement PreparedStatement CallableStatementConnectionDriverManagerJDBC/ODBC桥Oracle驱动程序ODBC数据源Oracle数据库
  • 13. 5.2 用JDBC连接数据库1. 数据库URL 数据库URL包括以下内容: (1)定义所用的数据库类型; (2)所有数据库连接信息(主机、端口、数据库名、用户访问和口令)。 数据库URL的语法如下: jdbc:<子协议>:<数据库名>
  • 14. 5.2 用JDBC连接数据库2. 建立连接 通过加载驱动程序,并使用数据库URL来构造连接,就可以建立一个数据库的连接了。 例如: Class.forName(“oracle.jdbc.driver.OracleDriver”);//装载驱动程序类 Connection conn=DriverManager.getConnection( “jdbc:oracle:thin:@MyOracleDB”,”scott”,”tiger”);//构造一个数据库连接
  • 15. 5.3 用JDBC实现数据库查询构造查询需要考虑以下几个方面的问题: 选择合适的语句进行构造; 区别数据的检索和数据的更新。
  • 16. 5.3 用JDBC实现数据库查询1. 创建表 COFFEES数据表 COF_NAMESUP_IDPRICESALESTOTALColombian1017.9900French_Roast498.9900Espresso1509.9900Colombian_Decaf1018.9900French_Roast_Decaf499.9900
  • 17. 5.3 用JDBC实现数据库查询创建COFFEES表的程序如下: CREATE TABLE COFFEES (COF_NAME VARCHAR(32), SUP_ID INTEGER, PRICE FLOAT, SALES INTEGER, TOTAL INTEGER)
  • 18. 5.3 用JDBC实现数据库查询SUPPLIERS信息表 SUP_IDSUP_NAMESTREETCITYSTATEZIP101Acme, Inc.99 Market StreetGroundsvilleCA9519949Superior Coffee1 Party PlaceMendocinoCA95460150The High Ground100 Coffee LaneMeadowsCA93966
  • 19. 5.3 用JDBC实现数据库查询创建SUPPLIERS表的程序如下: CREATE TABLE SUPPLIERS (SUP_ID INTEGER, SUP_NAME VARCHAR(32), STREET VARCHAR(32), CITY VARCHAR(32), STATE VARCHAR(32), ZIP VARCHAR(32))
  • 20. 5.3 用JDBC实现数据库查询2. 创建处理语句 调用DriverManager.getConnection()方法返回一个Connection对象con,用它可以创建Statement对象,如下面的语句: Statement stmt = con.createStatement();
  • 21. 5.3 用JDBC实现数据库查询然后,我们就可以调用Statement类的executeUpdate()方法来创建数据表了。 stmt.executeUpdate("CREATE TABLE COFFEES " + "(COF_NAME VARCHAR(32), SUP_ID INTEGER, PRICE FLOAT, " + "SALES INTEGER, TOTAL INTEGER)");
  • 22. 5.3 用JDBC实现数据库查询在一个表中添加数据实际上也是对表数据的更新,因此,我们还可以使用executeUpdate方法实现对表数据的添加。例如下面的代码: Statement stmt = con.createStatement(); stmt.executeUpdate( "INSERT INTO COFFEES " + "VALUES ('Colombian', 101, 7.99, 0, 0)");
  • 23. 5.3 用JDBC实现数据库查询executeUpdate方法可以被调用任意多次。 stmt.executeUpdate("INSERT INTO COFFEES " + "VALUES ('French_Roast', 49, 8.99, 0, 0)"); stmt.executeUpdate("INSERT INTO COFFEES " + "VALUES ('Espresso', 150, 9.99, 0, 0)"); stmt.executeUpdate("INSERT INTO COFFEES " + "VALUES ('Colombian_Decaf', 101, 8.99, 0, 0)"); stmt.executeUpdate("INSERT INTO COFFEES " + "VALUES ('French_Roast_Decaf', 49, 9.99, 0, 0)");
  • 24. 5.3 用JDBC实现数据库查询3. 从数据库表中获取数据 使用SQL语句的SELECT进行查询 SELECT COF_NAME, PRICE FROM COFFEES 查询的结果: COF_NAME PRICE -------- ---------- ----- Colombian 7.99 French_Roast 8.99 Espresso 9.99 Colombian_Decaf 8.99 French_Roast_Decaf 9.99
  • 25. 5.3 用JDBC实现数据库查询JDBC把查询结果返回到ResultSet对象中 ResultSet rs = stmt.executeQuery( "SELECT COF_NAME, PRICE FROM COFFEES");
  • 26. 5.3 用JDBC实现数据库查询除了要用到ResultSet类的对象以外,还需要两个方法,即 next()方法和 getXXX()方法, 这两个方法都是ResuleSet类中的方法。
  • 27. 5.3 用JDBC实现数据库查询SQL数据类型及其相应的Java语言数据类型 SQL数据类型Java数据类型INTEGER或INTintSMALLINTshortNUMERIC、DECIMAIL或DECjava.sql.NumericFLOATdoubleREALfloatDOUBLEdoubleCHARACTER或CHARStringVARCHARStringBOOLEANbooleanDATEjava.sql.DateTIMEjava.sql.TimeTIMESTAMPjava.sql.TimestampBLOBjava.sql.BlobCLOBjava.sql.ClobARRAYjava.sql.Array
  • 28. 5. 4 用JDBC实现数据库更新使用JDBC更新数据库就是使用excuteUpdate()方法向数据库传送SQL语句。这些语句包括SQL INSERT、UPDATE或DELETE语句,也包括DDL语句,如CREATE TABLE等。
  • 29. 5. 4 用JDBC实现数据库更新管理人员想要对COFFEES表中的SALES字段的值进行更新,则可以使用如下的代码: String updateString = "UPDATE COFFEES " + "SET SALES = 75 " + "WHERE COF_NAME LIKE 'Colombian'"; stmt.executeUpdate(updateString);
  • 30. 5. 4 用JDBC实现数据库更新这段代码的执行结果应该如下所示: COF_NAME SUP_ID PRICE SALES TOTAL -------- ------ ----- ----- ----- Colombian 101 7.99 75 0 French_Roast 49 8.99 0 0 Espresso 150 9.99 0 0 Colombian_Decaf 101 8.99 0 0 French_Roast_Decaf 49 9.99 0 0
  • 31. 5. 4 用JDBC实现数据库更新在Access数据库管理系统中创建一个MyDB数据库文件,并在控制面板的ODBC数据源中,添加一个系统DSN,系统数据源的名称为MyDB,并指向已经创建好的MyDB数据库
  • 32. 5. 4 用JDBC实现数据库更新创建ODBC数据源
  • 33. 5. 4 用JDBC实现数据库更新Access数据源的安装
  • 34. 5. 4 用JDBC实现数据库更新成功添加了一个系统数据源
  • 35. 6.1 程序操作预编译 我们想对查询执行1000次,用预编译语句处理,写成如下的形式: PreparedStatement prepStmt= con.prepareStatement("SELECT COF_NAME, PRICE FROM COFFEES"); ResultSet rs; for(int i=0;i<1000;i++){ rs = prepStmt.executeQuery(); }
  • 36. 6.1 程序操作预编译SELECT COF_NAME, SUP_ID FROM COFFEES WHERE COF_NAME LIKE 'Colombian'; SELECT COF_NAME, SUP_ID FROM COFFEES WHERE COF_NAME LIKE ' French_Roast '; SELECT COF_NAME, SUP_ID FROM COFFEES WHERE COF_NAME LIKE ' Espresso '; 我们可以为一类查询设计一个模板,形式如下: SELECT COF_NAME, SUP_ID FROM COFFEES WHERE COF_NAME LIKE ?
  • 37. 6.1 程序操作预编译把上面的三条查询代码重新改写如下: PreparedStatement prepStmt= Con.prepareStatement("SELECT COF_NAME, SUP_ID FROM COFFEES "+ "WHERE COF_NAME LIKE ?"); prepStmt..setString(1,"Colombian"); prepStmt..setString(1,"French_Roast"); prepStmt..setString(1,"Espresso"); ResultSet rs=prepStmt.executeQuery();
  • 38. 6.1 程序操作预编译如果LIKE子句有大量的值需要绑定,参数的值可以事先存储在一个数组中,通过I/O流机制实现数据的输入和输出。 PreparedStatement prepStmt= Con.prepareStatement("SELECT COF_NAME, SUP_ID FROM COFFEES "+ "WHERE COF_NAME LIKE ?"); String coffees[]={"Colombian","French_Roast","Espresso"}; int len=coffees.length; for(int i=0;i
  • 39. 6.2 事务管理怎样在编程中实现对事务的管理呢?首先我们没有必要显示地启动一个事务,可以通过调用Connection.setAutoCommit(false)隐式地实现。然后调用Connection.commit()方法来提交一个事务,而且如果考虑到代码的安全性,还要包括一个回滚Connection.rollback()。 例如下面的这段代码:
  • 40. 6.2 事务管理con.setAutoCommit(false); PreparedStatement updateSales = con.prepareStatement( "UPDATE COFFEES SET SALES = ? WHERE COF_NAME LIKE ?"); updateSales.setInt(1, 50); updateSales.setString(2, "Colombian"); updateSales.executeUpdate(); PreparedStatement updateTotal = con.prepareStatement( "UPDATE COFFEES SET TOTAL = TOTAL + ? WHERE COF_NAME LIKE ?"); updateTotal.setInt(1, 50); updateTotal.setString(2, "Colombian"); updateTotal.executeUpdate(); con.commit(); con.setAutoCommit(true);
  • 41. 6.3 存储过程创建一个存储过程 create procedure SHOW_SUPPLIERS as select SUPPLIERS.SUP_NAME, COFFEES.COF_NAME from SUPPLIERS, COFFEES where SUPPLIERS.SUP_ID = COFFEES.SUP_ID order by SUP_NAME
  • 42. 6.3 存储过程将上面的SQL语言串保存在一个String变量中,以便后续使用。 String createProcedure = "create procedure SHOW_SUPPLIERS " + "as " + "select SUPPLIERS.SUP_NAME, COFFEES.COF_NAME " + "from SUPPLIERS, COFFEES " + "where SUPPLIERS.SUP_ID = COFFEES.SUP_ID " + "order by SUP_NAME";
  • 43. 6.3 存储过程创建一个Statement连接,并运行这个SQL语句串。 Statement stmt = con.createStatement(); stmt.executeUpdate(createProcedure);
  • 44. 6.3 存储过程JDBC允许用户在应用程序中调用存储过程。首先需要创建一个CallableStatement对象。CallableStatement对象包含一个存储过程调用,而不是包含存储过程本身,存储过程调用要写在{}中,并用“”引起来。
  • 45. 6.3 存储过程CallableStatement cs = con.prepareCall("{call SHOW_SUPPLIERS}"); ResultSet rs = cs.executeQuery();
  • 46. 6.3 存储过程程序执行得到的结果集可能如同下面的形式: SUP_NAME COF_NAME ---------------- ----------------------- Acme, Inc. Colombian Acme, Inc. Colombian_Decaf Superior Coffee French_Roast Superior Coffee French_Roast_Decaf The High Ground Espresso
  • 47. 6.3 存储过程上面的代码中执行cs的方法调用的是executeQuery()方法,这是因为cs调用的存储过程包含了一个查询语句而且只生成一个结果集。如果存储过程中包含的是更新语句或DDL语句,则需要用executeUpdate()方法来调用。