使用JDBC CallableStatements執行存儲過程

使用JDBC CallableStatements執行存儲過程java

實驗目的:掌握jdbc callableStatements 的執行過程。mysql

實驗內容:掌握jdbc callableStatements 的執行過程。web

實驗過程:sql

CallableStatement的全部超級接口爲PreparedStatement、Statement、Wrapper。其中繼承自PreparedStatement接口。CallableStatement主要是調用數據庫中的存儲過程。在使用CallableStatement時能夠接收存儲過程的返回值。CallableStatement對象爲全部的DBMS提供了一種標準的形式去調用數據庫中已存在的存儲過程。對數據庫中存儲過程的調用是CallableStatement對象所含的內容。有兩種形式:1:形式帶結果參數;2:形式不帶結果參數。結果參數是一種輸出參數(存儲過程當中的輸出OUT參數),是存儲過程的返回值。兩種形式都有帶有數量可變的輸入、輸出、輸入和輸出的參數。用問號作佔位符。數據庫

       形式帶結果參數語法格式:{ ? = call 存儲過程名[(?, ?, ?, ...)]};app

       形式不帶結果參數語法格式:{ call 存儲過程名[(?, ?, ?, ...)]};PS方括號裏面的內容無關緊要。ide

       CallableStatement接口中經常使用的方法。測試

       1:getInt(int parameterIndex)、getInt(String parameterName)、還有getString、getBigDecimal、getString、getDate、getURL等等都相似和PreparedStatement與Statement中的用法相似。this

       2:registerOutParameter(int parameterIndex, int sqlType):按順序位置parameterIndex將OUT參數註冊爲JDBC類型sqlType。spa

       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 ;

---恢復內容結束---

相關文章
相關標籤/搜索