10 JDBC数据库编程.ppt
第十章第十章JDBC数据库编程数据库编程210.1.1 JDBC 的概述的概述JDBC 是一种可以用来执行是一种可以用来执行SQL语句的底层语句的底层Java API,对于不同的数据库系统,在功能层次上提供了统一的访对于不同的数据库系统,在功能层次上提供了统一的访问方法。问方法。构成:由构成:由Java语言编写的接口和类组成语言编写的接口和类组成数据库访问功能:数据库访问功能:打开打开/关闭数据库连接关闭数据库连接与数据库通信与数据库通信执行执行 SQL 语句语句 检索查询结果检索查询结果3 JDBC提供连接各种常用数据库的能力,可以为多提供连接各种常用数据库的能力,可以为多种关系数据库提供统一的访问接口。种关系数据库提供统一的访问接口。Java应用程序应用程序JDBCJDBCJSP/Servlet客户端客户端数据库服务器数据库服务器J2EE应用服应用服务器务器数据库服务器数据库服务器客户端客户端4ODBC(Open Database Connectivity)简介简介微软开发的在微软开发的在Windows平台数据库访问的平台数据库访问的C语语言的言的API,不适合,不适合Java中直接使用。中直接使用。ODBC 提供一个与提供一个与数据库数据库类型类型无关的前端应用无关的前端应用和后端数据库和后端数据库系统系统之间的接口之间的接口,通过配置数据源,通过配置数据源,允许用户访问来自不同允许用户访问来自不同类型类型的数据库的数据库。5ODBC不适合在不适合在Java中直接使用:中直接使用:ODBC是一个是一个C语言实现的语言实现的API,从,从Java中调用本地的中调用本地的C程序在安程序在安全性、完整性、健壮性方面都有缺点。全性、完整性、健壮性方面都有缺点。无法精确实现从无法精确实现从ODBC API到到Java API的翻译的翻译(语言限制:指针支持,操作系统限制)。(语言限制:指针支持,操作系统限制)。为什么不直接使用为什么不直接使用ODBC?6JDBC的构成的构成(1)面向)面向Java程序员的程序员的JDBC API:通过调用通过调用JDBC API可实现连接数据库、执行可实现连接数据库、执行SQL语句语句并返回结果集,是由并返回结果集,是由JDK定义的接口所构成:定义的接口所构成:java.sql.Driverjava.sql.Connectionjava.sql.Statementjava.sql.PreparedStatementjava.sql.CallableStatementjava.sql.ResultSet.7(2)面向数据库厂商的)面向数据库厂商的JDBC Driver(驱动):(驱动):数据库厂商必须提供相应的驱动并实现数据库厂商必须提供相应的驱动并实现JDBC API所要求的基本接口所要求的基本接口每个数据库驱动必须针对该数据库提供对每个数据库驱动必须针对该数据库提供对Driver、Connection、Statement、ResultSet等接口的等接口的具体实现类,从而保证具体实现类,从而保证Java程序员通过调用程序员通过调用JDBC API实现对不同的数据库操作。实现对不同的数据库操作。8JDBC程序的结构程序的结构JDBC API提供:提供:JDK定义定义内容:供编程调用的接口,位于内容:供编程调用的接口,位于java.sql包中包中Driver Manager(DriverManager类)类)提供:提供:JDK实现实现作用:载入各种不同的作用:载入各种不同的JDBC驱动驱动JDBC 驱动驱动提供:数据库厂商提供:数据库厂商内容:连接特定的数据库的内容:连接特定的数据库的JDBC API接口实现类接口实现类SqlSql ServerServerOracleOracleJDBC API JDBC Driver Manager JDBC 驱动驱动 JDBC 驱动驱动 Java 应用程序应用程序 9JDBC API、Driver Manager、JDBC 驱动驱动之间的关系之间的关系(1)JDBC API为为JDK定义的接口和类,具体功能定义的接口和类,具体功能实现在实现在JDBC驱动中;驱动中;如:如:JDBC API 定义了定义了Driver、ResultSet 等等接口,需要在接口,需要在JDBC驱动的实现类中实现这些接口;驱动的实现类中实现这些接口;(2)对于不同的数据库,)对于不同的数据库,JDBC 驱动不同,驱动不同,Driver Manager用来管理用来管理JDBC 驱动,进行注册驱动。驱动,进行注册驱动。(3)应用程序调用的是)应用程序调用的是JDBC API,故从编程角度访,故从编程角度访问所有数据库可采用一致的方法。问所有数据库可采用一致的方法。10JDBC API可完成:与数据库建立连接、执行可完成:与数据库建立连接、执行SQL 语句、处理结果语句、处理结果ConnectionDriverManagerStatementResultSet DriverManager:依据数据库的不同,管理:依据数据库的不同,管理JDBC驱动驱动 Connection:负责连接数据库并担任传送数据的任务:负责连接数据库并担任传送数据的任务 Statement:由由 Connection 产生、负责执行产生、负责执行SQL语句语句 ResultSet:负责保存:负责保存Statement执行后所产生的查询结果执行后所产生的查询结果客户端客户端数据库服务器数据库服务器12341110.1.2 JDBC 驱动类型驱动类型JDBC驱动程序的类型驱动程序的类型JDBC-ODBC 桥驱动桥驱动本地协议纯本地协议纯 Java 驱动驱动JDBC 网络纯网络纯 Java 驱动驱动纯纯 Java 驱动驱动12JDBC-ODBC桥桥JDBC-ODBC桥桥Java 应用程序应用程序 JDBC APIODBC APIODBC层层DBDBServerServer将对将对JDBC API的调用,转换为对的调用,转换为对ODBC连接连接API的调用的调用优点:可以访问所有优点:可以访问所有ODBC可以访问的数据库可以访问的数据库缺点:执行效率低、功能不够强大缺点:执行效率低、功能不够强大一般在个人开发与测试中使用一般在个人开发与测试中使用13本地协议纯本地协议纯Java驱动驱动 利用数据库提供商的本地库来直接和数据库利用数据库提供商的本地库来直接和数据库通信,不同的数据库不同。通信,不同的数据库不同。可移植性比较差,但效率最快。可移植性比较差,但效率最快。本地本地JDBC 驱动驱动 Java 应用程序应用程序 JDBC API DBDBServerServer本地本地API 14JDBC 网络纯网络纯 Java 驱动驱动 主要利用中间件提供数据连接池的服务,如主要利用中间件提供数据连接池的服务,如使用使用tomcat 连接池。连接池。Java 应用程序应用程序 JDBC API中间件中间件JDBC驱动驱动DBDBServerServer15纯纯 Java 驱动驱动JDBC 驱动驱动 Java 应用程序应用程序 JDBC API DBDBServerServer由由JDBC驱动直接访问数据库驱动直接访问数据库优点:优点:100%Java,快又可跨平台,快又可跨平台缺点:访问不同的数据库需下载专用的缺点:访问不同的数据库需下载专用的JDBC驱动驱动1610.1.3 配置配置ODBC数据源数据源目的:目的:使用使用jdbc-odbc桥接驱动方式访问数据库桥接驱动方式访问数据库(access)1718选择数据选择数据库所在地库所在地路径路径1910.1.4 JDBC数据库编程步骤数据库编程步骤六步使用六步使用 JDBC:(1)加载)加载 JDBC Driver(2)获取与数据库)获取与数据库 Connection(3)创建)创建 Statement对象对象(4)执行)执行 SQL语句语句(5)处理)处理 ResultSet(针对查询语句针对查询语句)(6)关闭)关闭 Connection202110.1.4 JDBC数据库编程步骤数据库编程步骤(1)使用)使用jdbc-odbc桥的方式:桥的方式:首先创建首先创建odbc源源(操作如前所示操作如前所示)加载驱动:加载驱动:Class.forName(sun.jdbc.odbc.JdbcOdbcDriverClass.forName(sun.jdbc.odbc.JdbcOdbcDriver););Class.forName(xxx.xx.xx);作用:要求作用:要求JVM查找并加载指定的类,查找并加载指定的类,JVM会会执行该类的静态代码段执行该类的静态代码段22JDBC规范中要求驱动的规范中要求驱动的Driver实现类必须向实现类必须向DriverManager 注册自己,即任何一个注册自己,即任何一个JDBC Driver的的Driver类的代码都必须类似如下:类的代码都必须类似如下:public class MyJDBCDriver implements Driver static DriverManager.registerDriver(new MyJDBCDriver();所以在使用所以在使用JDBC时需要时需要Class.forName(XXX.XXX);为什么调用为什么调用Class.forName?2310.1.4 JDBC数据库编程步骤数据库编程步骤(2)建立连接建立连接 Connection Connection connconn=DriverManager.getConnection(urlDriverManager.getConnection(url,login_name,login_name,login_passwordlogin_password););对于对于Access:Connection conn=DriverManager.getConnection(“jdbc:odbc:testdb”,“”,“”);2410.1.4 JDBC数据库编程步骤数据库编程步骤(1)使用纯)使用纯Java驱动方式:驱动方式:首先需要下载数据库的驱动,之后在首先需要下载数据库的驱动,之后在IDE中引入中引入驱动程序包(驱动程序包(jar文件)文件)加载驱动(加载驱动(SqlServer2000为例):为例):Class.forName(Class.forName(com.microsoft.jdbc.sqlserver.SQLServerDriver););2510.1.4 JDBC数据库编程步骤数据库编程步骤(2)建立连接建立连接 Connection Connection connconn=DriverManager.getConnection(urlDriverManager.getConnection(url,login_name,login_name,login_passwordlogin_password););SqlServer2000为例:为例:Connection conn=DriverManager.getConnection(jdbc:microsoft:sqlserver:/localhost:1433;DatabaseName=sample,sa,sql);注意:注意:SqlServer2000需安装需安装SP4补丁,选择混合认证模式补丁,选择混合认证模式2610.1.4 JDBC数据库编程步骤数据库编程步骤(3)创建创建Statement对象对象Statement 对象可将对象可将 SQL 语句发送到语句发送到 DBMS Statement stmt=conn.createStatement();27(4)使用)使用Statement 对象执行对象执行SQL语句语句int executeUpdate(String sql)用来执行用来执行INSERT、UPDATE 或或 DELETE语语句句;返回为整型数,表示对多少条记录产生了影响返回为整型数,表示对多少条记录产生了影响28ResultSet executeQuery(String sql)执行执行SELECT 语句语句 查询到数据返回为查询到数据返回为ResultSet类型类型boolean execute(String sql)用于执行任何用于执行任何 SQL 语句。语句。返回布尔值,有返回结果为返回布尔值,有返回结果为true,否则,否则false。29(5)处理)处理 ResultSetResultSet 包含包含 SQL 语句的执行结果语句的执行结果ResultSet对象具有指向其当前数据行的指针。最初,对象具有指向其当前数据行的指针。最初,指针被置于第一行之前。指针被置于第一行之前。指针移动方法:指针移动方法:boolean next()将指针从当前位置下移一行将指针从当前位置下移一行boolean previous()将指针从当前位置上移一行将指针从当前位置上移一行boolean absolute(int row)将指针移动到给定行将指针移动到给定行boolean first()将指针移动到第一行将指针移动到第一行boolean last()将指针移动到最后一行将指针移动到最后一行30使用使用 getXXX 方法获取数据方法获取数据:int getInt(int columnIndex)int getInt(String columnName)用于获取整型值用于获取整型值String getString(int columnIndex)String getString(String columnName)用于获取字符用于获取字符串值串值short getShort(int columnIndex)short getShort(String columnName).ResultSet使用完调用使用完调用close()关闭关闭31(6)关闭数据库)关闭数据库关闭关闭 Statement 对象对象stmt.close();关闭关闭 Connection 对象对象conn.close();3210.2 JDBC API常用类和接口常用类和接口管理驱动的类:管理驱动的类:DriverManager数据库的驱动接口:数据库的驱动接口:Driver与数据库连接接口:与数据库连接接口:Connection执行执行SQL语句的接口:语句的接口:Statement PreparedStatement CallableStatement返回结果集的接口:返回结果集的接口:ResultSetJDBC API包含以下主要的类和接口:包含以下主要的类和接口:33DriverManager类类用来管理用来管理Driver对象,提供了注册驱动、获对象,提供了注册驱动、获得连接及与数据库系统通信的功能。得连接及与数据库系统通信的功能。重要方法重要方法:registerDriver():注册注册Driver对象;对象;getConnection():试图建立到给定数据库试图建立到给定数据库 URL 的连接的连接,DriverManager 试图从已试图从已注册的驱动程序集中选择一个适当的驱动注册的驱动程序集中选择一个适当的驱动程序。程序。34Driver接口接口数据库的驱动需要提供一个数据库的驱动需要提供一个 Driver 接口的接口的实现类。实现类。用于读取数据库驱动的基本信息,提供了用于读取数据库驱动的基本信息,提供了connect()方法供方法供DriverManager调用建立访问数据调用建立访问数据库所用的库所用的Connection对象。对象。35Connection接口:连接数据库接口:连接数据库 数据库驱动需要提供数据库驱动需要提供Connection接口的实现类。接口的实现类。重要方法:重要方法:Statement createStatement()创建创建Statement对象。对象。PreparedStatement prepareStatement(String sql)创建创建PreparedStatement对象对象36Statement接口:接口:数据库驱动需要提供数据库驱动需要提供Statement接口的实现类。接口的实现类。功能:执行功能:执行sql语句,得到数据库的返回结果语句,得到数据库的返回结果ResultSet executeQuery(SQL)int executeUpdate(SQL)boolean execute(SQL)close()。37ResultSet接口:接口:数据库驱动需要提供数据库驱动需要提供ResultSet接口的实现类。接口的实现类。功能:表示数据库查询返回的结果,通常通过执功能:表示数据库查询返回的结果,通常通过执行查询数据库的语句生成。行查询数据库的语句生成。38创建创建Statement对对ResultSet的影响的影响1、产生结果集、产生结果集Statement stm=con.createStatement();ResultSet rst=stm.executeQuery(sql);用缺省设置创建用缺省设置创建Statement,查询得到,查询得到ResultSet 是是一种只能访问一次(一种只能访问一次(one-time-through)、只能向前)、只能向前访问(访问(forward-only)和只读的对象。)和只读的对象。只能访问只能访问ResultSet数据一次,如果再次需要该数据,数据一次,如果再次需要该数据,必须重新查询数据库。必须重新查询数据库。39Statement stm=con.createStatement(resultSetType,resultSetConcurrency);ResultSet rst=stm.executeQuery(sql);resultSetType指定指定 ResultSet 的类型的类型:ResultSet.TYPE_FORWARD_ONLY:缺省类型。只允许向前:缺省类型。只允许向前访问一次,并且不会受到其他用户对该数据库所作更改的影响。访问一次,并且不会受到其他用户对该数据库所作更改的影响。ResultSet.TYPE_SCROLL_INSENSITIVE:允许向前或向后移:允许向前或向后移动指针与进行指针定位,不会受到其他用户对所作更改的影响。动指针与进行指针定位,不会受到其他用户对所作更改的影响。ResultSet.TYPE_SCROLL_SENSITIVE:允许移动与定位,受:允许移动与定位,受到其他用户所作更改的影响。到其他用户所作更改的影响。40resultSetConcurrency设置设置 ResultSet 的并发性,确定是的并发性,确定是否可以通过否可以通过 ResultSet更新数据库。更新数据库。ResultSet.CONCUR_READ_ONLY:缺省值,不可以使用查询:缺省值,不可以使用查询到的到的ResultSet更新数据库;更新数据库;即即ResultSet为只读,不能通过为只读,不能通过ResultSet 的deleteRow()、update系列方法更新数据库。系列方法更新数据库。ResultSet.CONCUR_UPDATABLE:可以使用:可以使用 ResultSet更更新数据库;新数据库;即可通过即可通过ResultSet 的deleteRow()、update系列方法更新数系列方法更新数据库。据库。41Statement关于关于SELECT语句使用:语句使用:/不带参数不带参数String sql=select*from users;String sql=select*from users where name=张三张三 and sno=123;/带有参数(采用带有参数(采用+拼接字符串)拼接字符串)String sql=select*from users where name=+name+and sno=+no;/执行查询执行查询ResultSet rs=stm.executeQuery(sql);422、处理结果集、处理结果集判断是否有查询结果判断是否有查询结果if(rs.next()循环处理结果集内容循环处理结果集内容while(rs.next()rs.getString(1);rs.getInt(2);rs.getDate(3);3、操作方法、操作方法int getRow()boolean previous()boolean first()boolean last()boolean absolute()43使用使用Statement查询时注意:查询时注意:(1)一个)一个Statement对象在同一时刻只能查询获取一个对象在同一时刻只能查询获取一个ResultSet,再次执行查询时会隐含将前一个,再次执行查询时会隐含将前一个ResultSet关闭;关闭;(2)如果要同时打开多个)如果要同时打开多个ResultSet,需要创建多个,需要创建多个Statement对象。对象。44Statement执行执行添加、更新和删除添加、更新和删除Statement stm=con.createStatement();String sql=insert into users values (+name+,+age+,+sno+,+email+);int u=stm.executeUpdate(sql);if(u0)System.out.println(“添加成功添加成功”);45PreparedStatement对象对象 能执行带变量的能执行带变量的SQL语句。变量是在后面的程语句。变量是在后面的程序代码中设置的,或在程序执行期间动态指定序代码中设置的,或在程序执行期间动态指定的。的。使用使用PreparedStatement的优点:的优点:可以使用此对象高效地多次执行该语句可以使用此对象高效地多次执行该语句;可以防止;可以防止SQL注入攻击,防止数据库缓冲池溢出,代码的可读注入攻击,防止数据库缓冲池溢出,代码的可读性,可维护性。性,可维护性。46添加、更新和删除添加、更新和删除(1)设置设置SQL语句创建语句创建String sql=“insert into Employer values(?,?,?,?)”;pstm=con.preparStatement(sql);(3)设置参数的值设置参数的值pstm.setInt(1,12);pstm.setString(2,”wang”);pstm.setString(3,”);Pstm.setString(4,”2081122”)(4)执行语句执行语句pstm.executeUpdate();pstm.executeQuery();47prepareStatement(sql,resultSetType,resultSetConcurrency);resultSetType取值:取值:ResultSet.TYPE_FORWARD_ONLY、ResultSet.TYPE_SCROLL_INSENSITIVE、ResultSet.TYPE_SCROLL_SENSITIVEresultSetConcurrency取值:取值:ResultSet.CONCUR_READ_ONLY、ResultSet.CONCUR_UPDATABLE可以指定可以指定PrepareStatement结果集类型和并发性结果集类型和并发性 48JDBC事务操作简介事务操作简介在在JDBC的数据库操作中,一项事务是由一条或是的数据库操作中,一项事务是由一条或是多条表达式所组成的一个不可分割的工作单元多条表达式所组成的一个不可分割的工作单元。关于事务操作的方法都位于接口关于事务操作的方法都位于接口Connection中中,通过提交通过提交commit()或是回滚或是回滚rollback()来结束事务的来结束事务的操作。操作。在在JDBC中,事务操作缺省是自动提交。一条对数据库的更中,事务操作缺省是自动提交。一条对数据库的更新表达式代表一项事务操作,操作成功后,系统将自动调用新表达式代表一项事务操作,操作成功后,系统将自动调用commit()来提交,否则将调用来提交,否则将调用rollback()来回滚。来回滚。49通过调用通过调用setAutoCommit(false)禁止自动提交,之禁止自动提交,之后可以把多个数据库操作的表达式作为一个事务后可以把多个数据库操作的表达式作为一个事务:在操作完成后调用在操作完成后调用commit()来进行整体提交,若其来进行整体提交,若其中一个表达式操作失败,都不会执行到中一个表达式操作失败,都不会执行到commit(),并且将产生响应的异常;此时就可以在异常捕获时并且将产生响应的异常;此时就可以在异常捕获时调用调用rollback()进行回滚。进行回滚。这样可以保持多次更新操作后,相关数据的一致性。这样可以保持多次更新操作后,相关数据的一致性。50 try conn=DriverManager.getConnection(.);conn.setAutoCommit(false);/禁止自动提交禁止自动提交 stmt=conn.createStatement();stmt.executeUpdate(alter table);stmt.executeUpdate(insert into table);mit();/事务提交事务提交 catch(Exception ex)try conn.rollback();/操作不成功则回滚操作不成功则回滚 catch(Exception e)5110.3 JDBC示例示例数据库操作实例数据库操作实例添加员工资料到数据库中,并可实现对数添加员工资料到数据库中,并可实现对数据的基本操作。据的基本操作。52MVC分层原理分层原理M(module):模型(数据访问层):模型(数据访问层)维护数据维护数据并提供数据访问方法并提供数据访问方法V(view):视图(表示层):视图(表示层)数据的显示数据的显示 C(control):控制器(业务层):控制器(业务层)处理用户命处理用户命令以及程序事件,业务逻辑令以及程序事件,业务逻辑10.3 JDBC示例示例53数据访问数据访问层层数据持久层数据持久层业务层业务层表示层表示层数据映射层数据映射层10.3 JDBC示例示例J2EE等企业系统开发时通常将数据访问层划分出来等企业系统开发时通常将数据访问层划分出来54连接数据库。连接不同的数据库,在该层连接数据库。连接不同的数据库,在该层会有区别,在其它层中各数据库的区别被会有区别,在其它层中各数据库的区别被隐藏。所以,即使更换数据库,也只对该隐藏。所以,即使更换数据库,也只对该层有影响。层有影响。(2)数据访问层数据访问层