前言

最近在研究Mybatis框架,由于该框架基于JDBC,想要很好地理解和学习Mybatis,必须要对JDBC有较深入的了解。所以便把JDBC 这个东东翻出来,老调重弹,好好总结一番,作为自己的笔记,也是给读者一个参考~~~

本文主要通过 使用JDBC创建存储过程 和使用JDBC调用存储过程两部分 阐述JDBC 对存储过程的支持。本文将在Oracle数据库下创建一个可以表示岗位信息的基本表Jobs为例, 然后通过存储过程对这个Jobs表进行各种操作。表JOBS的建表语句如下:

[sql] view plain copy  print?
  1. -- Create table
  2. create table JOBS
  3. (
  4. job_id     VARCHAR2(10) not null,
  5. job_title  VARCHAR2(35),
  6. min_salary NUMBER(6),
  7. max_salary NUMBER(6)
  8. );
  9. -- Add comments to the table
  10. comment on table JOBS
  11. is '岗位信息表';
  12. -- Add comments to the columns
  13. comment on column JOBS.job_id
  14. is 'Job Id';
  15. comment on column JOBS.job_title
  16. is '岗位名称';
  17. comment on column JOBS.min_salary
  18. is '最小薪酬';
  19. comment on column JOBS.max_salary
  20. is '最大薪酬';
  21. -- Create/Recreate primary, unique and foreign key constraints
  22. alter table JOBS
  23. add constraint PK_JOB_ID primary key (JOB_ID);

JDBC创建存储过程

使用数据库操作数据库需要三个步骤: 执行 创建存储过程语句 --> 编译存储过程---> 调用存储过程

比如我们创建一个向表Jobs添加记录的存储过程,并且调用它,在数据库上要执行下列代码:

[sql] view plain copy  print?
  1. --1.创建存储过程
  2. CREATE OR REPLACE PROCEDURE insert_jobs_proc(
  3. input_job_id IN VARCHAR2,
  4. input_job_title IN VARCHAR2,
  5. input_min_salary IN NUMBER,
  6. input_max_salary IN NUMBER) AS
  7. BEGIN
  8. INSERT INTO jobs(job_id,job_title,Min_Salary,max_salary)VALUES(input_job_id,input_job_title,input_min_salary,input_max_salary);
  9. END insert_jobs_proc;
  10. --2.编译存储过程
  11. COMPILE;
  12. --3.使用存储过程
  13. CALL insert_jobs_proc('AD_PRES','President',20080,40000);

由于上述的代码本质上来说就是SQL代码,可以使用JDBC逐步执行上述的SQL代码即可(不过使用JDBC创建不需要调用compile进行编译,JDBC会自动让数据库编译):

[java] view plain copy  print?
  1. public static void inTest(){
  2. Connection connection = null;
  3. Statement statement = null;
  4. ResultSet resultSet = null;
  5. try {
  6. Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
  7. Driver driver = DriverManager.getDriver(URL);
  8. Properties props = new Properties();
  9. props.put("user", USER_NAME);
  10. props.put("password", PASSWORD);
  11. connection = driver.connect(URL, props);
  12. //获得Statement对象,这里使用了事务机制,如果创建存储过程语句失败或者是执行compile失败,回退
  13. connection.setAutoCommit(false);
  14. statement = connection.createStatement();
  15. String procedureString = "CREATE OR REPLACE PROCEDURE insert_jobs_proc("
  16. +"input_job_id IN VARCHAR2,"
  17. +"input_job_title IN VARCHAR2,"
  18. +"input_min_salary IN NUMBER,"
  19. +"input_max_salary IN NUMBER) AS "
  20. +"BEGIN "
  21. +"INSERT INTO jobs(job_id,job_title,Min_Salary,max_salary)VALUES(input_job_id,input_job_title,input_min_salary,input_max_salary); "
  22. +"END insert_jobs_proc;";
  23. //1 创建存储过程,JDBC 数据库会编译存储过程
  24. statement.execute(procedureString);
  25. //成功则提交
  26. connection.commit();
  27. //2.调用
  28. CallableStatement callableStatement = connection.prepareCall("CALL insert_jobs_proc(?,?,?,?)");
  29. //设置IN参数
  30. callableStatement.setString(1, "AD_PRESS");
  31. callableStatement.setString(2, "President");
  32. callableStatement.setBigDecimal(3, new BigDecimal(20080));
  33. callableStatement.setBigDecimal(4, new BigDecimal(40000));
  34. callableStatement.execute();
  35. connection.commit();
  36. } catch (ClassNotFoundException e) {
  37. System.out.println("加载Oracle类失败!");
  38. e.printStackTrace();
  39. } catch (SQLException e) {
  40. try {
  41. connection.rollback();
  42. } catch (SQLException e1) {
  43. e1.printStackTrace();
  44. }
  45. e.printStackTrace();
  46. } catch (InstantiationException e) {
  47. e.printStackTrace();
  48. } catch (IllegalAccessException e) {
  49. e.printStackTrace();
  50. }finally{
  51. //使用完成后管理链接,释放资源,释放顺序应该是: ResultSet ->Statement ->Connection
  52. try {
  53. statement.close();
  54. } catch (SQLException e) {
  55. e.printStackTrace();
  56. }
  57. try {
  58. connection.close();
  59. } catch (SQLException e) {
  60. e.printStackTrace();
  61. }
  62. }
  63. }

