Java程序设计-15-访问数据库.ppt_第1页
Java程序设计-15-访问数据库.ppt_第2页
Java程序设计-15-访问数据库.ppt_第3页
Java程序设计-15-访问数据库.ppt_第4页
Java程序设计-15-访问数据库.ppt_第5页
已阅读5页,还剩29页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Java程序设计,第15章 访问数据库,学习目标,了解JDBC发展历史 能够用不同的方式建立到数据库的连接 利用Statement访问数据 能够在对象和数据库的记录之间进行转换,了解ORM技术 掌握批量更新 能够调用存储过程 了解连接池技术,15.1.1什么是JDBC,JDBC(Java Database Connectivity) 一种用于执行SQL 语句,和数据库进行交互的技术,它由一组用 Java 编程语言编写的类和接口组成。,JDBC的历史 JDBC1.X API规范遵循的是SQL2/SQL92标准,对它的支持的类都定义在java.sql包中。 JDBC2.0规范发布时,增加了对SQL3的支持,并且重点扩展了在应用服务器端访问数据库的功能,相关扩展的类包含在javax.sql中。 目前JDBC已经发布了4.0的版本,其重要的变化集中在丰富的数据类型、元数据的支持、支持标注和应用服务器端编程的特性如数据源、连接池、分布式的事务等。,15.1.2 JDBC 驱动程序类型,JDBC-ODBC 桥加 ODBC 驱动程序 必须提供ODBC驱动程序 本地 API - 部分用 Java 来编写的驱动程序 一种用Java实现的,替代JDBC-ODBC 桥产品的驱动程序 JDBC 网络纯 Java 驱动程序 一种和具体数据库无关的驱动程序。 本地协议纯 Java 驱动程序 一种支持将JDBC调用直接转换为某个具体DBMS的驱动程序,通常由数据库厂家提供,实践中常用,15.2基本的数据库存取过程,实现简单的数据库存取操作是一件很轻松的事情。实现基本的数据存取操作包括三个步骤: 连接到数据库 存取数据 关闭连接。,连接到数据库 连接到数据库需要由驱动程序的支持,在保证已经将驱动程序文件复制到可被运行环境搜索到的位置后,开发对数据库进行存取操作的第一步是建立到指定数据库的连接,这一过程可以细分为两个操作: 加载指定的驱动程序(可选) 获得到指定数据库的连接,public class SqlServerDemo public static void main(String args) String url =“jdbc:sqlserver:/localhost:1433;databaseName=bank; user=sa;password=123456;“; Connection con = null; try con = DriverManager.getConnection(url);/获得到数据库的连接 /获得连接数据库的元数据对象metaData DatabaseMetaData metaData = con.getMetaData(); /输出连接数据库的产品名称 System.out.println(metaData.getDatabaseProductName(); /输出连接数据库的产品版本号 System.out.println(metaData.getDatabaseProductVersion(); con.close();/关闭到数据库的连接,释放资源 catch (SQLException e) e.printStackTrace(); ,1. 加载驱动程序(可选) 检查数据库厂商提供的JDBC驱动程序,可以在对应的位置发现其提供的驱动程序类。通过调用方法 Class.forName(),将显式地加载驱动程序类。,加载SQLServer驱动程序类 Class.forName(“com.microsoft.sqlserver.jdbc.SQLServerDriver“); 加载Oracle驱动程序类 Class.forName(“oracle.thin.Driver “); Class.forName(“oracle.jdbc.driver.OracleDriver“); 加载MySQL驱动程序类 Class.forName(“org.gjt.mm.mysql.Driver “);,2 建立连接 加载 Driver 类之后,应用程序还需显式的获得到数据库的一个连接。当调用 DriverManager.getConnection() 方法发出连接请求时,DriverManager 将检查每个驱动程序,查看它是否可以建立连接。该方法的返回值类型是Connection。,连接所需的URL分析,jdbc: 例如: url= “jdbc:microsoft:sqlserver:/localhost:1433;“ + “databasename=score;User=sa;Password=123456“; 这里的subprotocol是microsoft,除此之外,根据情况还有odbc、oracle、mysql等。而subname则指定了数据源。,Connection,表示了与特定数据库的连接(会话),在连接上下文中执行 SQL 语句并返回结果。,15.3使用Statement访问数据库,Statement对象用于将 SQL 语句发送到数据库系统中。实际上有三种 Statement 对象,它们都作为在给定连接上执行 SQL 语句的包容器: Statement PreparedStatement(继承 Statement) CallableStatement(继承PreparedStatement) 它们都专用于发送特定类型的 SQL 语句: Statement 对象用于执行不带参数的简单 SQL 语句; PreparedStatement 对象用于执行带或不带 IN 参数的预编译 SQL 语句; CallableStatement 对象用于执行对数据库已存储过程的调用。,1 创建 Statement 对象 建立了到特定数据库的连接之后,要想用该连接发送 SQL 语句,首先需要创建一个Statement 对象,可用 Connection 的方法 createStatement 创建。 Statement stmt = con.createStatement();,2 使用 Statement 对象执行语句 ResultSet rs = stmt.executeQuery(“select sid, name, gender from student“); Statement 接口提供了四种执行 SQL 语句的方法。 方法addBatch和executeBatch结合起来使用,执行命令的顺序以添加到批中的顺序为主。 方法 executeQuery 用于产生单个结果集的语句,例如 SELECT 语句。 方法 executeUpdate 用于执行 INSERT、UPDATE 或 DELETE 语句以及 SQL DDL(数据定义语言)语句。 方法 execute 用于执行返回多个结果集、多个更新计数或二者组合的语句。,ResultSet rs = null; rs = stmt.executeQuery(“select sid, name, gender from student“);,3 语句完成 当连接处于自动提交模式时,其中所执行的语句在完成时将自动提交或还原。语句在已执行且所有结果返回时,即认为已完成。对于返回一个结果集的 executeQuery 方法,在检索完 ResultSet 对象的所有行时该语句完成。对于方法 executeUpdate,当它执行时语句即完成。但在少数调用方法 execute 的情况中,在检索所有结果集或它生成的更新计数之后语句才完成。 有些 DBMS 将已存储过程中的每条语句视为独立的语句;而另外一些则将整个过程视为一个复合语句。在启用自动提交时,这种差别就变得非常重要,因为它影响什么时候调用 commit 方法。在前一种情况中,每条语句单独提交;在后一种情况中,所有语句同时提交。,4 关闭 Statement 对象 Statement 对象将由 Java 垃圾收集程序自动关闭。而作为一种好的编程风格,应在不需要 Statement 对象时显式地关闭它们。这将立即释放 DBMS 资源,有助于避免潜在的内存问题。如上述程序中的finally代码块中的语句: stmt.close(); con.close();,15.4ResultSet,ResultSet 包含数据库中存储的符合 SQL 语句中条件的所有记录,并且它通过一套 get 方法(这些 get 方法可以访问当前行中的不同列)提供了对这些记录中数据的访问。 定位记录 获得此记录对应属性的值,15.4.1行和光标,行和光标 ResultSet 对象具有指向其当前数据行的指针。最初,指针被置于第一行之前。next 方法将指针移动到下一行,因为该方法在 ResultSet 对象中没有下一行时返回 false,所以可以在 while 循环中使用它来迭代结果集。 默认的 ResultSet 对象不可更新,仅有一个向前移动的指针。因此,只能迭代它一次,并且只能按从第一行到最后一行的顺序进行。 可更新结果集 Statement stmt = con.createStatement(int resultSetType , int resultSetConcurrency ); 参数resultSetType表示结果集类型。它是 esultSet.TYPE_FORWARD_ONLY、ResultSet.TYPE_SCROLL_INSENSITIVE 或 ResultSet.TYPE_SCROLL_SENSITIVE 之一 参数resultSetConcurrency 表示并发类型 。它是 ResultSet.CONCUR_READ_ONLY 或 ResultSet.CONCUR_UPDATABLE 之一,15.4.2获取列的值,2 访问列 方法 getXXX 提供了获取当前行中某列值的途径。在每一行内,可按任何次序获取列值。但为了保证可移植性,应该从左至右获取列值,并且一次性地读取列值。列名或列号可用于标识要从中获取数据的列。 通过下标获得当前记录指定列的列值 通过字段名获得当前记录指定列的列值 通过字段名或下标获得当前记录未知类型的指定列的列值,String sql=“select id,name,balance from tb_account“; ResultSet rs=stmt.executeQuery(sql); while(rs.next() String id=rs.getString(1); String name=rs.getString(2); int balance=rs.getInt(3); System.out.printf(“id:%s,name:%s,balance:%drn“, id,name,balance); rs.close();,String sql=“select id,name,balance from tb_account“; ResultSet rs=stmt.executeQuery(sql); while(rs.next() String id=rs.getString(“id“); String name=rs.getString(“name“); int balance=rs.getInt(“balance“); System.out.printf(“id:%s,name:%s,balance:%drn“, id,name,balance); rs.close();,Object id=rs.getObject(“id“); Object name=rs.getObject(“name“); Object balance=rs.getObject(“balance“);,15.4.3插入新行,插入新行 直接利用Statement执行 insert语句。 当Statement对象的结果集类型是可更新的时候, ResultSet对象具有一个与其关联的特殊行,该行用作构建要插入的行的暂存区域 (staging area),利用它可以完成向数据表的插入操作。,rs.moveToInsertRow();/ 定位插入行位置,然后更新每个字段的值 rs.updateString(“id“, uuid.toString(); rs.updateNString(“name“, name); rs.updateInt(“balance“, balance); rs.insertRow();/将插入行的内容插入到此 ResultSet 对象和数据库,15.4.4更新列值,更新列值 同样地批量的修改可以用Statement执行SQL来确定 ResultSet提供了针对一条记录某个字段进行修改的方法updateXXX;,ResultSet rs = stmt.executeQuery(“select id,name,balance“ + “ from tb_account where name=张华“); if(rs.next() /假如找到这样符合条件的记录 rs.updateInt(“balance“, 100); rs.updateRow(); ,15.4.5删除记录行,删除记录 同样地批量的删除可以用Statement执行SQL来确定 ResultSet提供了删除一条记录的方法deleteRow();,ResultSet rs = stmt.executeQuery(“select * from tb_account where balance=0“); while (rs.next() / 逐个删除每条记录 rs.deleteRow(); rs.close();,6 数据类型和转换 对于 getXXX 方法,JDBC 驱动程序试图将基本数据转换成指定 Java 类型,然后返回适合的 Java 值。例如,如果 getXXX 方法为 getString,而基本数据库中数据类型为 VARCHAR,则 JDBC 驱动程序将把 VARCHAR 转换成 Java String。getString 的返回值将为 Java String 对象。,7 对非常大的行值使用I/O流 JDBC API 具有三个获取流的方法,分别具有不同的返回值: getBinaryStream 返回只提供数据库原字节而不进行任何转换的流。 getAsciiStream 返回提供单字节 ASCII 字符的流。 getCharacterStream(返回提Reader类型字符的流。,8 NULL 结果值 在读取字段值时,一般而言要对一些不明确值是否存在的字段值进行空值判断。要确定给定结果值是否是 JDBC NULL,必须先读取该列,然后使用 ResultSet.wasNull 方法检查该次读取是否返回 JDBC NULL。,15.5 PreparedStatement,PreparedStatement 继承于Statement,它允许使用可替代的参数修改最终执行的SQL语句,,PreparedStatement pstmt = con.prepareStatement( “insert into tb_account(id,name,balance) values(?,?,?)“);,UUID uuid = UUID.randomUUID(); pstmt.setString(1, uuid.toString();/设置id字段的值 pstmt.setString(2, “王军“);/设置name字段的值 pstmt.setInt(3, 1000); /设置balance字段的值 pstmt.executeUpdate(); /用前面的实参值,替代原来的参数,执行SQL语句,PreparedStatement pstmt = con.prepareStatement( “select id,name,balance from tb_account where name=?“, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); pstmt.setString(1, “张华“); ResultSet rs = pstmt.executeQuery();,15.6 CallableStatement,CallableStatement JDBC中提供了CallableStatement 对象为所有的 DBMS 实现了一种以标准形式调用储存过程的方法。对储存过程的调用是 CallableStatement对象所含的主要内容。,CREATE procedure sumBalance low int, high int as begin declare total int select total=sum(balance) from tb_account where balance=low and balance=high return total end;,CallableStatement cstmt = con.prepareCall(“?=call sumBalance(?,?)“);,Connection con = null; try (01) con = DriverManager.getConnection(url); (02) String procName=“?=call sumBalance(?,?)“; (03) CallableStatement cstmt = con.prepareCall(procName); (04) cstmt.setInt(2, 1000); (05) cstmt.setInt(3, 10000); (06) cstmt.registerOutParameter(1, Types.INTEGER); (07) cstmt.execute(); (08) System.out.println(cstmt.getInt(1); (09) cstmt.close(); (10) con.close(); catch (SQLException e) e.printStackTrace(); ,15.7 JDBC事务,事务 数据库的事务就是对现实生活中事务的模拟,它由一组在业务逻辑上相互依赖的SQL语句组成。为了保证事务的完整性,JDBC提供了相应的事务控制机制。 事务提交模式 在JDBC编程模型中,一个数据库连接建立时,就处于一个自动提交模式,每一个SQL语句被执行完成后就会被自动提交,反映至数据库中。当需要把几条逻辑上相关的SQL组成一个事务执行时,就需要关闭事务自动提交模式。如下面的语句所示: con.setAutoCommit(false);/关闭自动提交模式 一旦关闭了事务自动提交模式,不会有任何SQL语句被提交至数据库系统执行,除非显式的调用提交方法。,public void transfer(Account a,Account b,int amount)throws SQLException PreparedStatement pstmt =null; String sql=“update tb_account set balance=? where id=?“; try pstmt = con.prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE); /关闭自动提交模式,以下语句直到commit()前都作为一个完整的事务执行 con.setAutoCommit(false); /开始处理转账,将账户a上减少amount元 p

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论