1、能够使用java进行数据库连接和SQL查询操作 2019/1/17 知识点 1、能够使用java进行数据库连接和SQL查询操作
主要内容 使用URL类访问网络资源 基于Socket的客户和服务器编程 基于Datagram客户和服务器编程
Socket通信 预备知识 Socket TCP UDP 端口
UDP UDP仅在想发送时才发送,可将对方作为目标发送数据包 主机A 主机B
UDP 主机A 主机B 即使因网络混杂,产生数据包丢失现象,也不进行特别处理。
可与对方的主机进行通信,确认是否接收到对方的连接 TCP三次握手 可与对方的主机进行通信,确认是否接收到对方的连接 SYN(请求建立连接) 主机B 主机A SYN+ACK(确认SYN响应和连接请求) Ack(确认SYN响应) A:你瞅啥? B:瞅你咋地? C:来咱俩唠唠。 然后就唠上了... A:你能听到我说吗? B:能,我说你能听到吧? C:嗯,开始聊天吧。 A:How are you? B:Fine, and you? C:Fine.
TCP通信 通过顺序号与确认响应号来确认数据是否到达.确认响应后,才通知下一个应当发送的顺序号。 顺序号=3001 主机B 主机A 确认响应序号=4001 顺序号=4001 确认响应序号=5001
Socket应用 客户端与服务器端的实现 服务器端 客户端
Socket通信的一般过程 使用Socket进行客户/服务器通信程序设计的一般过程是这样的: Server端listen(监听)某个端口是否有连接请求, Client端向Server端发出connect(连接)请求, Server端向Client端发回Accept(接受)消息。 一个连接就建立好了,之后客户端、服务器端都可以用send()、write()等方法与对方通信。
Socket通信的一般过程 对于一个功能齐全的Socket的工作过程包含以下四个基本步骤: 创建Socket; 打开连接到Socket的输入输出流; 按照一定的协议对Socket进行读/写操作; 关闭Socket。
8.5 Socket . 8.5 Socket 定义数据成员 定义数据成员 1111 创建Socket实例 创建服务器(端口号) waiting for user 127.0.0.1 1111 服务器等待 网络连接 建立socket流 读socket流 (接收并显示) 建立socket流 connetcting client... login: 向用户发出一个字符串 送用户名给 服务器 java 读客户 端信息 User :java 读socket流 Login successful 提示用户登录成功 关闭流
java.net.Socket类 Socket编程 表示TCP连接的客户方(Client),和谁连接 Socket对象包括两个流 操作步骤 指定对方的IP地址和端口号 public Socket(String host, int port) throws UnknownHostException, IOException Socket对象包括两个流 Socket代表了TCP所定义的双向通信连接的一个端点 输入流(读取通过网络进来的数据) public InputStream getInputStream() throws IOException 输出流(将数据写入输出流中,并通过网络发送) public OutputStream getOutputStream() throws IOException 操作步骤 先建立连接 进行流的读写操作
java.net.ServerSocket类 TCP连接的服务器方(Server),监听端口 等待自客户端发来的连接 public ServerSocket(int port) throws IOException 接收连接请求 public Socket accept() throws IOException Listens for a connection to be made to this socket and accepts it. The method blocks(阻塞) until a connection is made 服务器端通过所接收到的Socket对象和客户端通信 Socket代表了TCP所定义的双向通信连接的一个端点 操作步骤 监听端口 接收连接 进行流的读写操作
创建Socket 创建客户端Socket可以通过Socket的构造方法,介绍如下: public Socket(String host,int port) public Socket(InetAddress address,int port) // 用该方法创建一个与指定远程主机及其端口建立连接; public Socket(String host,Int port,boolean stream) // stream指明Socket是流式Socket还是数据报式Socket public socket(InetAddress address,Int port,boolean stream) Serversocket的构造方法为: public Serversocket(int port) //指定端口号来创建Serversocket对象,该端口为端主机的端口; public Serversocket(int port,int count) //用指定的端口号创建Serversocket对象,如果该端的端口正在使用,只等待count毫秒。
打开输入/输出流 public Inputstream getInputstream( ) //得到 Socket建立的输入流 pubic Outputstream getoutputstream( ) //得到 Socket建立的输出流 Socket对象的其他方法: public void close() public InetAddress getlnetAddress() //得到远程主机 IP地址的 InetAddress对象 public int getLocalPort() //得到与远程机连接的本地机的端口号
Serversocket对象的其他方法 public Socket accept() //获取与客户端连接的 Socket对象 //accept()为一个阻塞性方法,即该方法被调用后,将等待客户的请求,直到有一个客户启动并请求连接到相同的端口,然后accept()返回一个对应于客户的Socket。 public void close() public InetAddrss getInetAddress() // 得到与客户端相连的 InetAddress对象 public int getLocalPort() // 得到服务器在监听的端口号
对客户端对Socket进行读写-实例 客户端 服务器端 Socket应用 Localhost Socket OutputStream InputStream me.whut.edu.cn ServerSocket InputStream OutputStream 客户端 服务器端
对客户端对Socket进行读写-实例 Socket应用 me.whut.edu.cn ServerSocket Localhost OutputStream InputStream Socket应用 对客户端对Socket进行读写-实例 import java.net.*; import java.io.*; public class SimpleClient { public static void main(String args[]) { Socket s = new Socket(“me.whut.edu.cn”, 5432); InputStream in = s.getInputStream(); DataInputStream dis = new DataInputStream(in); String st = dis.readUTF(); System.out.println(st); in.close(); s.close(); } 建立连接 打开输入流 读取输入流 关闭输入流 关闭连接
对ServerSocket的实现-实例 客户端 服务器端 Socket应用 me.whut.edu.cn ServerSocket Localhost Socket OutputStream InputStream 客户端 服务器端
Socket应用 me.whut.edu.cn ServerSocket Localhost Socket OutputStream InputStream Socket应用 ServerSocket s = null; String hello = “Hello World!”; try { s = new ServerSocket(5432); } catch(IOException e) { System.out.println(e); System.exit(1); } while(true) { Socket cs = s.accept(); OutputStream out = cs.getOutputStream(); DataOutputStream dos = new DataOutputStream(out); dos.writeUTF(hello); out.close(); cs.close(); } catch(IOException e) { System.out.println(e); } 监听端口 接收连接 打开输出流 写入输出流 关闭输出流 关闭连接
多线程的服务器实现 Socket应用 为每个客户的连接(Socket)分配一个线程,让其独立处理 两种实现方式 作为java.lang.Thread类的子类 实现java.lang.Runnable接口 Client 1 Socket Port 7 me.whut.edu.cn ServerSocket 1 3 2 1 Thread 1 2 Client n Socket 3 Thread n
多线程的服务器实现-实例 Socket应用 ServerSocket s = new ServerSocket(5432); boolean listening = true; while (listening) new ServerThread(s.accept()).start(); s.close(); class ServerThread extends Thread { … … public void run() { }
TCP/IP传输层由两个并列的协议:TCP,UDP. 一般套接字(TCP)提供一个可靠的传输模型作为两个网络端点的字节流,有纠错能力. 3 Datagram TCP/IP传输层由两个并列的协议:TCP,UDP. 一般套接字(TCP)提供一个可靠的传输模型作为两个网络端点的字节流,有纠错能力. UDP没有保持的连接和数据流,数据报是一个网络上发送的独立信息,它的到达,到达时间,以及内容不能得到保证. socket Socket要求数据按照发送的次序接收,包丢失要重发,浪费网络资源,没有保持的连接和数据流,UDP的价值在于效率,如果通信子网可靠UDP大有用武之处.TCP和UDP都由端口的概念.TCP的可靠来源于确认和超时重传.要求先建立连接,传输后关闭,次序不变. UDP不需要实现连接,数据报是独立的,没有次序要求路径不同. server client datagram server client
DatagramSocket socket; DatagramPacket packet; 发出报文的标准步骤如下: 1. 定义数据成员 DatagramSocket socket; DatagramPacket packet; InetAddress address;(用来存放接收方的地址) int port; ;(用来存放接收方的端口号) 2. 创建数据报文Socket对象 try {socket=new DatagramSocket(1111);} catch(java.net.SocketException e) {} socket 绑定到一个本地的可用端口,等待接收客户的请求.
3.分配并填写数据缓冲区(一个字节类型的数组) byte[] Buf=new byte[256]; 存放从客户端接收的请求信息. Datagram 3.分配并填写数据缓冲区(一个字节类型的数组) byte[] Buf=new byte[256]; 存放从客户端接收的请求信息. 4.创建一个DatagramPacket packet=new DatagramPacket(buf, 256); 用来从socket接收数据,它只有两个参数 5. 服务器阻塞 socket.receive(packet); 在客户的请求报道来之前一直等待
InetAddress address=packet.getAddress(); int port=packet.getPort(); Datagram 6. 从到来的包中得到地址和端口号 InetAddress address=packet.getAddress(); int port=packet.getPort(); 7. 将数据送入缓冲区 或来自文件,或键盘输入 8. 建立报文包,用来从socket上发送信息 packet=new DatagramPacket (buf,buf.length, address,port); 9. 发送数据包 10.关闭socket socket.send(packet); socket.close();
int port; InetAddress address; DatagramSocket socket; 客户端接收包的步骤如下: 1. 定义数据成员 int port; InetAddress address; DatagramSocket socket; DatagramPacket packet; byte[] sendBuf=new byte[256]; 2. 建立socket socket=new DatagramSocket();
address=InetAddress.getByName(args[0]); port=parseInt(args[1]); Datagram 3. 向服务器发出请求报文 address=InetAddress.getByName(args[0]); port=parseInt(args[1]); packet=new DatagramPacket(sendBuf,256,address,port); socket.send(packet); 这个包本身带有客户端的信息 4. 客户机等待应答 packet=new DatagramPacket(sendBuf,256); socket.receive(packet);(如果没有到就一直等待,因此实用程序要设置时间限度)
System.out.println(received); Datagram 5. 处理接收到的数据 String received=new String(packet.getData(),0); System.out.println(received);
Datagram 建立数据报socket(); 建立数据报socket 建立一个报文包packet 建立一个请求包 发出请求 等待请求报文 创建接收包 获得对方地址 等待接收 构成信息包 发送出去
2019/1/17 Java语言程序设计-数据库编程编程 教师:段鹏飞
单 词 说 明 本章相关词汇 driver 驱动,驱动程序 connection 连接 manager 管理器 statement 语句 单 词 说 明 driver 驱动,驱动程序 connection 连接 manager 管理器 statement 语句 prepared 预备的,预编译的 result 结果 create 创建,创造 execute 执行 query 查询
通过JDBC访问数据库执行SQL 语句的方法。 主要内容 JDBC的特点,结构,应用模型; JDBC驱动程序的类型; 通过JDBC访问数据库执行SQL 语句的方法。
问题1:应用程序中的SQL语句如何传到数据库中执行 数据库编程 发送 SQL 语句 客户机/服务器 应用程序 数据库 检索查询结果 问题1:应用程序中的SQL语句如何传到数据库中执行 问题2:数据库的执行结果如何返回到应用程序中
当今企业级应用程序大部分采用了客户机/服务器(C/S)模式; 数据库访问技术简介 当今企业级应用程序大部分采用了客户机/服务器(C/S)模式; 客户端机器需要与服务器进行通讯,要操作数据库中的数据,执行SQL(Structured Query Language结构化查询语言)语句以及检索查询结果; 在Java中实现这些活动的技术称作JDBC。
DBMS(DataBase Management System)是指数据库管理系统; 目前DBMS的生产商众多,产品也不尽相同,如: Oracle公司的Oracle系列; Microsoft公司的Access系列和SQL Server系列; Microsoft公司早期的FoxPro; IBM公司的DB2; Sybase公司的Sybase; 还有自由开源的MySQL等等。 这就意味着编程语言要针对不同的DBMS开发不同版本的应用程序,这将是一项非常枯燥的工作。
解决方案:应用程序和数据库之间必须建立一条通道,提供SQL语句的发送和执行结果的返回 数据库访问技术简介 解决方案:应用程序和数据库之间必须建立一条通道,提供SQL语句的发送和执行结果的返回 建立通道的方式 ODBC:开放式数据库连接 JDBC:JAVA 数据库连接应用程序接口
JDBC直连应用图解 Oracle厂商提供 Java 应用程序 JDBC 驱动 JDBC 驱动 代替了ODBC SQL厂商提供 Oracle API Sql Server JDBC 驱动 代替了ODBC SQL厂商提供
JDBC驱动 JDBC驱动是数据库厂商提供的,在数据库编程中,用到哪种数据库就需要在应用程序中添加相应的驱动程序 以MySql数据库为例,MySql提供的JDBC驱动为: 使用前需要其导入应用程序中(演示)
JDBC API可做三件事:与数据库建立连接、执行SQL 语句、处理结果 2 Connection 数据库服务器 客户端 3 Statement ResultSet 4 1 DriverManager DriverManager :依据数据库的不同,管理JDBC驱动 Connection :负责连接数据库并担任传送数据的任务 Statement :由 Connection 产生、负责执行SQL语句 ResultSet:负责保存Statement执行后所产生的查询结果
使用JDBC连接数据库可以通过不同的驱动方式来实现,有4种驱动类型: JDBC-ODBC桥驱动 纯Java驱动 本地API部分Java驱动 JDBC网络纯Java驱动 不论采用哪种驱动方式,在程序中对数据库的操作方式基本相同,只是加载不同的驱动程序即可。
java.sql包也是Java内置的包,其中包含了一系列用于与数据库进行通信的类和接口; 如果要使用到这些类和接口的话,则必须显式地声明如下语句: import java.sql.*;
java.sql包中的一些接口 接口名称 说 明 Connection Driver Statement PreparedStatement 说 明 Connection 连接对象,用于与数据库取得连接 Driver 用于创建连接(Connection)对象 Statement 语句对象,用于执行SQL语句,并将数据检索到结果集(ResultSet)对象中 PreparedStatement 预编译语句对象,用于执行预编译的SQL语句,执行效率比Statement高 CallableStatement 存储过程语句对象,用于调用执行存储过程 ResultSet 结果集对象,包含执行SQL语句后返回的数据的集合
类 名 称 说 明 java.sql包中的一些类 SQLException DriverManager Date TimeStamp 类 名 称 说 明 SQLException 数据库异常类,是其它JDBC异常类的根类,继承于java.lang.Exception,绝大部分对数据库进行操作的方法都有可能抛出该异常 DriverManager 驱动程序管理类,用于加载和卸载各种驱动程序,并建立与数据库的连接 Date 该类中包含有将SQL日期格式转换成Java日期格式的方法 TimeStamp 表示一个时间戳,能精确到纳秒
JDBC程序访问数据库步骤 导入 java.sql包 加载并注册驱动程序 创建Connection 对象 创建 Statement 对象 开 始 导入 java.sql包 加载并注册驱动程序 创建Connection 对象 创建 Statement 对象 执行SQL语句 关闭ResultSet 对象 关闭Statement对象 关闭Connection对象 使用ResultSet对象 建立数据源(ODBC) 附加相应产商提供的驱动 结 束 JDBC-ODBC桥方式 纯Java驱动方式
这里以JDBC驱动方式为例,逐步详细地讲解在Java程序中如何操作数据库。 步骤详解1:建立数据源 这里以JDBC驱动方式为例,逐步详细地讲解在Java程序中如何操作数据库。 下载驱动程序包,以mysql为例: 下载
使用纯Java驱动连接到MySQL 5.0数据库,加载驱动程序应改成如下语句: Class.forName("com.mysql.jdbc.Driver"); 连接字符串应如下格式: "jdbc:mysql://服务器名或IP:3306/数据库名" 如: Connection con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "root", "root");
使用Class类的forName方法,将驱动程序类加载到JVM(Java虚拟机)中; 步骤详解2:加载驱动程序 使用Class类的forName方法,将驱动程序类加载到JVM(Java虚拟机)中; 如: Class.forName("com.mysql.jdbc.Driver"); 方 法 原 型 说 明 static Class forName(String className) throws ClassNotFoundException 将由className指定完整名称的类加载到JVM中,如果加载失败,将抛出异常,必须捕捉
成功加载驱动后,必须使用DriverManager类的静态方法getConnection来获得连接对象; 步骤详解3:获得连接对象 成功加载驱动后,必须使用DriverManager类的静态方法getConnection来获得连接对象; 对于使用JDBC桥的连接方式,连接字符串的一般形式是:“jdbc:类型:数据源名称”,如: Connection con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "root", "root"); 方 法 原 型 说 明 static Connection getConnection (String url, String user, String password) throws SQLException 参数url是连接字符串,参数user是数据库用户名,参数password是登录口令,成功连接到数据库返回Connection对象,连接失败则抛出SQLException异常,必须捕捉
Statement sta = con.createStatement(); 步骤详解释4:创建语句对象 一旦成功连接到数据库,获得Connection对象后,必须通过Connection对象的createStatement方法来创建语句对象,才可以执行SQL语句; 如: Statement sta = con.createStatement(); 方 法 原 型 说 明 Statement createStatement() throws SQLException 成功创建返回Statement对象,否则抛出SQLException异常,必须捕捉
使用语句对象来执行SQL语句,有两种情况: 一种是执行DELETE、UPDATE和INSERT之类的数据库操作语句(DML),这样的语句没有数据结果返回,使用Statement对象的executeUpdate方法执行; 如: sta.executeUpdate("INSERT INTO Friends VALUES('田七', '重庆', 456712, '2003-2-25', 7500)"); 方 法 原 型 说 明 int executeUpdate(String sql) throws SQLException 参数sql是要执行的SQL语句,执行成功返回受影响的行数,执行失败则抛出SQLException异常,必须捕捉
步骤详解5:执行SQL语句(续) 另一种是执行SELECT这样的数据查询语句(DQL),这样的语句将从数据库中获得所需的数据,使用Statement对象的executeQuery 方法执行; 如: ResultSet rs = sta.executeQuery("SELECT * FROM Friend"); 方 法 原 型 说 明 ResultSet executeQuery(String sql) throws SQLException 参数sql是要执行的SQL语句,查询成功返回包含有结果数据的ResultSet对象,否则抛出SQLException异常,必须捕捉
当对数据库的操作结束后,应当将所有已经被打开的资源关闭,否则将会造成资源泄漏; 步骤详解6:关闭资源 当对数据库的操作结束后,应当将所有已经被打开的资源关闭,否则将会造成资源泄漏; Connection对象、Statement对象和ResultSet对象都有执行关闭的close方法; 函数原型都是:void close() throws SQLException 如: rs.close(); //关闭ResultSet对象 sta.close(); //关闭Statement对象 con.close(); //关闭Connection对象 有可能抛出SQLException异常,必须捕捉; 请注意关闭的顺序,最后打开的资源最先关闭,最先打开的资源最后关闭。
数据库操作示例 import java.sql.*; //导入java.sql包 public class JDBCDemo { public static void main(String[] args) { String strCon = "jdbc:mysql://127.0.0.1:3306/test"; //连接字符串 String strUser = "root"; //数据库用户名 String strPwd = "root"; //口令 System.out.println("正在连接数据库..."); try { //监控异常 Class.forName("com.mysql.jdbc.Driver"); //加载驱动程序 Connection con; //获得连接对象 con = DriverManager.getConnection(strCon, strUser, strPwd); System.out.println("成功连接到数据库。"); Statement sta = con.createStatement(); //创建语句对象 //执行SQL语句 String strSql = "DELETE FROM Friends WHERE [Name] = '郑六'"; int count = sta.executeUpdate(strSql); System.out.println("成功删除" + count + "行数据。"); sta.close(); con.close(); //关闭所有已经打开的资源 } catch (ClassNotFoundException cnfe) { cnfe.printStackTrace(); } catch (SQLException sqle) { sqle.printStackTrace(); } } }
操作结果集 使用Statement对象的executeQuery方法成功执行SELECT语句后,将返回一个包含有结果数据的ResultSet对象,要从该对象中获取数据,将使用到如下方法: 方 法 原 型 说 明 boolean next() throws SQLException 将结果集游标往下移动一行,如果已经到达结果集最后,将会返回false,有可能抛异常,必须捕捉 X getX(String columnName) 获得某个字段的值,X是指具体的数据类型,视数据库表中字段的具体情况而定,该方法有一组,并且每个都有两种重载方法,一种是以字段名称为参数,另一种是以字段索引为参数(字段索引从1开始),有可能抛异常,必须捕捉 X getX(int columnIndex)
操作结果集示例 try { String strCon = "jdbc:odbc:MyODBC"; System.out.println("正在连接数据库..."); Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); Connection con; con = DriverManager.getConnection(strCon, "sa", ""); System.out.println("成功连接到数据库。"); Statement sta = con.createStatement(); ResultSet rs = sta.executeQuery("SELECT * FROM Friends"); System.out.println("查询到数据如下:"); while (rs.next()) { //循环将结果集游标往下移动,到达末尾返回false //根据字段名称获得各个字段的值 System.out.print(rs.getString("Name") + "\t"); //获得字符串 System.out.print(rs.getString("Address") + "\t"); //获得字符串 System.out.print(rs.getInt("Telephone") + "\t"); //获得整数 System.out.print(rs.getDate("HireDate") + "\t"); //获得日期型数据 System.out.println(rs.getFloat("Salary")); //获得浮点型数据 } rs.close(); sta.close(); con.close(); } catch (ClassNotFoundException cnfe) { cnfe.printStackTrace(); } catch (SQLException sqle) { sqle.printStackTrace(); }
Sql语句 select * from [table] where id=3; insert into [table] (id, uname, psw) values (1, 'abc', '123'); update [table] set uname='abc'; delete from [table] where id=3;
总结 JDBC是使用Java程序操作数据库的技术; 使用 Class类的forName 方法可以将驱动程序加载到 Java 解释器中; 使用DriverManager类的getConnection方法获得Connection对象,从而建立与数据库的连接; 使用Connection对象的createStatement方法创建语句对象,以便执行SQL语句; 使用Statement对象的executeQuery或executeUpdate方法执行SQL语句,并使用ResultSet对象来操作结果数据; PreparedStatement接口允许创建预编译的SQL语句,并使得在后续阶段可以指定语句的参数。
2019/1/17 谢谢