使用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; | 
---恢复内容结束---
                    
                
                
            
        
浙公网安备 33010602011771号