使用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 ; |
---恢复内容结束---