Springboot调用存储过程

本文介绍了如何在SpringBoot应用中使用Oracle数据库的存储过程,包括其封装性、可重用性、参数传递、性能优势以及在Spring框架下通过MyBatis进行调用的详细步骤和配置示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

SpringBoot使用存储过程

前言

存储过程(Stored Procedure)是一种在数据库中存储的、可被多次调用的预编译程序单元。它是一组SQL语句的集合,可以在数据库中执行一系列操作。存储过程通常由数据库管理系统的特定编程语言编写,例如,对于Oracle数据库,存储过程通常是用PL/SQL(Procedural Language/Structured Query Language)编写的。

提示:以下是本篇文章正文内容,下面案例可供参考

一、特点

封装性: 存储过程将一系列SQL语句封装在一个单独的单元中,使其成为一个独立的、可复用的程序。

可重用性: 存储过程可以被多次调用,促使了代码的重用。这有助于减少代码的冗余,并简化了数据库操作的管理。

参数传递: 存储过程可以接受输入参数,使得可以根据不同的参数值执行不同的操作。这增加了存储过程的灵活性和通用性。

性能优化: 存储过程的代码在首次编译后被存储在数据库中,因此每次调用时无需重新编译。这可以提高性能,特别是当存储过程包含复杂的业务逻辑时。

事务控制: 存储过程可以包含事务控制语句,用于确保一系列操作的原子性,即要么全部成功执行,要么全部回滚。

安全性: 存储过程的执行权限可以被分配给不同的用户,以控制对数据库的访问。

提示:用存储过程时,通常通过调用存储过程的名称和传递参数的方式来执行它

二、存储过程的创建和使用

1.存储过程定义

基本结构代码如下(示例):

//存储过程的开始 CREATE PROCEDURE语句用于定义新的存储过程,OR REPLACE表示如果同名的存储过程已经存在,则替换它。
CREATE OR REPLACE PROCEDURE add_numbers
//num1 、num1 等是参数的名称,而NUMBER是参数的数据类型。存储过程可以接受零个或多个输入参数。
(num1 NUMBER, num2 NUMBER, sum OUT NUMBER)
//IS 变量的声明 这里暂未使用
IS
//这是存储过程主体的开始标记(写sql和逻辑)。
BEGIN
     sum := num1 + num2;//自定义sql
//异常捕捉
EXCEPTION
    WHEN OTHERS THEN
        -- 步骤 5: 处理其他异常
        -- 在此处理任何未捕获的异常
        DBMS_OUTPUT.PUT_LINE('An error occurred: ' || SQLERRM);
//结束标记,其中procedure_name是存储过程的名称
END add_numbers;
/


2.使用例子

2.1 创建表

CREATE TABLE employees (
    employee_id NUMBER PRIMARY KEY,
    first_name VARCHAR2(50),
    last_name VARCHAR2(50),
    salary NUMBER
);
-- 插入数据
INSERT INTO employees VALUES (1, 'John', 'Doe', 50000);
INSERT INTO employees VALUES (2, 'Jane', 'Smith', 60000);
COMMIT;

2.2 创建存储过程

-- 创建存储过程  这里是一个简单的查询功能
CREATE OR REPLACE PROCEDURE get_employee_info
    (p_employee_id IN NUMBER, 
     p_first_name OUT VARCHAR2,
     p_last_name OUT VARCHAR2,
     p_salary OUT NUMBER)
AS
BEGIN
    SELECT first_name, last_name, salary
    INTO p_first_name, p_last_name, p_salary  //INTO 语句通常用于将查询的结果赋值给存储过程中声明的变量。
    FROM employees
    WHERE employee_id = p_employee_id;
END get_employee_info;

2.3 SpringBoot方式调用(实体类等省略)
.yml配置文件(安装自己配置修改)

