https://blog.csdn.net/luanlouis/article/details/31376041

前言

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

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

[sql] view plaincopy
  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 plaincopy
  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 plaincopy
  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 plaincopy
  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 plaincopy
  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 plaincopy
  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 plaincopy
  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 plaincopy
  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 plaincopy
  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系列 之 存储过程相关推荐

  1. 老调重弹:JDBC系列 之 存储过程 CallableStatement(创建和使用)

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

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

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

  3. java jdbc 教程_java JDBC系列教程之JDBC类的简析与JDBC的基础操作

    什么是JDBC? 概念:JAVA Database Connectivity Javas数据库连接,Java语言操作数据库接口,然后由各个数据库厂商去实现这个接口,提供数据库驱动java包,我们可以使 ...

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

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

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

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

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

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

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

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

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

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

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

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

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

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

最新文章

  1. Java之控制反转和依赖注入
  2. [转]面向对象(1、三大特征;2、六大原则)
  3. 就这几个简单页面APP,这混小子要我10W块?!大家评评理!
  4. java 作业 老师与教员信息 类与对象
  5. 中国开源燃烧!Zilliz 获全球开源基础软件最大单笔融资 4300 万美元
  6. DedeCms进行SEO优化全攻略
  7. 每日一记—Android动态申请多个权限
  8. $.ajax %5b%5d,数据传回后台数带有%5B%5D的问题
  9. Windows优化大师下载| Windows优化大师下载
  10. OSChina 周五乱弹——岂能说走就能走
  11. 让你精力充沛的25个简单方法
  12. 开源四轴飞行器CC3D的稳定模式和PID算法简介
  13. 轮播图动画滑动动画效果
  14. asp.net MVC三层结构代码生成器
  15. 学习java随堂练习-20220610
  16. 深入浅出PA和LNA
  17. 拒绝一心多用的工作学习方式(转)
  18. kubeadm故障排除
  19. 用友U8C U8Cloud U8 cloud u8c V2.1 2.2 V2.3 V2.4 V2.5 V2.6 V2.7 V3.0 3.1 3.2文件下载
  20. 斑马条纹是为了驱散舌蝇和马蝇

热门文章

  1. 想要升级Big Sur?你的Mac与Big Sur兼容吗?
  2. VirtualBox 虚拟CentOS7新增虚拟盘,并扩充 root和home 目录容量
  3. 利用js解析php的表单数据
  4. Laravel 获取执行的sql语句
  5. 《通信技术导论(原书第5版)》——2.5 内部使用的IP专用交换系统
  6. MySQL初步研究数据库
  7. 21个最佳jQuery插件推荐
  8. cisco4503端口镜像配置
  9. 苹果mac最好用的SVN客户端:Cornerstone 4 (SVN管理工具)
  10. 「Photoshop 入门教程」了解 Photoshop 工作区