《java网络编程第3章1.ppt》由会员分享,可在线阅读,更多相关《java网络编程第3章1.ppt(56页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第三章第三章JDBC数据库访问技术数据库访问技术 课程目标课程目标JDBC技术概述:JDBC的概念JDBC的诞生JDBC的任务JDBC驱动程序分类JDBC的应用:DriverManager类Connection接口Statement接口ResultSet接口ResultSetMetaData接口PreparedStatement接口CallableStatement接口 课程定位课程定位JDBC的概念的概念 JDBC是一种可用于执行SQL语句的JAVA API(Application Programming Interface应用程序设计接口)。JDBC为数据库应用开发人员和数据库前台工具开发
2、人员提供了一种标准的应用程序设计接口,使开发人员可以用纯JAVA语言编写完整的数据库应用程序。JDBC的任务的任务 简单地说,JDBC能完成下列三件事:和某个数据库建立连接和某个数据库建立连接向数据库发送向数据库发送SQL语句语句处理数据库返回的结果处理数据库返回的结果 JDBC驱动程序分类驱动程序分类(1)第一类JDBC驱动程序是JDBC-ODBC桥再加上一个ODBC驱动程序。尽管SUN公司提供了JDBC-ODBC桥接驱动程序,但由于ODBC会在客户端装载二进制代码和数据库客户端代码,这种技术不适用于高事务性的环境。另外,第一类JDBC驱动程序不支持完整的JAVA命令集,而是局限于ODBC驱
3、动程序的功能。JDBC 连接类型连接类型 1JDBC驱动程序分类驱动程序分类(2)第二类JDBC驱动程序是部分JAVA API代码的驱动程序,用于把JDBC调用转换成主流数据库API的本机调用。这类驱动程序也存在与第一类驱动程序一样的性能问题,即客户端载入二进制代码的问题,而且它们被绑定了特定的平台。第二类驱动程序要求编写面向特定平台的代码,这对于任何JAVA开发者来说恐怕都不属于真正乐意做的事情。主流的数据库厂商,例如Oracle和IBM,都为它们的企业数据库平台提供了第二类驱动程序,使用这些驱动程序的开发者必须及时跟进不同数据库厂商针对不同操作系统发行的各个驱动程序版本。JDBC驱动程序分
4、类驱动程序分类(3)第三类JDBC驱动程序是面向数据库中间件的纯JAVA驱动程序,JDBC调用被转换成一种中间件厂商的协议,中间件再把这些调用转换到数据库API。第三类JDBC驱动程序的优点是它以服务器为基础,也就是不再需要客户端的本机代码,这使得第三类驱动程序要比第一、二两类快。另外,开发者还可以利用单一的驱动程序连接到多种数据库。JDBC驱动程序分类驱动程序分类(4)第四类JDBC驱动程序是直接面向数据库的纯JAVA驱动程序,即所谓的“瘦”(thin)驱动程序,它把JDBC调用转换成某种直接可被DBMS使用的网络协议,这样,客户机和应用服务器可以直接调用DBMS服务器。对于第四类驱动程序,
5、不同DBMS的驱动程序是不同的。因此,在一个异构计算环境中,驱动程序的数量可能会比较多。但是,由于第四类驱动程序具有较高的性能,能够直接访问DBMS,所以这一问题就显得不那么突出了。JDBC 连接类型连接类型DriverManager类类 DriverManager类 该类是控制应用程序和JDBC驱动程序之间的接口。DriverManager类还提供了一系列管理驱动程序的服务“jdbc.drivers”系统属性中引用的驱动程序类。如果该属性存在,则应该有一串单独的驱动程序名字,如在/.hotjava/properties 文件中,用户可以指定:jdbc.drivers=foo.bah.Driv
6、er:wombat.sql.Driver:bad.taste.ourDriver。当getConnection()方法被调用的时候,它就在这一系列的驱动程序中进行搜索,直到找到能定位到URL所指向的数据库的驱动程序为止。DriverManager的常用方法的常用方法 1.deregisterDriver(Driver driver)用于从DriverManager的列表中删除一个驱动程序。2.getConnection(String url,String user,String password)试图建立到给定数据库URL的连接。3.getLoginTimeout()获得驱动程序试图登录到某一
7、数据库时可以等待的最长时间,时间以秒为单位。4.setLoginTimeout(int seconds)置驱动程序试图连接到某一数据库时将等待的最长时间,以秒为单位。上面的方法中最常用的是getConnection(String url,String user,String password)方法,它是用来获得数据库的连接Connection接口类,Connection类是什么我们下节将要讲解的。Connection接口接口 Connection是一个接口类,其功能是与数据库进行连接(会话),用于在连接上下文中执行SQL语句并返回结果。我们使用如下形式来建立一个Connection接口类对象。
8、Class.forName(com.microsoft.jdbc.sqlserver.SQLServerDriver);/返回与带有给定字符串名的类或接口相关联的Class对象。Connection conn=DriverManager.getConnection(url,username,password);对象模型对象模型Connection的常用方法的常用方法 close()方法commit()方法createStatement(int resultSetType,int resultSetConcurrency)方法getAutoCommit()方法isClosed()方法prepar
9、eCall(String sql)方法prepareStatement(String sql)方法rollback()方法setAutoCommit(boolean autoCommit)方法示例示例1.import java.sql.*;2.public class Dao3.4.public static void main(String args)5.6.new Dao();7.8.public Dao()9.10.try 11.12.Class.forName(com.microsoft.jdbc.sqlserver.SQLServerDriver);13./返回与带有给定字符串名的类
10、或接口相关联的Class对象。14.Connection conn=DriverManager.getConnection(15.jdbc:microsoft:sqlserver:/localhost:1433;databasename=phoneroot,sa,);16.System.out.println(连接成功);17.catch(Exception e)18.19.System.out.println(连接失败);20.e.printStackTrace();21.22.23.Statement接口接口 Statement本身就是一个接口类,他主要被用于执行关于SQL的动作(如添、删
11、、改、查),并返回它所生成的结果对象,我们通常使用如下形式来建立Statement对象:Connection conn=DriverManager.getConnection(url,username,password);Statement stm=conn.createStatement();Statement接口类还派生出两个接口类PreparedStatement和CallableStatement,这两个接口类对象为我们提供了更加强大的数据访问功能。Statement的常用方法的常用方法 executeQuery(String sql)方法为查询数据的方法,他执行给定的SQL语句,并返
12、回数据库记录集ResultSet对象,如果执行该方法时出现错误,就产生SQLException异常,运行时记着处理异常。该方法示例如下:ResultSet rs=stm.executeQuery(select*from roots);executeUpdate(String sql)方法这个方法执行给定的SQL语句,他可以为INSERT、UPDATE或DELETE语句,还可以用来执行数据定义语言(DDL),如:create table和drop table等等。INSERT、UPDATE、DELETE语句可以对一个表中的行或列进行添加、删除或修改。这个方法的返回值是整型,代表了这个方法在执行后
13、所作用的行数,使用create table和drop table语句时的返回值是,因为数据定义语言(DDL)不作用于具体的行,该方法示例如下:stm.executeUpdate(insert into roots values(张三,12345678);示例示例1.import java.sql.*;2.public class Dao3.4.public static void main(String args)5.6.new Dao();7.8.public Dao()9.10.try 11.12.Class.forName(com.microsoft.jdbc.sqlserver.SQL
14、ServerDriver);13./返回与带有给定字符串名的类或接口相关联的Class对象。14.Connection conn=DriverManager.getConnection(15.jdbc:microsoft:sqlserver:/localhost:1433;DatabaseName=phoneroot,sa,);16.Statement st=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE17.,ResultSet.CONCUR_UPDATABLE);18.int i=st.executeUpdate(insert in
15、to roots values(张三,1234567);19./向数据库表插入一条数据20.System.out.println(你成功的操作了+i+数据);21.catch(Exception e)22.System.out.println(连接失败);23.e.printStackTrace();24.25.26.ResultSet接口接口 游标 当一个结果集产生以后,我们如何才能随意的进行存取结果集数据呢?这就需要引入一个新的概念游标。如果将结果集看成一张二维表,那么我们就可以将游标看成一个可控制的、可以指向任意一条记录的指针。有了这个指针我们就能轻易地指出我们要对结果集中的哪一条记录进
16、行修改、删除,或者要在哪一条记录之前插入数据。一个结果集对象中只包含一个游标。常见的结果集有两种:可滚动的结果集和可更新的结果集。可滚动的结果集可滚动的结果集 JDBC中有只进游标(TYPE_FORWARD_ONLY)滚动_敏感游标(TYPE_SCROLL_SENSITIVE)滚动_不敏感游标(TYPE_SCROLL_INSENSITIVE)可更新的结果集可更新的结果集 一个结果集有不同的更新特性,它分为可动态更新和不可动态更新。可动态更新的结果集由于能够动态更新,所以它对更新记录提供了很大的方便。下面是JDBC提供的两种不同的更新类型:CONCUR_READ_ONLY:这种结果集不可以被动态
17、更新,他可以提供最大程度的并发访问。当一个只读结果集使用一个只读的标识时,这时只允许用户读取数据而不允许用户修改它,因为只读的结果集不需要对只读锁进行限制,所以实际上并发访问的用户也没有限制。CONCUR_UPDATABLE:这种结果集可以被动态地更新,降低了可以并发的程度,可更新结果集可以使用一个只写标识来限制在某一个时刻只能有一个用户往数据库中写数据,所以这就限制了多个用户试图同时改变数据,但是保证了数据的一致性。ResultSet接口接口 ResultSet对象通常用于保存数据库的结果集,比如,我们可以使用如下的形式来建立ResultSet对象:Connection conn=Drive
18、rManager.getConnection(url,username,password);Statement stm=conn.createStatement();ResultSet rs=stm.executeQuery(select*from roots);(续)(续)ResultSet对象具有指向其当前数据行的指针。ResultSet对象生成时,指针被置于第一行之前。而使用next()方法将可以把指针移动到下一行;在ResultSet对象中没有下一行时next()方法将返回false。默认的ResultSet对象不可更新,仅有一个向下移动的指针。因此,只能迭代它一次,并且只能按从第一行
19、到最后一行的顺序进行。可以生成可滚动或可更新的ResultSet对象。以下代码是关于如何生成可滚动且不受其他更新影响的、可更新的结果集。下面是ResultSet的用法,代码如下:Statement stmt=con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);ResultSet rs=stmt.executeQuery(SELECT*FROM roots);ResultSet的常用方法的常用方法 1.absolute(int row)方法将指针移动到此ResultSet对象的给定行。
20、2.beforeFirst()方法将指针移动到此ResultSet对象的开头,并且位于第一行之前,ResultSet默认也是在第一行之前。3.first()方法将指针移动到此ResultSet对象的第一行。4.last()方法 将指针移动到此ResultSet对象的最后一行。5.afterLast()方法将指针移动到此ResultSet对象的末尾,使他位于最后一行之后。6.next()方法将指针从当前位置向下移一行。7.previous()方法将指针移动到此ResultSet对象的上一行。8.getString(int columnIndex)方法以JAVA编程语言中String的形式检索此R
21、esultSet对象的当前行中指定列的值,参数可以是列名也可以是列的序号。示例示例1.import java.sql.*;2.public class Dao3.4.public static void main(String args)5.6.new Dao();7.8.public Dao()9.10.try 11.12.Class.forName(com.microsoft.jdbc.sqlserver.SQLServerDriver);13.Connection conn=DriverManager.getConnection(14.jdbc:microsoft:sqlserver:/
22、localhost:1433;DatabaseName=phoneroot,sa,);15.Statement st=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE16.,ResultSet.CONCUR_UPDATABLE);17.ResultSet rs=st.executeQuery(select*from roots);18.while(rs.next()/游标向下移动19.for(int i=0;i3;i+)20.System.out.print(rs.getString(i+1)+);/取数据并打印21.22.System.
23、out.println();23.24.catch(Exception e)25.System.out.println(连接失败);26.e.printStackTrace();27.28.29.ResultSetMetaData接口接口 ResultSetMetaData接口可得到诸如查询结果集中有多少列、列名称分别是什么、列标签分别是什么、列的数据类型分别是什么等信息。结果集的元数据并不直接包含在结果集对象中,所以我们要采用如下的方法来获取结果集的元数据:ResultSet rst=stm.executeQuery(sql);/”sql”为select查询语句 ResultSetMetaD
24、ata rsmd=rst.getMetaData();ResultSetMetaData的常用方法的常用方法 1.getColumnCount()返回此ResultSet对象中的列数。2.getColumnName(int column)获取指定列的名称。3.getColumnType(int column)检索指定列的SQL用数字表示的类型。4.getColumnTypeName(int column)检索指定列的数据库特定的类型名称。示例示例1.import java.sql.*;2.public class Dao3.4.public static void main(String ar
25、gs)5.6.new Dao();7.8.public Dao()9.10.try 11.12.Class.forName(com.microsoft.jdbc.sqlserver.SQLServerDriver);13.Connection conn=DriverManager.getConnection(14.jdbc:microsoft:sqlserver:/localhost:1433;DatabaseName=phoneroot,sa,);15.Statement st=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,16.R
26、esultSet.CONCUR_UPDATABLE);17.ResultSet rs=st.executeQuery(select*from roots);18.ResultSetMetaData rsmd=rs.getMetaData();19.System.out.println(数据表列数为:+rsmd.getColumnCount();20.System.out.println(数据表第1列名为:+rsmd.getColumnName(1);21.System.out.println(数据表第1列的类型(数值表示):+rsmd.getColumnType(1);22.System.ou
27、t.println(数据表第1列类型名为:+rsmd.getColumnTypeName(1);23.catch(Exception e)24.System.out.println(连接失败);25.e.printStackTrace();26.27.28.PreparedStatement接口接口 PreparedStatement接口 PreparedStatement可以对SQL语句进行预编译,并且可以存储在PreparedStatement对象中,当多次执行SQL语句时可以提高效率。PreparedStatement类虽然继承了Statement类。PreparedStatement类
28、和Statement类有一些不同,这些不同点主要有:一个PreparedStatement的实例已经含有一个已经编译过的SQL语句。一个包含在PreparedStatement中的SQL语句对象可以有一个或多个参数。作为Statement的子类,PreparedStatement继承了Statement的所有函数,PreparedStatement对象的创建和一般对象的创建类似,如:Connection con;PreparedState str=con.prepareStatement(update roots set sno=?where sname=?”);因为SQL语句需要DBMS编译
29、,所以最好将多次用到的语句预编译,并保存在PreparedStatement对象中。PreparedStatement和和Statement的有点的有点(1)代码的可读性和可维护性(2)PreparedStatement会尽最大可能提高性能(3)最重要的一点是极大地提高了安全性 PreparedStatement的常用方法的常用方法 execute()在此PreparedStatement对象中执行SQL语句,该语句可以是任何种类的SQL语句。executeQuery()在此PreparedStatement对象中执行SQL查询,并返回该查询生成的ResultSet对象。setString(i
30、nt parameterIndex,String x)将指定参数设置为给定String值,setXXX方法很多这里只举一个例。示例示例1.import java.sql.*;2.public class Dao3.4.public static void main(String args)5.6.new Dao();7.8.public Dao()9.10.try11.12.Class.forName(com.microsoft.jdbc.sqlserver.SQLServerDriver);13.Connection conn=DriverManager.getConnection(14.j
31、dbc:microsoft:sqlserver:/localhost:1433;DatabaseName=phoneroot,sa,);15.PreparedStatement ps=conn.prepareStatement(16.update roots set name=?where pid=?);17./?表示要用setXXX方法复值的变量18.ps.setString(1,孙七);/表示第一个参数为张三19.ps.setInt(2,32);/表示第二个参数为3220.ps.execute();/执行操作21.catch(Exception e)22.System.out.printl
32、n(连接失败);23.e.printStackTrace();24.25.26.CallableStatement接口接口 CallableStatement类继承了PreparedStatement类,他主要用于执行SQL存储过程。JDBC API提供了一个SQL存储过程的转义语法,该语法允许对所有RDBMS使用标准方式调用存储过程。此转义语法有一个包含结果参数的形式和一个不包含结果参数的形式。如果使用了包含结果参数的形式,则必须将结果参数注册为OUT型参数。结果参数以外的其他参数可用于输入、输出或同时用于二者。参数是按数字形式引用,第一个参数的序号是1。CallableStatement是
33、用Connection方法创建的,代码如下:Connection con;CallableStatement cst=con.prepareCall(“call getTestData(?,?)”);CallableStatement的常用方法的常用方法 setString(String parameterName,String x)将指定参数设置为给定的JAVA String值。registerOutParameter(int parameterIndex,int sqlType)按顺序位置parameterIndex将OUT参数注册为JDBC类型sqlType。getString(int
34、parameterIndex)以JAVA编程语言中String的形式检索指定的JDBC CHAR、VARCHAR或LONGVARCHAR参数的值(获得结果)。示例示例-无返回值无返回值1.import java.sql.*;2.public class Dao3.4.public static void main(String args)5.6.new Dao();7.8.public Dao()9.10.try11.12.Class.forName(com.microsoft.jdbc.sqlserver.SQLServerDriver);13.Connection conn=DriverM
35、anager.getConnection(14.jdbc:microsoft:sqlserver:/localhost:1433;DatabaseName=phoneroot,sa,);15.PreparedStatement ps=conn.prepareStatement(16.select*from roots where name=?and number=?);17.ps.setString(1,孙七);18.ps.setString(2,1234567);19.ResultSet rs=ps.executeQuery();20.while(rs.next()21.for(int i=
36、0;i3;i+)22.System.out.print(rs.getString(i+1)+);23.24.System.out.println();25.26.catch(Exception e)27.System.out.println(连接失败);28.e.printStackTrace();29.30.31.示例示例-存储过程代码存储过程代码create procedure GetPhoneNumbername varchar(20),phone varchar(20)outputasselect phone=number from rootswhere name=nameJava 代
37、码代码1.import java.sql.*;2.public class Dao3.4.public static void main(String args)5.6.new Dao();7.8.public Dao()9.10.try11.12.Class.forName(com.microsoft.jdbc.sqlserver.SQLServerDriver);13.Connection conn=DriverManager.getConnection(14.jdbc:microsoft:sqlserver:/localhost:1433;DatabaseName=phoneroot,s
38、a,);15.CallableStatement cs=conn.prepareCall(call GetPhoneNumber(?,?);16./调存储过程生成CallableStatement对象17.cs.setString(1,李四);/设置第一个参数18.cs.registerOutParameter(2,java.sql.Types.VARCHAR);19./设置第二个参数为输出参数和类型20.cs.execute();/执行21.System.out.println(cs.getString(2);/取值22.catch(Exception e)23.System.out.pri
39、ntln(连接失败);24.e.printStackTrace();25.26.27.本章总结本章总结JDBC技术概述:JDBC的概念JDBC的诞生JDBC的任务JDBC驱动程序分类JDBC的应用:DriverManager类Connection接口Statement接口ResultSet接口ResultSetMetaData接口PreparedStatement接口CallableStatement接口 动手实践:通讯录动手实践:通讯录基本数据库编程基本数据库编程通讯录软件的实现通讯录软件的实现 目标通讯录软件的功能比较简单,主要用于记录联系人的姓名和电话。运行程序后,可以得到所有已经存入数
40、据库的联系人的姓名和电话。如果需要添加新的姓名和电话,则在“姓名”和“电话”后面的文本框中输入相应的信息,当点击“添加”按钮后,会把文本框中的姓名和电话号码添加到数据库中,并且在姓名和电话列表中显示该联系人的信息。我们在姓名和电话号码中填写正确的记录后,如下图所示:之后点击添加按钮后,效果如下图所示:之后点击添加按钮后,效果如下图所示:如果输入的姓名或者是电话号码为空点击添加按钮则会提示出错,弹出以下对话框。基本思路基本思路(1)窗体分为两部分:上面用表格,表格分两列,分别是姓名、电话号码,下面是两个文本框 分别用来输入姓名和电话号码,还有一个“增加”按钮。(2)建数据库表,有二个字段,分别用
41、来存放姓名和电话号码。(3)表格对应着数据库中的表,打开通讯录时就会读数据库表中的内容显示到表格中,当点击 按钮时把文本框里的内容添加到数据库中同时在窗体表格中显示出来。(1)数据库的建立)数据库的建立数据库名为:phoneroot数据表名为:roots表中的字段名为:pid,name,number(pid为int类型自动编号,name为char类型,为简化起见我们把number也暂时设定为char类型)(2)数据库操作类的实现)数据库操作类的实现(2)数据库操作类的实现,首先获得数据库的连接:public void connect(String serverName,String dataB
42、ase,String userName,String passWord)tryClass.forName(com.microsoft.jdbc.sqlserver.SQLServerDriver);Connection cn=DriverManager.getConnection(jdbc:microsoft:sqlserver:/+serverName+:1433;databasename=+dataBase,userName,passWord);catch(Exception e)System.out.println(数据库连接出错.);e.printStackTrace();在构造函数中
43、调connect()方法,connect()方法是连接数据库的方法,代码如下:public DAOoperation(String serverName,String dataBase,String userName,String passWord)this.connect(serverName,dataBase,userName,passWord);1.用来获得vector数据的方法:有两个Vector对象,第一个用来存放数据库中表的一行,另一个用来存放保存数据行Vector对象,也就是第一个Vector对象中保存着表的一行,第二个Vector对象中保存着表的所有行。代码如下:2.publi
44、c Vector getData()3.Vector data=new Vector();4.try5.st=cn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,6.ResultSet.CONCUR_UPDATABLE);7.rs=st.executeQuery(select name,number from roots);8.ResultSetMetaData rsmd=rs.getMetaData();9.int num=rsmd.getColumnCount();10.Vector row;11.while(rs.next()12.row
45、=new Vector();13.for(int i=1;i num+1;i+)14.String s=rs.getString(i);15.row.add(s);16.17.data.add(row);18.19.catch(Exception e)20.System.out.println(查询数据出错.);21.e.printStackTrace();22.23.return data;24.1.用来向数据库插入数据的方法代码如下:2.public boolean addData(String name,String number)3.boolean flag=false;4.try5.
46、st.executeUpdate(insert into roots values(+name+,+number+);6.flag=true;7.catch(Exception e)8.System.out.println(插入数据出错.);9.e.printStackTrace();10.11.return flag;12.(3)窗体类的实现)窗体类的实现下面方法为构造函数,是用来得到数据类的对象并以Vector类型返回显示在table中,表DefaultTableModel是用来存放数据的,table本身不能得到数据,他要通过得到DefaultTableModel中的信息来得到数据,JSc
47、rollPane类生成滚动条,数据过多窗体显示不完整时会出现下拉条。注:在方法中没有定义类型的变量都是全局变量。public DataTableFrame(DAOoperation dao)super(通讯录);title.add(姓名);title.add(电话号码);JLabel labelName=new JLabel(姓名);fieldName=new JTextField(10);JLabel labelNumber=new JLabel(电话号码);fieldNumber=new JTextField(10);tableModel=new DefaultTableModel();t
48、ableModel.setDataVector(dao.getData(),title);table=new JTable(tableModel);JScrollPane pane=new JScrollPane(table);this.add(pane);p1.add(labelName);p1.add(fieldName);p1.add(labelNumber);p1.add(fieldNumber);p1.add(button);this.add(South,p1);this.dao=dao;button.addActionListener(this);this.setSize(500,
49、200);1.点击按钮时触发此方法具体代码如下:2.public void actionPerformed(ActionEvent e)3.String name=fieldName.getText();4.String number=fieldNumber.getText();5.if(name.equals()|name=null|number.equals()|number=null)6.JOptionPane.showMessageDialog(this,姓名或者是电话号码不能为空.);7.8.else if(dao.addData(name,number)9./如果往数据库中添加成功
50、,就将该记录添加到JTable中显示10.Vector nowRow=new Vector();11.nowRow.add(fieldName.getText();12.nowRow.add(fieldNumber.getText();13.tableModel.addRow(nowRow);14./因为table不会自动刷新所以要把插入数据库的数据在添加到talbe模型里15.16.fieldName.setText();/清空文本框内容17.fieldNumber.setText();18.(4)主类代码的实现)主类代码的实现public class Mainpublic static v