JdbcTemplate操作SQLServer存储过程

最近需要频繁使用到存储过程,然而 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<String, Object> outArgInfo, Object... inArgInfoArr) {
        // 校验入参个数必须为偶数
        if (!isEven(inArgInfoArr.length)) {
            throw new RuntimeException("一个入参必须对应一个值");
        }
        if (outArgInfo != null) {
            // 校验输出参数类型必须为 SQLType
            Collection<Object> values = outArgInfo.values();
            values.forEach(p -> {
                if (!(p instanceof Integer) || !(isInclude(Integer.parseInt(p.toString())))) {
                    throw new RuntimeException("类型代码必须在【java.sql.Types】类中已定义");
                }
            });
        }
        // 入参信息整理
        Map<String, Object> 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<List<Map<String, Object>>>() {
                    @Override
                    public List<Map<String, Object>> 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<Map<String, Object>> 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<String> 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<Integer> typeCodeList = new ArrayList<Integer>();
        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<String, Object>,如果没有输出参数则可直接传 null
Map<String, Object> 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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Spring Boot是一个开源的Java框架,用于快速构建基于Spring的应用程序。SQL Server是微软公司开发的关系型数据库管理系统。Spring Boot可以很方便地与SQL Server集成,通过使用Spring Data JPA或MyBatis等ORM框架,可以轻松地进行数据库操作。同时,Spring Boot还提供了一些自动配置和简化的API,使得开发人员可以更加快速地开发和部署应用程序。 ### 回答2: Spring Boot是一个用于创建Java应用程序的开发框架,它简化了Java的开发过程。而SQL Server是一种关系型数据库管理系统,可用于存储和管理企业级数据。 在Spring Boot中使用SQL Server,需要进行以下配置: 首先,在pom.xml文件中添加SQL Server的相关依赖,如下所示: ```xml <dependency> <groupId>com.microsoft.sqlserver</groupId> <artifactId>mssql-jdbc</artifactId> <version>8.4.1.jre11</version> </dependency> ``` 然后,在application.properties或application.yml文件中配置SQL Server的连接信息,包括数据库URL、用户名、密码等,如下所示: ```properties spring.datasource.url=jdbc:sqlserver://localhost:1433;databaseName=mydatabase spring.datasource.username=sa spring.datasource.password=password spring.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver ``` 接下来,创建一个Spring Boot的实体类,用于映射SQL Server中的表结构。 ```java @Entity @Table(name = "user") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "name") private String name; // 省略getter和setter } ``` 然后,创建一个Spring Boot的数据访问层接口和实现类,用于执行SQL Server的增删改查操作。 ```java @Repository public interface UserRepository extends JpaRepository<User, Long> { // 省略其他方法 } ``` 最后,在Spring Boot的业务逻辑层或控制器中,调用数据访问层的方法,实现与SQL Server的交互。 ```java @Service public class UserService { @Autowired private UserRepository userRepository; public User getUser(Long id) { return userRepository.findById(id).orElse(null); } public void saveUser(User user) { userRepository.save(user); } // 省略其他方法 } ``` 通过以上配置和代码,我们可以在Spring Boot项目中使用SQL Server进行数据持久化操作。同时,Spring Boot还提供了很多与SQL Server的集成解决方案,比如使用JdbcTemplate执行原生SQL语句、使用MyBatis进行数据访问等,开发人员可以根据实际需求选择合适的方法来操作SQL Server数据库。 ### 回答3: Spring Boot是一个用于构建Java应用程序和微服务的开发框架,它提供了一种简化和快速启动项目的方法。SQL Server是Microsoft开发的一个关系型数据库管理系统。 使用Spring Boot与SQL Server可以实现Java应用程序与SQL Server数据库的无缝集成。Spring Boot提供了JPA(Java Persistence API)和Spring Data JPA等持久化技术,可以方便地操作SQL Server数据库。 首先,在Spring Boot项目的配置文件中配置SQL Server数据库的连接信息,如连接URL、用户名和密码。可以使用Spring Boot的自动配置功能,只需要在配置文件中指定数据库相关的属性,Spring Boot会自动根据这些属性来配置数据库连接。 然后,创建实体类和数据库表之间的映射关系。通过使用注解(如@Entity、@Table、@Column)标注实体类和属性,可以告诉Spring Boot如何将实体类中的数据映射到数据库表中的字段。 接下来,使用Spring Data JPA提供的接口和方法来操作数据库。Spring Data JPA提供了一组简化的CRUD(Create、Retrieve、Update、Delete)操作方法,可以方便地进行数据库的增删改查操作。 通过以上步骤,已经实现了Spring Boot与SQL Server的集成。可以通过调用JPA接口的方法来执行数据库操作,如保存数据、查询数据、更新数据和删除数据等。 总结一下,通过Spring Boot和SQL Server的集成,可以快速、简便地开发和部署Java应用程序,实现与SQL Server数据库的数据交互和管理。这样可以提升开发效率,同时还能充分利用Spring Boot和SQL Server提供的功能和优势。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值