使用Jdbc调用存储过程相信大多数朋友在开发过程中都会用到,本例使用一个工具类将调用存储过程的方法封装起来,隐藏了大部分的处理逻辑,使用起来还是很方便的。
package com.coolfancy;
import java.math.BigDecimal;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.Date;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.ConnectionCallback;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.stereotype.Service;
@Service
public class ProcedureUtil extends JdbcDaoSupport {
@Autowired
public void setter(DataSource dataSource) {
super.setDataSource(dataSource);
}
/**
* <p>
* 调用存储过程。
* </p>
* <p>
* 输入参数可识别的数据类型为String、Long、BigDecimal和Date,识别三种特殊类型的入参:
* <ul>
* <li>"varcharnull"表示Null值的VARCHAR型入参;
* <li>"numbernull"表示Null值的Number型入参;
* <li>"datenull"表示Null值的Date型入参。
* </ul>
* </p>
* <p>
* 输出参数的类型用字符串表示,识别的三种值:
* <ul>
* <li>"varchar"表示VARCHAR型出参;
* <li>"number"表示Number型出参;
* <li>"date"表示Date型出参。
* </ul>
* </p>
* <p>
*
* @author coolfancy
* @param proName
* 存储过程名称。
* @param paraIn
* 输入参数。
* @param _paraOutType
* 输出参数的类型,传入Null表示没有返回值。
* @return 存储过程的返回值。
*/
public List<Object> executeProcedure(final String proName, final Object[] paraIn, final String[] _paraOutType) {
final int len = _paraOutType == null ? 0 : _paraOutType.length;
final int[] paraOutType = new int[len];
for (int i = 0; i < len; i++) {
if ("varchar".equalsIgnoreCase(_paraOutType[i]))
paraOutType[i] = Types.VARCHAR;
else if ("number".equalsIgnoreCase(_paraOutType[i]))
paraOutType[i] = Types.FLOAT;
else if ("date".equalsIgnoreCase(_paraOutType[i]))
paraOutType[i] = Types.DATE;
}
paraOutType[len] = Types.FLOAT;
paraOutType[len + 1] = Types.VARCHAR;
return getJdbcTemplate().execute(new ConnectionCallback<List<Object>>() {
public List<Object> doInConnection(Connection conn) throws SQLException, DataAccessException {
final List<Object> returnObjs = new ArrayList<Object>();
final StringBuffer procedureName = new StringBuffer("{call ").append(proName).append("(");
for (int i = 0; i < paraIn.length + len; i++) {
if (i == paraIn.length + len - 1)
procedureName.append("?)}");
else
procedureName.append("?,");
}
final CallableStatement proc = conn.prepareCall(procedureName.toString());
for (int i = 1; i <= paraIn.length; i++) {
final Object para_obj = paraIn[i - 1];
if (para_obj == null || para_obj.equals("varcharnull")) {
proc.setNull(i, Types.VARCHAR);
} else if (para_obj.equals("numbernull")) {
proc.setNull(i, Types.FLOAT);
} else if (para_obj.equals("datenull")) {
proc.setNull(i, Types.DATE);
} else if (para_obj instanceof String) {
proc.setString(i, (String) para_obj);
} else if (para_obj instanceof BigDecimal) {
proc.setBigDecimal(i, (BigDecimal) para_obj);
} else if (para_obj instanceof Date) {
proc.setDate(i, (Date) para_obj);
} else if (para_obj instanceof Long) {
proc.setLong(i, ((Long) para_obj).longValue());
} else {
throw new RuntimeException("执行存储过程" + proName + "]时发生错误:");
}
}
for (int i = paraIn.length + 1; i <= paraIn.length + paraOutType.length; i++)
proc.registerOutParameter(i, paraOutType[i - paraIn.length - 1]);
try {
proc.execute();
for (int i = 1; i <= paraOutType.length; i++)
returnObjs.add(proc.getObject(i + paraIn.length));
} finally {
proc.close();
}
return returnObjs;
}
});
}
}
更多精彩原创文章请关注笔者的原创博客:http://www.coolfancy.com