JDBC调用存储过程

使用JDBC调用存储过程的基本格式为:

CALL PROCEDURE_NAME(parameter1,parameter2,paramter3.....)

这里参数有三种不同的形式 :in 类型、out类型还有 in 和out的混合类型:

IN 类型:此类型是用于参数从外部传递给存储过程使用;

OUT类型:此类型是存储过程执行过程中的返回值;

IN、OUT混合类型:此类型是参数传入,然后返回。

以下分四种参数类型创建不同的存储过程,然后通过JDBC调用:

只有输入IN参数,没有输出OUT参数

上面演示的存储过程  insert_jobs_proc 就是只有IN 参数传入的例子,请读者看上述的 例子。

既有输入IN参数,也有输出OUT参数,输出是简单值(非列表)

创建一个存储过程  get_job_min_salary_proc,传入特定岗位的job_id,返回输出此岗位的最小薪酬min_salary,对应的SQL语句如下:

[sql] view plain copy  print?
  1. CREATE OR REPLACE PROCEDURE get_job_min_salary_proc(
  2. input_job_id IN VARCHAR2,
  3. output_salary OUT number) AS
  4. BEGIN
  5. SELECT min_salary INTO output_salary FROM jobs WHERE job_id = input_job_id;
  6. END   get_job_min_salary_proc;

在JDBC中调用如下:

[java] view plain copy  print?
  1. /*
  2. * 有IN 类型的参数输入 和Out类型的参数输出
  3. */
  4. public static void inOutTest(){
  5. Connection connection = null;
  6. Statement statement = null;
  7. ResultSet resultSet = null;
  8. try {
  9. Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
  10. Driver driver = DriverManager.getDriver(URL);
  11. Properties props = new Properties();
  12. props.put("user", USER_NAME);
  13. props.put("password", PASSWORD);
  14. connection = driver.connect(URL, props);
  15. //获得Statement对象,这里使用了事务机制,如果创建存储过程语句失败或者是执行compile失败,回退
  16. connection.setAutoCommit(false);
  17. statement = connection.createStatement();
  18. String procedureString = "CREATE OR REPLACE PROCEDURE get_job_min_salary_proc("
  19. +"input_job_id IN VARCHAR2,"
  20. +"output_salary OUT number) AS "
  21. +"BEGIN "
  22. +"SELECT min_salary INTO output_salary FROM jobs WHERE job_id = input_job_id; "
  23. +"END   get_job_min_salary_proc;";
  24. //1 创建存储过程,JDBC 数据库会编译存储过程
  25. statement.execute(procedureString);
  26. //成功则提交
  27. connection.commit();
  28. //2.创建callableStatement
  29. CallableStatement callableStatement = connection.prepareCall("CALL get_job_min_salary_proc(?,?)");
  30. //3,设置in参数
  31. callableStatement.setString(1, "AD_PRES");
  32. //4.注册输出参数
  33. callableStatement.registerOutParameter(2, Types.NUMERIC);
  34. //5.执行语句
  35. callableStatement.execute();
  36. BigDecimal salary = callableStatement.getBigDecimal(2);
  37. System.out.println(salary);
  38. } catch (ClassNotFoundException e) {
  39. System.out.println("加载Oracle类失败!");
  40. e.printStackTrace();
  41. } catch (SQLException e) {
  42. try {
  43. connection.rollback();
  44. } catch (SQLException e1) {
  45. e1.printStackTrace();
  46. }
  47. e.printStackTrace();
  48. } catch (InstantiationException e) {
  49. e.printStackTrace();
  50. } catch (IllegalAccessException e) {
  51. e.printStackTrace();
  52. }finally{
  53. //使用完成后管理链接,释放资源,释放顺序应该是: ResultSet ->Statement ->Connection
  54. try {
  55. statement.close();
  56. } catch (SQLException e) {
  57. e.printStackTrace();
  58. }
  59. try {
  60. connection.close();
  61. } catch (SQLException e) {
  62. e.printStackTrace();
  63. }
  64. }
  65. }

