日期:2014-05-16 浏览次数:20475 次
使用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.re