百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 数据库教程 > 正文

分布式系统的核心:进程间的通信,在Java中实现常用网络I/O模型

oygpt 2024-07-16 22:54 145 浏览 0 评论

实战:在Java中实现常用网络I/O模型

Java从初创之日起,就是为网络而生的。随着互联网应用的发展,Java也被越来越多的企业所采用。本节演示了如何基于Java实现常用网络I/O模型。

Java OIO

早期的Java提供java.net包用于开发网络应用,这类API也被称为Java OIO(Old-blocking I/O,阻塞I/O)。以下演示使用java.net包及java.io来开发Echo协议的客户端及服务器的过程。

Echo协议是指把接收到的消息按照原样返回,其主要用于检测和调试网络。这个协议可以基于TCP/UDP用于服务器检测端口7有无消息。

1.实战:开发Echo协议的服务器

以下是使用原生java.net包来开发Echo协议的服务器的示例。

package com.waylau.java.demo.net;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class BlockingEchoServer {
public static int DEFAULT_PORT = 7;
/**
* @param args
*/
public static void main(String[] args) {
int port;
try {
port = Integer.parseInt(args[0]);
} catch (RuntimeException ex) {
port = DEFAULT_PORT;}
ServerSocket serverSocket = null;
try {
// 服务器监听
serverSocket = new ServerSocket(port);
System.out.println(
"BlockingEchoServer已启动,端口:" + port);
} catch (IOException e) {
System.out.println(
"BlockingEchoServer启动异常,端口:" + port);
System.out.println(e.getMessage());
}
// Java 7 try-with-resource语句
try (
// 接受客户端建立链接,生成Socket实例
Socket clientSocket = serverSocket.accept();
PrintWriter out =
new PrintWriter(clientSocket.getOutputStream(), true);
// 接收客户端的消息
BufferedReader in =
new BufferedReader(
new InputStreamReader(
clientSocket.getInputStream()));) {
String inputLine;
while ((inputLine = in.readLine()) != null) {
// 发送消息给客户端
out.println(inputLine);
System.out.println("BlockingEchoServer -> "
+ clientSocket.getRemoteSocketAddress() + ":" + inputLine);
}
} catch (IOException e) {
System.out.println(
"BlockingEchoServer异常!" + e.getMessage());
}
}
}

上述例子BlockingEchoServer实现了Echo协议。BlockingEchoServer使用了java.net包中的Socket和ServerSocket类库,这两个类库主要用于开发基于TCP的应用。如果想要开发UDP的应用,则需要使用DatagramSocket类。

ServerSocket用于服务器端,而Socket是建立网络连接时使用的。在客户端连接服务器成功时,客户端和服务器端都会产生一个Socket实例,通过操作这个实例,来完成所需的会话。对于一个网络连接来说,Socket是平等的,并没有差别,不因为在服务器端或在客户端而产生不同的级别,不管是Socket还是ServerSocket,它们的工作都是通过Socket类和其子类来完成的。

运行BlockingEchoServer,可以看到控制台输出内容如下。

BlockingEchoServer已启动,端口:7

2.实战:开发Echo协议的客户端

以下是使用原生java.net包来开发Echo协议的客户端的示例。

package com.waylau.java.demo.net;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class BlockingEchoClient {
/**
* @param args
*/
public static void main(String[] args) {
if (args.length != 2) {
System.err.println(
"用法: java BlockingEchoClient <host name> <port number>");
System.exit(1);
}
String hostName = args[0];
int portNumber = Integer.parseInt(args[1]);
try (
Socket echoSocket = new Socket(hostName, portNumber);
PrintWriter out =
new PrintWriter(echoSocket.getOutputStream(), true);
BufferedReader in =
new BufferedReader(
new InputStreamReader(echoSocket.getInputStream()));
BufferedReader stdIn =
new BufferedReader(
new InputStreamReader(System.in))
) {
String userInput;
while ((userInput = stdIn.readLine()) != null) {
out.println(userInput);
System.out.println("echo: " + in.readLine());
}
} catch (UnknownHostException e) {
System.err.println("不明主机,主机名为: " + hostName);
System.exit(1);
} catch (IOException e) {
System.err.println("不能从主机中获取I/O,主机名为:" +
hostName);System.exit(1);
}
}
}