既有输入IN参数,也有输出OUT参数,输出是列表

创建一个存储过程 get_min_greater_proc,输入参数 最小薪酬,返回jobs表里最小薪酬不小于此参数的岗位集合。

对应的SQL语句如下:

[sql] view plain copy  print?
  1. --创建一个包,自定义一个数据类型 my_cursor
  2. CREATE OR REPLACE PACKAGE my_package_cursor IS
  3. TYPE my_cursor IS REF CURSOR;
  4. END  my_package_cursor;
  5. --创建 存储过程,通过传入最小薪酬,返回JOBs表内不小于最小薪酬的岗位集合
  6. CREATE OR REPLACE PROCEDURE get_min_greater_proc(
  7. input_min_salary IN NUMBER,
  8. setResult OUT my_package_cursor.my_cursor) AS
  9. BEGIN
  10. OPEN    setResult FOR
  11. SELECT * FROM jobs WHERE min_salary >= input_min_salary;
  12. END     get_min_greater_proc;

JDBC调用代码如下:

[java] view plain copy  print?
  1. /*
  2. * 有IN 类型的参数输入 和Out类型的集合输出
  3. */
  4. public static void inOutResultSetTest(){
  5. Connection connection = null;
  6. Statement statement = null;
  7. ResultSet resultSet = null;
  8. try {
  9. Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
  10. Driver driver = DriverManager.getDriver(URL);
  11. Properties props = new Properties();
  12. props.put("user", USER_NAME);
  13. props.put("password", PASSWORD);
  14. connection = driver.connect(URL, props);
  15. //1.创建callableStatement
  16. CallableStatement callableStatement = connection.prepareCall("CALL get_min_greater_proc(?,?)");
  17. //2,设置in参数
  18. callableStatement.setBigDecimal(1, new BigDecimal(20000));
  19. //3.注册输出参数
  20. callableStatement.registerOutParameter(2, OracleTypes.CURSOR);
  21. //4.执行语句
  22. callableStatement.execute();
  23. //返回的是结果集
  24. resultSet = (ResultSet)callableStatement.getObject(2);
  25. } catch (ClassNotFoundException e) {
  26. System.out.println("加载Oracle类失败!");
  27. e.printStackTrace();
  28. } catch (SQLException e) {
  29. try {
  30. connection.rollback();
  31. } catch (SQLException e1) {
  32. e1.printStackTrace();
  33. }
  34. e.printStackTrace();
  35. } catch (InstantiationException e) {
  36. e.printStackTrace();
  37. } catch (IllegalAccessException e) {
  38. e.printStackTrace();
  39. }finally{
  40. //使用完成后管理链接,释放资源,释放顺序应该是: ResultSet ->Statement ->Connection
  41. try {
  42. statement.close();
  43. } catch (SQLException e) {
  44. e.printStackTrace();
  45. }
  46. try {
  47. connection.close();
  48. } catch (SQLException e) {
  49. e.printStackTrace();
  50. }
  51. }
  52. }

输入输出参数是同一个(IN OUT)

创建一个存储过程 get_job_info ,传入job_id 返回 job_id ,返回的job_id 是输入的job_id 和对应的job_title 拼接而成。

[sql] view plain copy  print?
  1. --创建存储过程 传入job_id 返回job_id
  2. CREATE OR REPLACE PROCEDURE get_job_info(
  3. io_job_id IN OUT VARCHAR2) AS
  4. BEGIN
  5. SELECT job_id ||job_title INTO io_job_id FROM jobs WHERE job_id =io_job_id ;
  6. END     get_job_info;

对应的JDBC代码如下:

[java] view plain copy  print?
  1. //1.创建callableStatement
  2. CallableStatement callableStatement = connection.prepareCall("CALL get_job_info(?)");
  3. //2,设置in参数
  4. callableStatement.setString(1, "AD_PRES");
  5. //3.注册输出参数
  6. callableStatement.registerOutParameter(1, Types.VARCHAR);
  7. //4.执行语句
  8. callableStatement.execute();
  9. //返回结果
  10. String jobId = callableStatement.getString(1);
  11. System.out.println(jobId);

----------------------------------------------------------------------------------------------------------------------------------------

注:本篇文章很大程度上借鉴了 JDBC执行存储过程的四种情况 这篇博文。

欢迎读者关注我的   老调重弹:JDBC系列 的其他文章~~~

原文地址:http://blog.csdn.net/luanlouis/article/details/31376041