spring.datasource.url=jdbc:oracle:thin:@localhost:1521:xe
spring.datasource.username=your_username
spring.datasource.password=your_password
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
mybatis.mapper-locations=classpath:mapper/*.xml

mapper接口

@Mapper
public interface EmployeeMapper {
    void callGetEmployeeInfo(
        @Param("p_employee_id") int employeeId,
        @Param("p_first_name") Map<String, Object> firstName,
        @Param("p_last_name") Map<String, Object> lastName,
        @Param("p_salary") Map<String, Object> salary
    );

mybatis的xml文件

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.EmployeeMapper">

    <resultMap id="callGetEmployeeInfoResultMap" type="java.util.Map">
        <result column="p_first_name" property="first_name" />
        <result column="p_last_name" property="last_name" />
        <result column="p_salary" property="salary" />
    </resultMap>

    <select id="callGetEmployeeInfo" resultMap="callGetEmployeeInfoResultMap">
        {call get_employee_info(
            #{p_employee_id, mode=IN, jdbcType=INTEGER},
            #{p_first_name, mode=OUT, jdbcType=VARCHAR},
            #{p_last_name, mode=OUT, jdbcType=VARCHAR},
            #{p_salary, mode=OUT, jdbcType=INTEGER}
        )}
    </select>

</mapper>

Service接口

@Service
public class EmployeeService {

    @Autowired
    private EmployeeMapper employeeMapper;

    public Map<String, Object> getEmployeeInfo(int employeeId) {
        Map<String, Object> result = new HashMap<>();
        employeeMapper.callGetEmployeeInfo(employeeId, result, result, result);
        return result;
    }
}

Controller类

@RestController
@RequestMapping("/api/employees")
public class EmployeeController {

    @Autowired
    private EmployeeService employeeService;

    @GetMapping("/{employeeId}")
    public Map<String, Object> getEmployeeInfo(@PathVariable int employeeId) {
        return employeeService.getEmployeeInfo(employeeId);
    }

测试
启动您的 Spring Boot 应用程序,然后使用浏览器或其他工具访问 http://localhost:8080/api/employees/1(替换为您的实际端口和路径)


### 如何在 Spring Boot调用 MySQL 存储过程并返回列表 为了实现这一目标,需要利用 `EntityManager` 来创建命名存储过程查询,并处理其返回的结果集。下面是一个具体的实例说明。 #### 创建实体管理器和定义存储过程接口 首先,在应用程序中引入必要的依赖项以支持 JPA 和 MySQL 操作。接着,定义一个 Repository 接口用于声明自定义的方法来调用存储过程: ```java package com.example.repository; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface UserRepository extends JpaRepository<User, Long> { // 自定义方法签名,稍后将通过实现类提供具体逻辑 } ``` #### 实现存储过程调用逻辑 接下来,构建服务层组件负责实际调用存储过程以及映射结果至 Java 对象集合。这里假设有一个名为 `findUsersByCriteria` 的存储过程接受输入参数并返回多条记录作为输出: ```java package com.example.service.impl; import javax.persistence.EntityManager; import javax.persistence.StoredProcedureQuery; import java.util.ArrayList; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.example.model.User; import com.example.repository.UserRepository; @Service public class UserServiceImpl { private final EntityManager entityManager; private final UserRepository userRepository; @Autowired public UserServiceImpl(EntityManager entityManager, UserRepository userRepository) { this.entityManager = entityManager; this.userRepository = userRepository; } /** * 调用 findUsersByCriteria 存储过程并将结果转换成 List<User> */ public List<User> callFindUsersByCriteriaProcedure(String criteriaValue) { StoredProcedureQuery query = entityManager.createNamedStoredProcedureQuery("findUsersByCriteria"); // 设置 IN 参数 query.setParameter("criteria", criteriaValue); // 执行查询 boolean hasResults = query.execute(); if (hasResults && !query.getResultList().isEmpty()) { return new ArrayList<>(query.getResultList()); } return null; } } ``` 上述代码展示了如何使用 `createNamedStoredProcedureQuery()` 方法指定要执行的存储过程名称,并设置相应的输入参数。最后,通过 `getResultList()` 获取由存储过程产生的数据行,并将其封装在一个 `ArrayList<User>` 列表里以便进一步处理或展示给客户端应用[^3]。 #### 配置文件中的数据库连接信息 确保项目的 application.properties 文件包含了正确的 MySQL 数据源配置,使得 Spring Boot 可以成功建立与数据库之间的通信通道[^1]: ```properties spring.datasource.url=jdbc:mysql://localhost:3306/your_database?useSSL=false&serverTimezone=UTC spring.datasource.username=root spring.datasource.password=password spring.jpa.hibernate.ddl-auto=update ``` #### 测试 API 请求 当一切准备就绪之后,可以通过 RESTful Web Service 提供对外部系统的访问入口点。例如,可以添加如下控制器端点允许外部请求触发存储过程调用并接收响应的数据结构化表示形式[^4]。 ```java @RestController @RequestMapping("/api/users") public class UserController { private final UserService userService; @GetMapping("/procedure-call") public ResponseEntity<List<User>> getUsersFromProcedure(@RequestParam String criteria){ try{ List<User> users = userService.callFindUsersByCriteriaProcedure(criteria); if(users != null && !users.isEmpty()){ return new ResponseEntity<>(users, HttpStatus.OK); }else{ return new ResponseEntity<>(HttpStatus.NO_CONTENT); } }catch(Exception e){ return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR); } } } ``` 这样便完成了整个流程的设计——从初始化项目环境、编写业务逻辑直至最终暴露 HTTP API 给外界消费。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值