博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JdbcTemplate操作SQLServer存储过程
阅读量:5046 次
发布时间:2019-06-12

本文共 4641 字,大约阅读时间需要 15 分钟。

最近需要频繁使用到存储过程,然而 Jdbc 与 JdbcTemplate 原生的调用实在是有些繁杂,所以我抽空封装了一个通用的工具类,能拿到结果集与输出参数。代码如下:

存储过程操作模板类

package zze.workinglog.utils;import org.springframework.dao.DataAccessException;import org.springframework.jdbc.core.CallableStatementCallback;import org.springframework.jdbc.core.JdbcTemplate;import java.lang.reflect.Field;import java.sql.*;import java.util.*;public class ProcTemplate {    private JdbcTemplate jdbcTemplate;    public ProcTemplate(JdbcTemplate jdbcTemplate) {        this.jdbcTemplate = jdbcTemplate;    }    /**     * 执行存储过程     * @param procName 存储过程名称     * @param outArgInfo 输出参数及参数类型     * @param inArgInfoArr 输入参数及参数值     * @return 结果集封装为 List 返回     */    public List exec(String procName, Map
outArgInfo, Object... inArgInfoArr) { // 校验入参个数必须为偶数 if (!isEven(inArgInfoArr.length)) { throw new RuntimeException("一个入参必须对应一个值"); } if (outArgInfo != null) { // 校验输出参数类型必须为 SQLType Collection
values = outArgInfo.values(); values.forEach(p -> { if (!(p instanceof Integer) || !(isInclude(Integer.parseInt(p.toString())))) { throw new RuntimeException("类型代码必须在【java.sql.Types】类中已定义"); } }); } // 入参信息整理 Map
inArgInfo = new HashMap<>(); String inArgName = ""; for (int i = 0; i < inArgInfoArr.length; i++) { boolean isArgInfo = isEven(i); if (isArgInfo) { // 偶数时为参数信息 inArgName = inArgInfoArr[i].toString(); } else {
// 奇数时为参数值 inArgInfo.put(inArgName, inArgInfoArr[i]); } } // 拼接执行存储过程参数占位符 String procPlaceHolder = genProcPlaceHolder(inArgInfo.size() + (outArgInfo != null ? outArgInfo.size() : 0)); // 要执行的 SQL String execSql = String.format("exec %s %s", procName, procPlaceHolder); return jdbcTemplate.execute(execSql, new CallableStatementCallback
>>() { @Override public List
> doInCallableStatement( CallableStatement cs) throws SQLException, DataAccessException { // 设置入参参数值 for (String inArgName : inArgInfo.keySet()) { cs.setObject(inArgName, inArgInfo.get(inArgName)); } if (outArgInfo != null) { // 注册输出参数 for (String outArgName : outArgInfo.keySet()) { cs.registerOutParameter(outArgName, (Integer) outArgInfo.get(outArgName)); } } // 执行存储过程,获得结果集 ResultSet rs = cs.executeQuery(); List list = convertResultSetToList(rs); if (outArgInfo != null) { // 获取输出参数值 for (String outArgName : outArgInfo.keySet()) { outArgInfo.replace(outArgName, cs.getObject(outArgName)); } } return list; } }); } public List convertResultSetToList(ResultSet rs) throws SQLException { // 封装到 List List
> resultList = new ArrayList<>(); ResultSetMetaData metaData = rs.getMetaData(); int columnCount = metaData.getColumnCount(); while (rs.next()) { // 转换每行的返回值到Map中 Map rowMap = new HashMap(); for (int i = 1; i <= columnCount; i++) { String columnName = metaData.getColumnName(i); rowMap.put(columnName, rs.getString(columnName)); } resultList.add(rowMap); } rs.close(); return resultList; } /** * 判断一个数是不是偶数 * * @param num 需要判断的数字 * @return 如果是返回 true,否则为 false */ private boolean isEven(int num) { return num % 2 == 0; } /** * 按指定个数生成存储过程占位符 * * @param argCount 参数个数 * @return 占位符字符串,如 ?,?,?,... */ private String genProcPlaceHolder(int argCount) { List
placeHolderList = new ArrayList<>(); for (int i = 0; i < argCount; i++) { placeHolderList.add("?"); } return String.join(",", placeHolderList); } /** * 检查传入类型代码是否合法 * * @param key 类型代码 * @return 如果合法则返回 true,否则返回 false * @throws IllegalAccessException */ private static boolean isInclude(int key) { List
typeCodeList = new ArrayList
(); Field[] declaredFields = Types.class.getDeclaredFields(); for (Field declaredField : declaredFields) { try { typeCodeList.add(declaredField.getInt(Types.class)); } catch (IllegalAccessException e) { throw new RuntimeException("类型检查失败"); } } return typeCodeList.contains(key); }}

使用

// 定义一个存放输出参数信息的 Map ,泛型必须为 Map
,如果没有输出参数则可直接传 nullMap
outArgInfo = new HashMap<>();// 向输出参数 Map 中添加输出参数信息,key 是存储过程对应输出参数名称,值是 java.sql.Types 中的成员变量outArgInfo.put("remark", Types.VARCHAR);// 执行存储过程,返回值为将结果集包装的 List,输出参数值直接返回到 outArgInfo// param1:存储过程名称// param2:输出参数 Map 对象// param3-n:输入参数与其值,如 "id",1,"name","zhang",...List list = procTemplate.exec("proc_testOutputParam", outArgInfo, "intUserID", 22340);// 输出参数值直接从 outArgInfo 中拿到System.out.println(outArgInfo.get("remark"));

转载于:https://www.cnblogs.com/zze46/p/10844624.html

你可能感兴趣的文章
时间>金钱
查看>>
元数据元素
查看>>
Visual Studio Code 构建C/C++开发环境
查看>>
web自己主动保存表单
查看>>
一个小的日常实践——高速Fibonacci数算法
查看>>
创建与删除索引
查看>>
java的基本数据类型
查看>>
机器学些技法(9)--Decision Tree
查看>>
静态页面复习--用semantic UI写一个10min首页
查看>>
在Windows下安装64位压缩包版mysql 5.7.11版本的方法
查看>>
drf权限组件
查看>>
输入月份和日期,得出是今年第几天
查看>>
利用mysqldump备份mysql
查看>>
Qt中子窗口全屏显示与退出全屏
查看>>
使用brew安装软件
查看>>
[BZOJ1083] [SCOI2005] 繁忙的都市 (kruskal)
查看>>
吴裕雄 python 机器学习——数据预处理嵌入式特征选择
查看>>
Centos6.4安装JDK
查看>>
201521123069 《Java程序设计》 第4周学习总结
查看>>
线性表的顺序存储——线性表的本质和操作
查看>>