BlockingEchoClient的Socket的使用与BlockingEchoServer的Socket的使用基本类似。如果你本地的JDK版本是11以上,则可以跳过编译阶段直接运行源代码,命令如下。

$ java BlockingEchoClient.java localhost 7

从JDK 11开始,可以直接运行启动Java源代码文件。有关Java的最新特性,可见笔者所著的《Java核心编程》。

当BlockingEchoClient客户端与BlockingEchoServer服务器建立了连接之后,客户端就可以与服务器进行交互了。

当我们在客户端输入“a”字符时,服务器也会将“a”发送回客户端,客户端输入的任何内容,服务器也会原样返回。

BlockingEchoServer控制台输出内容如下。

BlockingEchoServer已启动,端口:7
BlockingEchoServer -> /127.0.0.1:52831:a
BlockingEchoServer -> /127.0.0.1:52831:hello waylau

3.java.net包API的缺点

BlockingEchoClient和BlockingEchoServer代码只是一个简单的示例,如果要创建一个复杂的客户端/服务器协议,仍然需要大量的样板代码,并且要求开发人员必须掌握相当多的底层技术细节才能使它整个流畅地运行起来。Socket和ServerSocket类库的API只支持由本地系统套接字库提供的所谓的阻塞函数,因此客户端与服务器的通信是阻塞的,并且要求每个新加入的连接,必须在服务器中创建一个新的Socket实例。这极大消耗了服务器的性能,并且也使得连接数受到了限制。

BlockingEchoClient客户端与BlockingEchoServer服务器所实现的方式是阻塞的。

那么Java是否可以实现非阻塞的I/O程序呢?答案是肯定的。

Java NIO

从Java 1.4开始,Java提供了NIO(New I/O),用来替代标准JavaI/O API(3.5.1小节所描述的早期的Java网络编程API)。Java NIO也被称为“Non-blocking I/O”,提供了非阻塞I/O的方式,用法与标准I/O有非常大的差异。

Java NIO提供了以下3个核心概念。

·通道(Channel)和缓冲区(Buffer):标准的I/O是基于字节流和字符流进行操作的,而NIO是基于通道和缓冲区进行操作的,数据总是从通道读取到缓冲区,或者从缓冲区写入通道。

·非阻塞I/O(Non-blocking I/O):Java NIO可以让你非阻塞地使用I/O,例如,当线程从通道读取数据到缓冲区时,线程还可以进行其他事情。当数据被写入缓冲区时,线程可以继续处理它。从缓冲区写入通道也类似。

·选择器(Selector):Java NIO引入了选择器的概念,选择器用于监听多个通道的事件(比如连接打开、数据到达)。因此,单个的线程可以监听多个数据通道,这极大提升了单机的并发能力。

Java NIO API位于java.nio包下。下面介绍Java NIO版本实现的支持Echo协议的客户端及服务器。

1.实战:开发NIO版本的Echo服务器

