共计 4579 个字符,预计需要花费 12 分钟才能阅读完成。
1. 关于 JDBC
(1) 什么是 JDBC?
JDBC 的全称是 Java Database Connectivity。主要有三个功能:
a. 建立与数据库的连接和访问任意表格数据源。
b. 发送一个 SQL 声明。
c. 处理结果。
(2) 连接数据库的前提
a. 安装 jdk。
b. 安装数据库。
c. 下载对应数据库的驱动。
(3) 数据库驱动的类型
a. 驱动实现 JDBC API 作为其他数据访问 API 的一种映射,类似 ODBC(Open Database Connectivity 开放数据库连接)。这种类型的驱动通常依赖于本地库,移植性受到很大的限制。如 JDBC-ODBC 桥接。注意:JDBC-ODBC 桥接被认为是传统的解决方案。它不支持 Oracle 数据库。使用这个驱动最好在您的 DBMS(数据库管理系统)不提供 java 的 JDBC 驱动的情况下。
b. 驱动程序编写部分是 Java 程序语言,部分是本地代码。这些驱动程序使用本地客户端库明确它们连接的数据源是哪个。而且,因为本地代码,移植性也受到了限制。如 Oracle 的 OCI(Oracle Call Interface Oracle 回调接口) 客户端。
c. 使用纯 java 的客户机,使用与数据库无关的协议和中间服务器通信。中间件服务器将主机的请求和数据源进行通信。
d. 使用纯 java 和实现了网络协议的驱动程序来明确数据源。客户端直接和数据源连接。
(这个大家可以看看 Java 关于 JDBC 的文档。)
2. 先在数据库创建一个存储过程,
(1) 先创建包
CREATE OR REPLACE PACKAGE LFF_TEST_PACKAGE
is
PROCEDURE LFF_TEST_PROCEDURE(id in number,org out varchar2,po_fhz out varchar2,po_msg out varchar2);
end LFF_TEST_PACKAGE;1
2
3
4
说明:id 是 number 类型的需要传入的参数,org,po_phz,po_msg 是 varchar2 类型的传出的参数。
(2) 创建包的实体
create or replace package body LFF_TEST_PACKAGE as
PROCEDURE LFF_TEST_PROCEDURE(id in number,org out varchar2,po_fhz out varchar2,po_msg out varchar2)
as
– 定义其他需要使用的变量,需要指定类型及其大小如 username varchar2(20) 而存储过程名称括号里面的输入和输出参数是没有指定类型大小的
begin
–select * into org from XX where xxx = id;
org := ‘aaa’;
po_fhz := ‘1’;
po_msg := ‘ 调用成功 ’;
exception
when others then
po_fhz := ‘-1’;
po_msg := ‘ 调用不成功 ’;
end;
end LFF_TEST_PACKAGE;
注意:exception 表示出现错误时的处理。when others 子句用于捕获命名系统异常和命名的程序员定义异常未处理的所有其余异常。我自己的理解就是相当于 java 中的 try{}catch(Exception e){} 中的 exception。
3. 利用 JDBC 调用数据库的存储过程。
总的来说,执行任何 JDBC 的 SQL 声明,有以下几个步骤:
(1) 建立连接。建立的数据连接可以是 DBMS, 传统的文件系统,或者使用相应的 JDBC 驱动程序的其他数据源。在 Java API 中对应的是 Connection 类。
(2) 创建声明。在 Java API 中有三种类型的声明:
a.Statement: 用于不带参数实现简单 SQL 声明。
b.PreparedStatement:(继承 Statement),用于可以带有输入参数的预编译 SQL 声明。
c.CallableStatement:(继承 PreparedStatement), 用于执行带有输入输出参数的存储过程。
(3) 执行语句。Java API 中有三种执行方法。
a.execute: 使用这个方法可以返回一个或更多个结果集对象。
b.executeQuery: 返回一个结果集。用于查询语句。
c.executeUpdate: 返回受到影响的记录的数目。这个方法用于插入 insert, 删除 delete, 或是更新 update。
(4) 处理结果集对象。通过光标处理 ResultSet 对象。这个光标不是数据库中的光标。这个光标是一个指针指向结果集对象中的某一行数据。最初,这个光标位于第一行数据的前面,你可以使用在结果集 ResultSet 对象中定义的各种各样的方法移动光标。
(5) 关闭连接。无论是否抛出异常,在 finally 中调用 close 方法。根据先打开后关闭的原则。
/**
* @date 2017-6-6
* @author liufeifei
* @description 测试调用数据库的存储过程
*/
public class TestProcedure {
public static void main(String[] args) {
// 数据库驱动的名称
String driver = “oracle.jdbc.OracleDriver”;
// 访问数据库路径 localhost 表示本机 (127.0.0.1),xxx 表示数据库名称
String url = “jdbc:oracle:thin:@localhost:1521:xxx”;
// 用户名
String username = “kfxx”;
// 密码
String password = “kfxx”;
Connection conn = null;
CallableStatement statement = null;
try {
// 加载驱动
Class.forName(driver);
// 连接
conn = DriverManager.getConnection(url, username, password);
// 请求的存储过程 (包名. 存储过程名称,四个? 表示参数)
String sql = “{call LFF_TEST_PACKAGE.LFF_TEST_PROCEDURE(?,?,?,?)}”;
statement = conn.prepareCall(sql);
// 传入的参数
statement.setInt(1,21);
// 返回的参数 (oracle.jdbc.OracleTypes.VARCHAR 表示返回参数类型)
statement.registerOutParameter(2,oracle.jdbc.OracleTypes.VARCHAR);
statement.registerOutParameter(3,oracle.jdbc.OracleTypes.VARCHAR);
statement.registerOutParameter(4,oracle.jdbc.OracleTypes.VARCHAR);
// 执行
statement.execute();
// 拿到返回的值,我的存储过程的参数 1 是传入参数,2,3,4 是传出参数
System.out.println(statement.getString(2) + ” “+ statement.getString(3) + ” “+ statement.getString(4));
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally{
try {
// 关闭连接
if(statement != null){
statement.close();
}
if(conn != null){
conn.close();
}
} catch (SQLException ex1) {
}
}
}
}
另外,Statement 和 PreparedStatement 的使用:
(1) 这三个都是接口 Interface。大家可以去看看 JDK 的源码
public interface Statement extends Wrapper {}
public interface PreparedStatement extends Statement {}
public interface CallableStatement extends PreparedStatement {}1
2
3
Statement 是用来执行不带参数的 SQL 语句。
Connection conn = null;
ResultSet rs = null;
Statement statement = null;
try {
// 加载
Class.forName(driver);
// 连接
conn = DriverManager.getConnection(url, username, password);
// 设置查询语句
statement = conn.createStatement();
statement.execute(“select * from emp”);
// 执行查询
rs = statement.getResultSet();
while(rs.next()){
System.out.println(rs.getObject(2)+”==>”+rs.getObject(1));
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
PreparedStatement 是用来执行带输入参数的 SQL 语句。
Connection conn = null;
ResultSet rs = null;
PreparedStatement statement = null;
try {
// 加载
Class.forName(driver);
// 连接
conn = DriverManager.getConnection(url, username,password);
// 设置查询语句
statement = conn.prepareStatement(“select * from emp where ename like ?”);
// 设置参数
statement.setString(1,”%S%”);
// 执行查询
rs = statement.executeQuery();
while(rs.next()){
System.out.println(rs.getObject(2)+”==>”+rs.getObject(1));
}
}catch(){
}
: