使用JDBC CallableStatements执行存储过程

使用JDBC CallableStatements执行存储过程

实验目的:掌握jdbc callableStatements 的执行过程。

实验内容:掌握jdbc callableStatements 的执行过程。

实验过程:

CallableStatement的所有超级接口为PreparedStatement、Statement、Wrapper。其中继承自PreparedStatement接口。CallableStatement主要是调用数据库中的存储过程。在使用CallableStatement时可以接收存储过程的返回值。CallableStatement对象为所有的DBMS提供了一种标准的形式去调用数据库中已存在的存储过程。对数据库中存储过程的调用是CallableStatement对象所含的内容。有两种形式:1:形式带结果参数;2:形式不带结果参数。结果参数是一种输出参数(存储过程中的输出OUT参数),是存储过程的返回值。两种形式都有带有数量可变的输入、输出、输入和输出的参数。用问号做占位符。

形式带结果参数语法格式:{ ? = call 存储过程名[(?, ?, ?, ...)]};

形式不带结果参数语法格式:{ call 存储过程名[(?, ?, ?, ...)]};PS方括号里面的内容可有可无。

CallableStatement接口中常用的方法。

1:getInt(int parameterIndex)、getInt(String parameterName)、还有getString、getBigDecimal、getString、getDate、getURL等等都类似和PreparedStatement与Statement中的用法类似。

2:registerOutParameter(int parameterIndex, int sqlType):按顺序位置parameterIndex将OUT参数注册为JDBC类型sqlType。

3:wasNull():查询最后一个读取的OUT参数是否为SQL Null。等等还有很多方法,感兴趣的读者可以自行查阅JDK API文档。

讲解了那么多,不如一个例子来的痛快。下面通过一个例子让读者更清楚的看到CallableStatement的用法。

首先在原先的t_employee表中添加表示干了多少年的tyear字段。

alter table t_employee add tyear int;

在数据库中编写存储过程统计指定id的userName的人,输出一下他一共赚了多少钱。

JDBC代码:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

package com.panli.dbutil;

/**

 * 连接数据库

 */

import java.sql.CallableStatement;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.sql.Statement;

 

public class DbUtil {

    //数据库驱动名字

    private static String jdbcName = "com.mysql.jdbc.Driver";

    //数据库协议地址

    private static String dbUrl = "jdbc:mysql://localhost:3306/db_user";

    //数据库用户名

    private static String dbUser = "root";

    //数据库密码

    private static String dbPassword = "123456";

    

    

    /**

     * 获取连接

     * @return

     * @throws Exception

     */

    public static Connection getCon() throws Exception{

        Class.forName(jdbcName);

        Connection conn = DriverManager.getConnection(dbUrl, dbUser, dbPassword);

        return conn;

    }

    

    /**

     * 关闭连接

     * @param stmt

     * @param conn

     * @throws Exception

     */

    public static void close(Statement stmt,Connection conn) throws Exception{

        if(stmt!=null){

            stmt.close();

            if(conn!=null){

                conn.close();

            }

        }

    }

    

    /**

     * 关闭连接

     * @param cstmt

     * @param conn

     * @throws Exception

     */

    public static void close(CallableStatement cstmt, Connection conn) throws Exception{

        if(cstmt!=null){

            cstmt.close();

            if(conn!=null){

                conn.close();

            }

        }

    }

    

    

    /**

     * 关闭连接

     * @param pstmt

     * @param conn

     * @throws SQLException

     */

    public static void close(PreparedStatement pstmt, Connection conn) throws SQLException{

        if(pstmt!=null){

            pstmt.close();

            if(conn!=null){

                conn.close();

            }

        }

    }

    

    

    /**

     * 重载关闭方法

     * @param pstmt

     * @param conn

     * @throws Exception

     */

    public void close(ResultSet rs,PreparedStatement pstmt, Connection conn) throws Exception{

        if(rs!=null){

            rs.close();

            if(pstmt!=null){

                pstmt.close();

                if(conn!=null){

                    conn.close();

                }

                

            }

        }

        

    }

}


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

package com.panli.model;

 

import java.io.File;

 

/**

 * model包下的cemployee类,对每个字段进行建模

 * @author Peter

 *

 */

public class CEmployee {

    private int id;

    private String userName;

    private double salary;

    private String job;

    private int jobTypeId;

    private File context;

    private File pic;

    private double counts;

    /**

     * 默认的构造方法

     */

    public CEmployee() {

        super();

        // TODO Auto-generated constructor stub

    }

    

    /**

     * 带一个参数的构造方法

     * @param id

     */

    public CEmployee(int id) {

        super();

        this.id = id;

    }

    

    /**

     * 两个参数的构造方法

     * @param counts

     * @param userNames

     */

    public CEmployee(double counts, String userName) {

        // TODO Auto-generated constructor stub

        this.counts = counts;

        this.userName = userName;

    }

 

    /**

     * 重写toString()方法

     */

    @Override

    public String toString(){

        return userName+"一共赚了"+counts+"钱";

    }

    public int getId() {

        return id;

    }

    public void setId(int id) {

        this.id = id;

    }

    public String getUserName() {

        return userName;

    }

    public void setUserName(String userName) {

        this.userName = userName;

    }

    public double getSalary() {

        return salary;

    }

    public void setSalary(double salary) {

        this.salary = salary;

    }

    public String getJob() {

        return job;

    }

    public void setJob(String job) {

        this.job = job;

    }

    public int getJobTypeId() {

        return jobTypeId;

    }

    public void setJobTypeId(int jobTypeId) {

        this.jobTypeId = jobTypeId;

    }

 

    public File getContext() {

        return context;

    }

 

    public void setContext(File context) {

        this.context = context;

    }

 

    public File getPic() {

        return pic;

    }

 

    public void setPic(File pic) {

        this.pic = pic;

    }

 

    public double getCounts() {

        return counts;

    }

 

    public void setCounts(double counts) {

        this.counts = counts;

    }

    

}


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

package com.panli.dao;

 

import java.sql.CallableStatement;

import java.sql.Connection;

import java.sql.Types;

import java.util.ArrayList;

import java.util.List;

 

import com.panli.dbutil.DbUtil;

import com.panli.model.CEmployee;

 

public class CountsEmployeeDao {

    private static DbUtil dbUtil = new DbUtil();

    /**

     * 调用存储过程得到指定ID用户的一共赚了多少钱

     * @param employee

     * @return

     * @throws Exception

     */

    public static List getCountsById(CEmployee cemployee)throws Exception{

        List list = new ArrayList();

        Connection conn = dbUtil.getCon();

        String sql = "{call pro_getCountById(?, ?, ?)}";

        CallableStatement cstmt = conn.prepareCall(sql);

        cstmt.setInt(1, cemployee.getId());

        cstmt.registerOutParameter(2, Types.DOUBLE);

        cstmt.registerOutParameter(3, Types.VARCHAR);

        cstmt.execute();

        double counts = cstmt.getDouble("counts");

        String userNames = cstmt.getString("userNames");

        CEmployee emp = new CEmployee(counts, userNames);

        list.add(emp);

        dbUtil.close(cstmt, conn);

        return list;

    }

    /**

     * 做测试的主方法

     * @param args

     */

    public static void main(String[] args)throws Exception {

        

        CEmployee cemployee = new CEmployee(1);

        List list = getCountsById(cemployee);

        for(CEmployee cemp: list){

            System.out.println(cemp);

        }

    }

}

创建的存储过程为:


1

2

3

4

5

6

7

8

9

10

11

delimiter &&

create procedure pro_getCountById(in tid int, out counts double, out userNames varchar(20))

begin

  select salary*tyear into counts from t_employee where id = tid;

  select userName into userNames from t_employee where id = tid;

end

&&

 

测试:

call pro_getCountById(1, @counts, @userNames);

select @counts, @userNames;


1

alter table t_employee add tyear int;

---恢复内容结束---

原文地址:https://www.cnblogs.com/ting-3/p/10991155.html

时间: 2024-10-29 09:35:03

使用JDBC CallableStatements执行存储过程的相关文章

JAVA使用JDBC技术操作SqlServer数据库执行存储过程

Java使用JDBC技术操作SqlServer数据库执行存储过程: 1.新建SQLSERVER数据库:java_conn_test 2.新建表:tb_User 3.分别新建三个存储过程: 1>带参数的新增用户存储过程: CREATE PROCEDURE [dbo].[p_Insert_User] @name nvarchar(50), @UserPwd nvarchar(50) AS BEGIN INSERT INTO tb_User VALUES(NEWID(),@name,@UserPwd)

JDBC连接执行MySQL存储过程报权限错误

今天在测试项目的时候  突然就报了一个错出来. User does not have access to metadata required to determine stored procedure parameter types. If rights can not be granted, configure connection with "noAccessToProcedureBodies=true" to have driver generate parameters tha

原生jdbc执行存储过程

1 //定时任务,结转 . 2 //表名 fys_sch_lvyou2 ,存储过程名:fys_sch_lvyou2_carrayover 3 //无参调用:{call insertLine} 4 //有参调用:{call fys_sch_lvyou2_carrayover(?,?) 然后传递参数即可 5 public void startCarrayOver(){ 6 //获取要结转的时间:当前月(2016年09月30日)的上月,2016年08月 7 Calendar c = Calendar.

jdbc中的Statement对象和Preparedstatement对象的区别,以及通过jdbc操作调用存储过程

一. java.sql.*   和  javax.sql.*的包的类结构 |- Driver接口: 表示java驱动程序接口.所有的具体的数据库厂商要来实现此接口. |- connect(url, properties):  连接数据库的方法. url: 连接数据库的URL URL语法: jdbc协议:数据库子协议://主机:端口/数据库 user: 数据库的用户名 password: 数据库用户密码 |- DriverManager类: 驱动管理器类,用于管理所有注册的驱动程序 |-regis

jdbc调用 oracle 存储过程操作

创建有参存储函数findEmpNameAndSal(编号),查询7902号员工的的姓名和月薪,[返回多个值,演示out的用法]当返回2个或多个值,必须使用out符号当返回1个值,就无需out符号 create or replace function findEmpNameAndSal(pempno in number,pename out varchar2) return numberas psal emp.sal%type;begin select ename,sal into pename,

Java中执行存储过程和函数(web基础学习笔记十四)

一.概述 如果想要执行存储过程,我们应该使用 CallableStatement 接口. CallableStatement 接口继承自PreparedStatement 接口.所以CallableStatement 接口包含有Statement 接口和PreparedStatement 接口定义的全部方法,但是并不是所有的方法我们都要使用,主要使用的方法有这样几个: CallableStatement 常用方法: 返回类型 方法签名 说明 boolean execute() 执行 SQL 语句

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

转载自 http://www.jb51.net/article/34747.htm 1. 创建存储过程 建立一个MySQL的存储过程 add_pro 复制代码代码如下: delimiter // drop procedure add_pro // create procedure add_pro(a int , b int , out sum int ) begin set sum = a * b; end; // 2. 调用存储过程 复制代码代码如下: package com.zhanggao

JDBC使用MySQL存储过程错误

JDBC连接执行 MySQL 存储过程报权限错误:User does not have access to metadata required to determine stored procedure parameter types. If rights can not be granted, 执行存储过程时,出现如下错误: java.sql.SQLException: User does not have access to metadata required to determine st

使用 JDBC 调用函数 & 存储过程

/** * 如何使用 JDBC 调用存储在数据库中的函数或存储过程 */ @Test public void testCallableStatment() { Connection connection = null; CallableStatement callableStatement = null; try { connection = JDBCTools.getConnection(); // 1. 通过 Connection 对象的 prepareCall() // 方法创建一个 Ca