1、网络与数据库编程,2,10.1 网络基础知识,在讲述如何进行网络程序开发之前,先讲述一些有关网络的基础知识。为了使两台计算机之间能够通信,必须为这两台电脑建立一个网络,将这两台计算机进行连接,把其中一台用作服务器,另一台作客户机。那什么是服务器?什么又是客户机?服务器就是能够提供信息的计算机或程序。客户机是指请求信息的计算机或程序。有的时候很难区分服务器和客户机,因为很多信息都是互相请求、互相提供信息的。(具体内容请参照本书),3,10.2 TCP与UDP,TCP(Transmission Control Protocol)就是传输控制协议,其和IP协议一起使用。一般会将两者合在一起,称TCP
2、/IP。TCP协议负责数据或文件的分组与重组,而IP协议负责发送和接收数据包。数据或文件在网络上传输的时候,会被分成许多块,称之为包。 UDP(User Datagram Protocol)就是数据包协议,它也跟IP协议一起使用。与TCP协议相比较有很多类似的地方。但是,它不对连接状态与数据丢失作检查,只是保证数据发出去了,例如,平时上网所使用的电子邮件或者聊天时的QQ、MSN等。它们都可以非在线发消息,而这一点与TCP不同。TCP需要对对方是否收到以及数据的完整性作检查。,4,10.3 端口与套接字,什么是端口,什么是套接字?下面将围绕这两个概念进行讲述。网络程序设计中的端口(port)并非
3、真实物理存在的,而是一个假想的连接器。计算机提供了很多种服务,例如Http、Ftp、Dns等等。那么客户机必须明确的直到自己要连接的是服务器上哪一个服务,是Http、Ftp或者是Dns。 为此就引入了一个端口的概念。端口被规定为一个在065535之间的整数。Http服务一般使用80端口,Ftp使用的是21端口,那么客户必须通过80端口才能连接到服务器的Http服务,而通过21端口,才能连接到服务器的Ftp服务器上。(具体内容请参照本书),5,10.4 TCP程序设计基础,Java中的TCP网络程序设计是指利用Socket类,编写通信程序。TCP程序设计的一个过程是:服务器的套接字等待客户机连接
4、请求,并创建新的套接字,使其与客户机的套接字连接,而本身继续等待其他客户机的连接请求。,6,10.4.1 如何设计TCP的程序,下面看看几个与TCP程序设计有关的类。 1与IP相关的InetAddress类应用 2服务器套接字应用 3套接字实现,7,10.4.2 一个简单的例子,下面演示一个Socket类和ServerSocket类的应用实例。(具体内容请参照本书),8,10.6 如何设计网络程序,上面一节中讲述了如何设计TCP程序和UDP程序,本节主要讲述如何将网络编程,应用到实际工作的开发中去。,9,10.6.1 单向通讯综合实例,下面举一个单向通信的实例。这个实例用来实现客户机向服务器发
5、送字符串功能。由于只要求客户机向服务器发送消息,不用服务器向客户机发送消息,所以称为单向通信。客户机套接字和服务器套接字连接成功后,客户机会通过输出流发送数据,而服务器会使用输入流接收数据,下面是具体的实例代码。(具体内容请参照本书),10,10.6.2 双向通讯综合实例,上节介绍了客户机向服务器发送数据的单向通信,本节将介绍服务器和客户机相互发送数据的双向通信,其程序代码在上一小节的代码基础上有所改变,读者可以比较两者的区别。(具体内容请参照本书),11,数据库访问技术简介,客户机/服务器 应用程序,数据库编程,ODBC,JDBC,两个常用的API,数据库,执行 SQL 语句,检索查询结果,
6、12,数据库,ODBC,客户机/服务器 GUI应用程序,ODBC (开放式数据库连接) (Microsoft 提供),插 入,删 除,修 改,应用程序编程接口,查询,13,JDBC,JDBC (Java 数据库连接) (sun公司提供),Java 应用程序编程接口,Java应用程序,数据库,插 入,修 改,删 除,查询,14,JDBC 驱动程序的类型,JDBC 驱动程序 的类型,JDBC-ODBC桥驱动程序及ODBC驱动程序,本地API部分Java驱动程序,JDBC-Net 纯Java驱动程序,本地协议纯Java驱动程序,15,JDBC 体系结构 2-1,Java 程序,JDBC 驱动程序,数
7、据库,SQL 命令,结果,16,JDBC 体系结构 2-2,应用层,Driver,Statement,ResultSet,Connection,各接口,驱动层,17,java.sql 包 3-1,18,java.sql 包 3-2,19,java.sql 包 3-3,SQLException,/* fooBar*/ public void foobar() throws SQLException throw new SQLException(“刚引发了一个 SQLException ”); , tryfooBar(); catch(SQLException ex) System.out.pri
8、ntln(“已捕获一个 SQLException 异常!”);System.out.println(“消息: “ + ex.getMessage();System.out.println(“错误代码: “ + ex.getErrorCode(); ,调用 fooBar,20,JDBC 程序访问数据库的步骤 2-1,开 始,导入 java.sql包,加载并注册驱动程序,创建一个 Connection 对象,创建一个 Statement 对象,执行语句,关闭ResultSet 对象,关闭Statement对象,关闭连接,结 束,使用ResultSet对象,21,Friends 表的结构,JDBC
9、程序访问数据库的步骤 2-2,它演示访问数据库的各个步骤 在执行示例 1 中的程序之前,SQL Server 中应该存在一个名为 friends 的表,演示:示例 1,/* 2005 Aptech Limited* 版权所有 */ import java.sql.SQLException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Statement; import java.sql.ResultSet; /* 这个类演示访问数据库需遵循的各个步骤. * version 1.0, 200
10、5 年 8 月 26 日 * author Ben*/ class Jdbctest /* 构造方法 */protected Jdbctest() ,/*这是 main 方法. */ public static void main(String args) try Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver“); catch (ClassNotFoundException ce) System.out.println(ce);try String url = “jdbc:odbc:test“;Connection con = DriverManage
11、r.getConnection(url);Statement s = con.createStatement();ResultSet rs = s.executeQuery(“select * from friends“);while (rs.next() System.out.print(rs.getString(1) + “t“);System.out.print(rs.getString(2) + “t“);System.out.print(rs.getInt(3) + “t“);System.out.print(rs.getDate(4) + “t“);System.out.print
12、ln(“ “);rs.close();s.close();con.close(); catch (SQLException ce) System.out.println(ce); ,22,JDBC 查询2-1,SQL 查询字符串,executeQuery() 方法,作为参数传递,ResultSet,返回查询数据,SELECT name, email, phone FROM colleagues;,使用 SQL 语句,查询可编写为:,String str = “SELECT emp_id, lname, fname FROM colleagues“; Statement stmt = con.c
13、reateStatement(); ResultSet rset = stmt.executeQuery(str);,使用 JDBC 编写此查询,则代码为:,Statement接口,23,JDBC 查询2-2,它演示 SQL 中 sum( ) 方法的用法,演示:示例 2,/* * Jdbctest2 */ import java.sql.SQLException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Statement; import java.sql.ResultSet; /*
14、这个类演示 SQL 中 sum() 方法的用法* version 1.0, 2005 年 8 月 26 日* author Ben*/ class Jdbctest2 /* 构造方法*/protected Jdbctest2() ,/* 这是 main 方法*/public static void main(String args) try Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver“); catch (ClassNotFoundException ce) System.out.println(ce); try String url = “jdbc:
15、odbc:test“;Connection con = DriverManager.getConnection(url);Statement s = con.createStatement();ResultSet rs = s.executeQuery(“select hiredate, sum(salary) from friends group by hiredate“);while (rs.next() System.out.print(rs.getDate(1) + “t“);System.out.print(rs.getInt(2) + “t“);System.out.println
16、(“ “);rs.close;s.close();con.close(); catch (SQLException ce) System.out.println(ce); ,24,演示:示例 3,它演示 SQL 中 INSERT 语句的用法,/* * Jdbctest3*/ import java.sql.SQLException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Statement; import java.sql.ResultSet; /* 这个类演示 INSERT 语句的
17、用法.* version 1.0, 2005 年 8 月 26 日* author Ben*/ class Jdbctest3 /* 构造方法 */protected Jdbctest3() ,JDBC 插入数据实现,/* 这是 main 方法*/ public static void main(String args) try Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver“); catch (ClassNotFoundException ce) System.out.println(ce);try String url = “jdbc:odbc:te
18、st“;String str = “INSERT INTO “ + friends(name,address,salary)“+ “VALUES(朱八,深圳 ,25690)“;Connection con = DriverManager.getConnection(url);Statement s = con.createStatement();int rowcount = s.executeUpdate(str);String str1 = “select name, sum(salary) “+from friends“+ “ group by name“;,ResultSet rs =
19、s.executeQuery(str1);while (rs.next() System.out.print(rs.getString(1) + “t“);System.out.print(rs.getInt(2) + “t“);System.out.println(“ “);rs.close();s.close();con.close(); catch (SQLException ce) System.out.println(ce); ,25,JDBC 删除和修改实现,它演示 SQL 中各种命令的用法,演示:示例 4,/* * Jdbc2*/ import java.sql.SQLExcep
20、tion; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Statement; /* 这这个类演示 SQL 中命令的用法.* version 1.0, 2005 年 8 月 26 日 * author Ben*/ class Jdbc2 /* 构造方法.*/protected Jdbc2() ,public static void main(String args) Connection con;Statement stmt;String url;String sql;try Class.f
21、orName(“sun.jdbc.odbc.JdbcOdbcDriver“); catch (ClassNotFoundException ce) System.out.println(ce);try url = “jdbc:odbc:test“;con = DriverManager.getConnection(url);sql = “Delete from friends where rtrim(name)like张三 ;“;System.out.println(“ “);stmt = con.createStatement();stmt.executeUpdate(sql);System
22、.out.println(“张三 的记录已删除“);stmt.close();con.close();,con = DriverManager.getConnection(url);sql = “Update friends set address=青岛 where “+ “rtrim(name) like 李四; “;System.out.println(“ “);stmt = con.createStatement();stmt.executeUpdate(sql);stmt.close();con.close();System.out.println(“李四的记录已更新“); catch
23、 (SQLException ce) System.out.println(ce); ,26,PreparedStatement接口 3-1,PreparedStatement接口 (预编译的 SQL 语句),PreparedStatement用于提高运行时效率,执行 PreparedStatement 对象比执行 Statement 对象快,Statement 接口,27,PreparedStatement接口 3-2,它演示了PreparedStatement 的用法,演示:示例 5,/* * CourseAppl*/ import java.sql.SQLException; impor
24、t java.sql.Connection; import java.sql.DriverManager; import java.sql.Statement; import java.sql.ResultSet; import java.sql.PreparedStatement; /* 这个类演示 SQL 中 PreparedStatement 的用法*/ class CourseAppl private Connection con; private String url; private String serverName; private String portNumber; pri
25、vate String databaseName; private String userName; private String password; private String sql;,CourseAppl() url = “jdbc:microsoft:sqlserver:/“;serverName = “localhost“;portNumber = “1433“;databaseName = “test“;userName = “sa“;password = “sa“; private String getConnectionUrl() return url + serverNam
26、e + “:“ + portNumber + “;databaseName =“ + databaseName + “;“; private java.sql.Connection getConnection() try Class.forName(“com.microsoft.jdbc.sqlserver.SQLServerDriver“);con = DriverManager.getConnection(getConnectionUrl(), userName, password);if (con != null) System.out.println(“连接成功!“); catch (
27、Exception e) e.printStackTrace();System.out.println(“getConnection() 内的错误跟踪:“ + e.getMessage(); return con; ,public void display() try con = getConnection();PreparedStatement pstmt = con.prepareStatement(“UPDATE friends SET salary = ? WHERE name like ?“);pstmt.setInt(1, 10000 );pstmt.setString(2, “李
28、四 “);pstmt.executeUpdate();System.out.println(“记录已更新!“);Statement s = con.createStatement();String sql = “SELECT * FROM friends “;ResultSet rs = s.executeQuery(sql);while (rs.next() System.out.println(“ “);System.out.print(rs.getInt(1) + “ “);System.out.println(rs.getInt(5); catch (SQLException ce)
29、System.out.println(ce); public static void main(String args) CourseAppl retObj = new CourseAppl();retObj.display(); ,28,PreparedStatement 接口 3-3,它演示在基于条件的 SQL 查询中如何使用 PreparedStatement,其中条件在 IN 参数中给出,演示:示例 6,import java.sql.SQLException; import java.sql.Connection; import java.sql.DriverManager; imp
30、ort java.sql.ResultSet; import java.sql.PreparedStatement; /* 这个类演示在基于条件的 SQL 查询中使用 PreparedStatement*/ class RetrieveRecords private Connection con; private String url; private String serverName, portNumber, databaseName, userName; private String sql; RetrieveRecords() url = “jdbc:microsoft:sqlserv
31、er:/“;serverName = “localhost“;portNumber = “1433“;databaseName = “test“;userName = “sa“;password = “sa“; ,private String getConnectionUrl() return url + serverName + “:“ + portNumber+ “;databaseName =“ + databaseName + “;“;private java.sql.Connection getConnection() tryClass.forName(“com.microsoft.
32、jdbc.sqlserver.SQLServerDriver“);con = DriverManager.getConnection(getConnectionUrl(), userName, password);if (con != null) System.out.println(“连接成功!“); catch (Exception e) e.printStackTrace();System.out.println(“getConnection() 内的错误跟踪:“+ e.getMessage();return con;,public void display() try con = ge
33、tConnection();sql = “select * from Friends where Salary ?“;PreparedStatement pstmt = con.prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);pstmt.setInt(1, 5000);ResultSet rs = pstmt.executeQuery();while (rs.next() System.out.print(rs.getString(1) + “t“);System.out.pr
34、int(rs.getString(2) + “t“);System.out.print(rs.getInt(3) + “t“);System.out.print(rs.getDate(4) + “t“);System.out.print(rs.getInt(5) + “t“);System.out.println(“ “);rs.close();pstmt.close();con.close(); catch (SQLException ce) System.out.println(ce); /* 这是 main 方法*/public static void main(String args)
35、 RetrieveRecords retRec = new RetrieveRecords();retRec.display(); ,29,使用结果集 3-1,ResultSet 对象完全依赖于 Statement 对象和 Connection 对象 每次执行 SQL 语句时,都会用新的结果重写结果集 当相关的 Statement 关闭时,ResultSet 对象会自动关闭,Next( ),get(),此方法将光标从 当前位置下移一行,从 ResultSet 对象返回数据,30,使用结果集 3-2,它演示对当前行的处理 使用 next() 方法时,记录是按顺序处理的 必须按照数据返回的顺序处理
36、每行中的数据, ResultSet rset = stmt.getResultSet();while(rset.next() String dept_name = rset.getString(1); ,31,使用结果集 3-3,演示对当前列的处理 使用 get() 方法可以直接访问列, Statement stmt = con.createStatement(); Stmt.executeQuery(“Select emp_id, fname from Employee“) ; ResultSet rset = stmt.getResultSet(); while(rset.next() S
37、tring ename = rset.getString (“fname“);System.out.println ( ename) ; , Statement stmt = con.createStatement(); stmt.executeQuery(“Select emp_id, fname from Employee“); ResultSet rset = stmt.getResultSet(); while(rset.next() String employeeid = rset.getString (1); ,以下代码显示值 1 被作为参数传递给 getString() 方法,这
38、实际上指列 emp_id 的索引,32,结果集的类型,可滚动,不可滚动,光标仅向前移动,光标可前后移动,也可移动 至与当前位置相对的某一行,如果对数据库做了更改, 则新值是可见的,结果集,TYPE_SCROLL_INSENSITIVE,TYPE_SCROLL_SENSITIVE,TYPE_FORWARD_ONLY,33,总结,JDBC概念的理解 使用 Class.forName() 方法可以将驱动程序加载到 Java 解释器中 使用 DriverManager 类的 getConnection() 方法和 Connection 对象的 createStatement() 方法可建立连接 最后,使用 executeQuery() 或 executeUpdate() 方法通过 Statement 实例构建并执行 SQL 语句 PreparedStatement 接口允许创建预编译的 SQL 语句,并使得在后续阶段可以指定语句的参数 结果集可以是可滚动的,也可以是不可滚动的,