stored procedure connector/j 8.0 Developer guide7.3

使用JDBC CallableStatements執行存儲過程

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

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

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

       CallableStatement接口中經常使用的方法。數據庫

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

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

       3:wasNull():查詢最後一個讀取的OUT參數是否爲SQL Null。等等還有不少方法,感興趣的讀者能夠自行查閱JDK API文檔。測試

      講解了那麼多,不如一個例子來的痛快。下面經過一個例子讓讀者更清楚的看到CallableStatement的用法。this

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

1
alter table t_employee add tyear  int ;

在數據庫中編寫存儲過程統計指定id的userName的人,輸出一下他一共賺了多少錢。code

      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 ;

使用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字段。

1
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 ;
相關文章
相關標籤/搜索