ludc
2025-01-16 986aa62ed00bee39363bab41b4eeb8259d446efd
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/**
 * <p>Title:</p>
 * <p>Description:</p>
 * <p>Copyright: Copyright (C) 2011 </p>
 * <p>Company: VCI </p>
 * @author Bear
 * @time 2011-8-22
 * @version 1.0
 */
package com.vci.server.base.persistence.dao;
 
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.LinkedHashMap;
 
import com.vci.common.log.ServerWithLog4j;
 
 
public class JDBCTemplate {
 
    private Object res = null;
    private Connection cn = null;
    private ResultSet rst = null;
    private CallableStatement cst = null;
    private String sql = "";
    private JDBCCallback callback = null;
    
    /**
     * 执行存储过程或函数
     * @param callback 回调对象
     * @return
     * @throws Exception
     */
    public Object run(JDBCCallback callback) throws JDBCException{
        this.callback = callback;
        if(callback == null){
            return res;
        }
        try{
            cn = callback.getCn();
            if(cn == null){
                return res;
            }
            sql = callback.getSql();
            cst = cn.prepareCall(sql);
            Object[] params = callback.getParams();
            JDBCRunType runType = callback.getRunType();
            int i = 1;
            // 函数的第一个参数是返回值
            if(runType == JDBCRunType.Function){
                cst.registerOutParameter(1, callback.getReturnSqlType());
                i = 2;
            }
            // 依次设置参数值
            if(params != null){
                for(Object val : params){
                    cst.setObject(i++, val);
                }
            }
            int refOutParamIndex = i;
            // 设置引用输出游标参数
            if(runType == JDBCRunType.Procedure && callback.isHasRefCursorOut()){
//                oracle.jdbc.OracleTypes.CURSOR = -10
                cst.registerOutParameter(refOutParamIndex, -10);
                // add by xchao 2012.12.13 完善存储过程对输出参数的支持
                registerOutParameter();
            }
            // 数据处理
            // 是函数时,直接取函数的返回值作为当前函数的返回值
            if(runType == JDBCRunType.Function){
                // add by xchao 2012.12.13 完善存储过程对输出参数的支持
                registerOutParameter();
                // 执行
                rst = cst.executeQuery();
                res = cst.getObject(1);
                // add by xchao 2012.12.13 完善存储过程对输出参数的支持
                readOutParamValueToMap();
            }
            // 是存储过程中时,如果有引用游标输出,则调用回调处理,否则
            else if(runType == JDBCRunType.Procedure){
                // 执行
                cst.execute();
                // add by xchao 2012.12.13 完善存储过程对输出参数的支持
                readOutParamValueToMap();
                if(callback.isHasRefCursorOut()){
                    rst = (ResultSet)cst.getObject(refOutParamIndex);
                    res = callback.execute(rst);
                }
            } else if(runType == JDBCRunType.SQL){
                rst = cst.executeQuery();
                res = callback.execute(rst);
            }
//            cn.commit();
        }catch(SQLException e){
            e.printStackTrace();
            try {
                cn.rollback();
            } catch (Throwable t) {
            }
            ServerWithLog4j.logger.error("↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓");
            ServerWithLog4j.logger.error(e);
            ServerWithLog4j.logger.error(e.getClass().getName() + ":StackTrace", e);
            ServerWithLog4j.logger.error("↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑");
            throw new JDBCException(e);
        }finally{
            try{
                if(rst != null) rst.close();
                if(cst != null) cst.close();
                // 根据参数选项,决定要不要关闭连接对象
                // 如果此连接来自于与Session连接池中的Connection,则不应该关闭连接
                // 如果此连接来自与DB创建的新连接(无连接池或不是从连接池中取出的连接),则需要即时关闭
                // 对于在启用了Hiberate的应用中,不需要即时关闭连接
                if(callback.isCloseConnectionInFinally()){
                    if(cn != null) cn.close();
                }
            }catch(SQLException e){
                throw new RuntimeException(e);
            }
        }
        return res;
    }
    
    /**
     * 设置输出参数、类型
     * @throws SQLException
     */
    private void registerOutParameter() throws SQLException{
        // add by xchao 2012.12.13 完善存储过程对输出参数的支持
        if(callback.getOutParamTypeMaps() != null){
            Iterator<Integer> keys = callback.getOutParamTypeMaps().keySet().iterator();
            while(keys.hasNext()){
                Integer key = keys.next();
                cst.registerOutParameter(key, callback.getOutParamTypeMaps().get(key));
            }
        }
    }
    /**
     * 读取输出参数数据值
     * @throws SQLException
     */
    private void readOutParamValueToMap() throws SQLException{
        // add by xchao 2012.12.13 完善存储过程对输出参数的支持
        if(callback.getOutParamTypeMaps() != null){
            LinkedHashMap<Integer, Object> outParamValueMaps = new LinkedHashMap<Integer, Object>();
            Iterator<Integer> keys = callback.getOutParamTypeMaps().keySet().iterator();
            while(keys.hasNext()){
                Integer key = keys.next();
                Object value = cst.getObject(key);
                outParamValueMaps.put(key, value);
            }
            callback.setOutParamValueMaps(outParamValueMaps);
        }
    }
}