老调重弹:JDBC系列 之 存储过程 CallableStatement(创建和使用)相关推荐

  1. 老调重弹:JDBC系列 之 JDBC层次结构和基本构成

    前言 最近在研究Mybatis框架,由于该框架基于JDBC,想要很好地理解和学习Mybatis,必须要对JDBC有较深入的了解.所以便把JDBC 这个东东翻出来,老调重弹,好好总结一番,作为自己的笔记 ...

  2. mysql驱动加载原理_老调重弹:JDBC系列 之 lt;驱动载入原理全面解析gt;

    前言 近期在研究Mybatis框架,因为该框架基于JDBC.想要非常好地理解和学习Mybatis,必需要对JDBC有较深入的了解.所以便把JDBC 这个东东翻出来.好好总结一番,作为自己的笔记,也是给 ...

  3. 老调重弹:JDBC系列之驱动加载原理全面解析)

    前言 最近在研究Mybatis框架,由于该框架基于JDBC,想要很好地理解和学习Mybatis,必须要对JDBC有较深入的了解.所以便把JDBC 这个东东翻出来,好好总结一番,作为自己的笔记,也是给读 ...

  4. 老调重弹:JDBC系列 之 驱动加载原理全面解析

    前言 最近在研究Mybatis框架,由于该框架基于JDBC,想要很好地理解和学习Mybatis,必须要对JDBC有较深入的了解.所以便把JDBC 这个东东翻出来,好好总结一番,作为自己的笔记,也是给读 ...

  5. jdbc调用mysql存储过程实现代码带有输入和输出

    转载自 http://www.jb51.net/article/34747.htm 1. 创建存储过程  建立一个MySQL的存储过程 add_pro 复制代码代码如下: delimiter //  ...

  6. jdbc oracle存储过程,java jdbc 执行oracle存储过程

    java jdbc 执行oracle存储过程 发布时间:2020-07-12 08:25:32 来源:51CTO 阅读:188 作者:v512345 java代码 public Connection ...

  7. oracle jdbc执行,java jdbc 执行oracle存储过程

    java代码 public Connection conn() { try { // 第一步:加载JDBC驱动 Class.forName("oracle.jdbc.driver.Oracl ...

  8. jdbc原生调用存储过程-------摸鱼王的日常问题

    日常问题-jdbc原生调用存储过程 大家好,我是摸鱼王 今天上班老板让写个根据条件清理数据库数据的接口 然后我发现java代码执行起来有点慢 因为数据量特别大 于是 写了个删除的存储过程 很简单就不展 ...

  9. jpa 使用jdbc_在JPA和JDBC中使用存储过程。 嗯,只要使用jOOQ

    jpa 使用jdbc Java杂志的当前版本由Josh Juneau撰写了有关JDBC和JPA的大数据最佳实践的文章: http : //www.javamagazine.mozaicreader.c ...

最新文章

  1. Django的路由系统
  2. angular 4使用jquery 第三方插件库
  3. Oracle序列的建立以及使用
  4. 如何用架构师思维解读区块链技术?
  5. 代码演示:获取锁时被中断
  6. OpenBSD基金会收到锤子科技约140万捐赠款
  7. mysql adduser_SQL创建登陆用户和赋予权限
  8. Java简单方法批量修改Windows文件夹下的文件名(简单IO使用)
  9. SAE学习-使用SAE的Storage服务存储图片
  10. 视频实现blob加密
  11. 【matlab】人工智能的仿生优化算法之萤火虫算法讲解(Firefly Algorithm)
  12. 三菱FX3U-PLC 前馈+PID闭环调节实现液压同步控制(比例换向阀)
  13. codecademy课程笔记——JavaScript Promise
  14. python掷骰子实验_Python基础(十二) 模拟掷骰子demo
  15. Java 响应对象详解
  16. Android Studio 卡在Download fastutil-8.4.0-sources jar以及New Module为灰色的问题及解决方法
  17. linux系统 安装nvm
  18. 韩国电力供应商利用区块链构建生态友好型微电网
  19. 九龙擒庄指标源码破译_妖股出世爆发点公式?九龙擒庄指标源码破译!
  20. 配置微型计算机实验报告,微型计算机原理实验报告.docx

热门文章

  1. linux下生成ssh密钥并获取密钥
  2. 【C语言程序设计】实验 2
  3. 数据据结构实验——顺序表实验
  4. OSChina 周四乱弹 —— 你妈是洗衣机的亲妈
  5. vue一些比较重要知识点的复习
  6. 01-【istio】-【服务网格概述】服务网格的优势
  7. 中职 php学啥,中职技校电脑专业主要学什么
  8. java redis 过期_Redis中的键值过期操作
  9. google map v3离线版地图
  10. 百味融汇的火锅宴,品一品别样热辣的鲲鹏生态