下面是使用原生Java NIO API来开发Echo协议的服务器的示例。package com.waylau.java.demo.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
public class NonBlockingEchoServer {
public static int DEFAULT_PORT = 7;
/**
* @param args
*/
public static void main(String[] args) {
int port;
try {
port = Integer.parseInt(args[0]);
} catch (RuntimeException ex) {
port = DEFAULT_PORT;
}
ServerSocketChannel serverChannel;
Selector selector;
try {
serverChannel = ServerSocketChannel.open();
InetSocketAddress address = new InetSocketAddress(port);
serverChannel.bind(address);
serverChannel.configureBlocking(false);
selector = Selector.open();
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("NonBlockingEchoServer已启动,端口:" + port);
} catch (IOException ex) {
ex.printStackTrace();
return;
}
while (true) {
try {
selector.select();
} catch (IOException e) {
System.out.println("NonBlockingEchoServer异常!" + e.getMessage());
}
Set<SelectionKey> readyKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = readyKeys.iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
iterator.remove();
try {
// 可连接
if (key.isAcceptable()) {
ServerSocketChannel server =
(ServerSocketChannel) key.channel();
SocketChannel client = server.accept();
System.out.println("NonBlockingEchoServer接受客户端的连接:"
+ client);
// 设置为非阻塞
client.configureBlocking(false);// 客户端注册到Selector
SelectionKey clientKey = client.register(selector,
SelectionKey.OP_WRITE | SelectionKey.OP_READ);
// 分配缓存区
ByteBuffer buffer = ByteBuffer.allocate(100);
clientKey.attach(buffer);
}
// 可读
if (key.isReadable()) {
SocketChannel client = (SocketChannel) key.channel();
ByteBuffer output = (ByteBuffer) key.attachment();
client.read(output);
System.out.println(client.getRemoteAddress()
+ " -> NonBlockingEchoServer:" + output.toString());
key.interestOps(SelectionKey.OP_WRITE);
}
// 可写
if (key.isWritable()) {
SocketChannel client = (SocketChannel) key.channel();
ByteBuffer output = (ByteBuffer) key.attachment();
output.flip();
client.write(output);
System.out.println("NonBlockingEchoServer -> "
+ client.getRemoteAddress() + ":" + output.toString());
output.compact();
key.interestOps(SelectionKey.OP_READ);
}
}ca tch (IOException ex) {
key.cancel();
try {
key.channel().close();
} catch (IOException cex) {
}
}
}
}
}
}

上述例子NonBlockingEchoServer实现了Echo协议,ServerSocketChannel与ServerSocket的职责类似。相比较而言,ServerSocket读和写操作都是同步阻塞的,在面对高并发的场景时,需要消耗大量的线程来维持连接。CPU在大量的线程之间频繁切换,性能损耗很大。一旦单机的连接超过1万,甚至达到几万的时候,服务器的性能会急剧下降。

NIO的Selector却很好地解决了这个问题,用主线程(一个线程或者是CPU个数的线程)保持所有的连接,管理和读取客户端连接的数据,将读取的数据交给后面的线程处理,后续线程处理完业务逻辑后,将结果交给主线程发送响应给客户端,这样少量的线程就可以处理大量连接的请求。

上述NonBlockingEchoServer例子,使用Selector注册Channel,然后调用它的select方法。这个select方法会一直阻塞到某个注册的通道有事件就绪。一旦这个方法返回,线程就可以处理这些事件。事件包括例如有新连接进来(OP_ACCEPT)、数据接收(OP_READ)等。

运行,可以看到控制台输出内容如下。

NonBlockingEchoServer已启动,端口:7

2.实战:开发NIO版本的Echo客户端

下面是使用原生NIO API来开发Echo协议的客户端的示例。

package com.waylau.java.demo.nio;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
public class NonBlockingEchoClient {
/**
* @param args
*/
public static void main(String[] args) {
if (args.length != 2) {
System.err.println("用法: java NonBlockingEchoClient <host name> <port
number>");
System.exit(1);
}
String hostName = args[0];
int portNumber = Integer.parseInt(args[1]);
SocketChannel socketChannel = null;
try {
socketChannel = SocketChannel.open();
socketChannel.connect(new InetSocketAddress(hostName, portNumber));
} catch (IOException e) {
System.err.println("NonBlockingEchoClient异常: " + e.getMessage());
System.exit(1);
}ByteBuffer writeBuffer = ByteBuffer.allocate(32);
ByteBuffer readBuffer = ByteBuffer.allocate(32);
try (BufferedReader stdIn =
new BufferedReader(new InputStreamReader(System.in))) {
String userInput;
while ((userInput = stdIn.readLine()) != null) {
writeBuffer.put(userInput.getBytes());
writeBuffer.flip();
writeBuffer.rewind();
// 写消息到管道
socketChannel.write(writeBuffer);
// 管道读消息
socketChannel.read(readBuffer);
// 清理缓冲区
writeBuffer.clear();
readBuffer.clear();
System.out.println("echo: " + userInput);
}
} catch (UnknownHostException e) {
System.err.println("不明主机,主机名为: " + hostName);
System.exit(1);
} catch (IOException e) {
System.err.println("不能从主机中获取I/O,主机名为:"
+ hostName);
System.exit(1);
}
}
}

NonBlockingEchoClient的SocketChannel的使用与NonBlockingEchoServer的SocketChannel的使用基本类似。启动客户端,命令如下。

$ java NonBlockingEchoClient.java localhost 7

当NonBlockingEchoClient客户端与NonBlockingEchoServer服务器建立连接之后,客户端就可以与服务器进行交互了。

当我们在客户端输入“a”字符时,服务器也会将“a”发送回客户端,客户端输入的任务内容,服务器也会原样返回。

NonBlockingEchoServer控制台输出内容如下。

NonBlockingEchoServer已启动,端口:7

NonBlockingEchoServer接受客户端的连接:

java.nio.channels.SocketChannel[connected local=
/127.0.0.1:7 remote=/127.0.0.1:56515]
NonBlockingEchoServer -> /127.0.0.1:56515:java.nio.HeapByteBuffer[pos=0 lim=0 cap=100]
/127.0.0.1:56515 -> NonBlockingEchoServer:java.nio.HeapByteBuffer[pos=1 lim=100 cap=
100]
NonBlockingEchoServer -> /127.0.0.1:56515:java.nio.HeapByteBuffer[pos=1 lim=1 cap=
100]
/127.0.0.1:56515 -> NonBlockingEchoServer:java.nio.HeapByteBuffer[pos=12 lim=100 cap=
100]
NonBlockingEchoServer -> /127.0.0.1:56515:java.nio.HeapByteBuffer[pos=12 lim=12 cap=
100]

Java AIO

从Java 1.7开始,Java提供了AIO(异步I/O)。Java AIO也被称为“NIO.2”,提供了异步I/O的方式,用法与标准I/O有非常大的差异。

Java AIO采用“发布/订阅”模式,即应用程序向操作系统注册I/O监听,然后继续做自己的事情。当操作系统发生I/O事件,并且准备好数据后,再主动通知应用程序,触发相应的函数。

与同步I/O一样,Java的AIO也是由操作系统进行支持的。微软的Windows系统提供了一种异步I/O技术——I/O完成端口(I/O CompletionPort,IOCP),而在Linux平台下并没有这种异步I/O技术,所以使用的是epoll对异步I/O进行模拟。

Java AIO API同Java NIO一样,都是位于java.nio包下。下面介绍Java AIO版本实现的支持Echo协议的客户端及服务器。

1.实战:开发AIO版本的Echo服务器

下面是使用原生Java AIO API来开发Echo协议的服务器的示例。

package com.waylau.java.demo.aio;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.StandardSocketOptions;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
public class AsyncEchoServer {public static int DEFAULT_PORT = 7;
/**
* @param args
*/
public static void main(String[] args) {
int port;
try {
port = Integer.parseInt(args[0]);
} catch (RuntimeException ex) {
port = DEFAULT_PORT;
}
AsynchronousServerSocketChannel serverChannel;
try {
serverChannel = AsynchronousServerSocketChannel.open();
InetSocketAddress address = new InetSocketAddress(port);
serverChannel.bind(address);
// 设置阐述
serverChannel.setOption(StandardSocketOptions.SO_RCVBUF, 4 * 1024);
serverChannel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
System.out.println("AsyncEchoServer已启动,端口:" + port);
} catch (IOException ex) {
ex.printStackTrace();
return;
}
while (true) {
// 可连接
Future<AsynchronousSocketChannel> future = serverChannel.accept();
AsynchronousSocketChannel socketChannel = null;
try {
socketChannel = future.get();
} catch (InterruptedException | ExecutionException e) {
System.out.println("AsyncEchoServer异常!" + e.getMessage());
}
System.out.println("AsyncEchoServer接受客户端的连接:" + socketChannel);
// 分配缓存区
ByteBuffer buffer = ByteBuffer.allocate(100);
try {
while (socketChannel.read(buffer).get() != -1) {
buffer.flip();
socketChannel.write(buffer).get();
System.out.println("AsyncEchoServer -> " +
socketChannel.getRemoteAddress() +
":" + buffer.toString());
if (buffer.hasRemaining()) {
buffer.compact();
} else {
buffer.clear();
}
}
socketChannel.close();
} catch (InterruptedException
| ExecutionException
| IOException e) {
System.out.println("AsyncEchoServer异常!"
+ e.getMessage());
}
}}
}

上述例子AsyncEchoServer实现了Echo协议,AsynchronousServerSocketChannel与Server SocketChannel的职责类似。

相比较而言,AsynchronousServerSocketChannel实现了异步的I/O,而无须再使用Selector,因此整体代码比ServerSocketChannel要简化很多。

运行代码后可以看到控制台输出内容如下。

AsyncEchoServer已启动,端口:7

2.实战:开发AIO版本的Echo客户端

下面是使用原生AIO API来开发Echo协议的客户端的示例。

package com.waylau.java.demo.aio;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
public class AsyncEchoClient {
/**
* @param args
*/
public static void main(String[] args) {
if (args.length != 2) {
System.err.println("用法: java AsyncEchoClient <host name> <port number>");
System.exit(1);
}
String hostName = args[0];
int portNumber = Integer.parseInt(args[1]);
AsynchronousSocketChannel socketChannel = null;
try {
socketChannel = AsynchronousSocketChannel.open();
socketChannel.connect(new InetSocketAddress(hostName, portNumber));
} catch (IOException e) {
System.err.println("AsyncEchoClient异常: "
+ e.getMessage());
System.exit(1);
}
ByteBuffer writeBuffer = ByteBuffer.allocate(32);
ByteBuffer readBuffer = ByteBuffer.allocate(32);try (BufferedReader stdIn = new BufferedReader(new InputStreamReader
(System.in))) {
String userInput;
while ((userInput = stdIn.readLine()) != null) {
writeBuffer.put(userInput.getBytes());
writeBuffer.flip();
writeBuffer.rewind();
// 写消息到管道
socketChannel.write(writeBuffer);
// 管道读消息
socketChannel.read(readBuffer);
// 清理缓冲区
writeBuffer.clear();
readBuffer.clear();
System.out.println("echo: " + userInput);
}
} catch (UnknownHostException e) {
System.err.println("不明主机,主机名为: " + hostName);
System.exit(1);
} catch (IOException e) {
System.err.println("不能从主机中获取I/O,主机名为:"
+ hostName);
System.exit(1);
}
}
}

AsyncEchoClient的AsynchronousSocketChannel的使用与NonBlockingEchoClient的SocketChannel的使用基本类似。启动客户端,命令如下。

$ java AsyncEchoClient.java localhost 7

当AsyncEchoClient客户端与AsyncEchoServer服务器建立连接之后,客户端就可以与服务器进行交互了。

当我们在客户端输入“a”字符时,服务器也会将“a”发送回客户端,客户端输入的任务内容,服务器也会原样返回。

AsyncEchoServer控制台输出内容如下。

AsyncEchoServer已启动,端口:7

AsyncEchoServer接受客户端的连接:

sun.nio.ch.WindowsAsynchronousSocketChannelImpl
[connected local=/127.0.0.1:7 remote=/127.0.0.1:57573]
AsyncEchoServer -> /127.0.0.1:57573:java.nio.HeapByteBuffer[pos=1 lim=1 cap=100]
AsyncEchoServer -> /127.0.0.1:57573:java.nio.HeapByteBuffer[pos=12 lim=12 cap=100]本节示例,可以在java-io-mode项目下找到。

本文给大家讲解的内容是分布式系统的核心:进程间的通信,实战:在Java中实现常用网络I/O模型

  1. 下篇文章给大家讲解的是分布式系统的核心:进程间的通信,事件驱动;
  2. 觉得文章不错的朋友可以转发此文关注小编;
  3. 感谢大家的支持!

相关推荐

PLSQL 命令行模式常见错误(plsql执行命令行)

日常运维过程中,经常使用PLSQL的command模式运行SQL脚本,对于一些常见的错误,你知道原因在哪里吗?1.SQL脚本执行后弹出输入框原因:SQL*PLUS默认环境里会把'&字符'...

了解 PL/SQL 的异常处理(sql数据库异常处理)

6.PL/SQL的异常处理在程序运行时出现的镇误,称为异常。发生异常后语句将停止执行,PL/SQL引擎立即将控制权转到PL/SQL块的异常处理部分。异常处理机制简化了代码中的错误检测。PL/SQ...

PL/SQL 泛型编程详解(泛型调用)

PL/SQL中的通用函数,也称为泛型函数,是一种可以接受任意数据类型参数的函数。这使得开发者能够编写可重用的代码,以处理不同的数据类型,而无需为每种数据类型编写专门的函数。PL/SQL的泛型函数通过使...

PL/pgSQL编写postgresql函数之基本语句

目录基本语句1赋值赋值运算符:=或=2单一行结果返回SELECT...INTO语法赋值更新操作结果返回3多行结果返回方式一:使用表充当容器方式二:使用自定义TYPE充当容器方式三:ret...

PLSQL安装教程(plsql安装教程及配置)

2.安装,双击上图Plsqldev.exe文件;3.单击确定,进行下一步安装;4.软件询问是否遵守协议,单击“IAgree”,进行下一步安装;5.选择软件安装在计算机中的路径,(客户端的安装...

PL/SQL字符函数概览(sqlplus 字符集)

PL/SQL提供了一系列内置的字符函数,这些函数可以对字符串进行各种操作,如转换、比较、搜索和替换等。以下是一些常用的PL/SQL字符函数及其用法示例:CONCAT:连接两个或多个字符串。示例:DEC...

instantclient + PLSQL安装与配置小结

一、软件1、instantclient-basic-windows.x64-11.2.0.4.0.zip到官网下载。2、PLSQLDeveloper13.rar到网上下载,找破解版的,网上有V...

如何使用 PL/SQL 块 ?(pl/sql 使用教程)

2.PL/SQL块PL/SQL是一种块结构的诺言,一个PL/SQL程序包含了一个或者多个逻辑块,逻辑块中可以声明变量,变量在使用之前必须先声明。除了正常的执行程序外,PL/SQL还提供了专门的异...

PL/SQL(Procedural Language(procedural objects)

PL/SQL(ProceduralLanguage/StructuredQueryLanguage)是由OracleCorporation开发的一种用于与Oracle数据库配合使用的编...

Oracle数据库扩展语言PL/SQL之块结构

【本文详细介绍了Oracle数据库扩展语言PL/SQL的块结构,欢迎读者朋友们阅读、转发和收藏!】1基本概念1.1PL/SQL块结构块(block)是PL/SQL的基本程序单元,编写P...

记一次生产数据库sql优化案例--with用法改写(11分钟优化到7秒)

概述前段时间开发丢了一个超长的sql给我,说需要优化,因为太长,连PL/SQL的美化工具都美化不了...下面简单记录一下优化的过程。with改写WITHAS短语,也叫做子查询部分(subquery...

如何在生产库与测试库做数据结构对比--PL/SQL工具

概述领导要求做个数据库之间的数据结构对比,这里我简单用PL/SQL工具来实现,下面介绍下使用过程。功能PLSQLDeveloperTools菜单下有CompareUserObjects和Com...

PLSQL使用教程——(1)基本使用教程

一、登录1、在这里配置好数据库服务,之后就可以登录了2、输入用户名和密码,并选择之前配置好的数据库服务。我这服务名取为localhost。(这个名字随意起。)二、创建表空间1、在SQL窗口中执行以下S...

PL/SQL调试存储过程?看这篇就够了

概述虽然现在存储过程相对比较少用了,但是平时接触不可避免的要跟存储过程打交道,当需要自己写的时候总会碰到这或那的错误,这个时候一般要怎么调试呢?PL/SQL调试PL/SQL中提供了【调试存储过程】的功...

IT运维基础篇之oracle sqlldr数据批量导入,比plsqldev还简单

在oralce中导入数据的方式有很多,比如:PL/SQL文本导入器、对表forupdate之后直接复制粘贴等等,导入方式有很多,今天我们介绍另一种大批量数据导入方式:sqlldr,具体其用法可以上网查...

取消回复欢迎 发表评论: