You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Spring Boot+Hibernate中调用带IN OUT参数的MySQL存储过程

我来帮你搞定Spring Boot调用带IN/OUT参数的MySQL存储过程的问题,咱们一步步调整代码,完美实现你的需求:


1. 修正实体类的存储过程注解

你的实体类注解有两个小问题:参数名多了空格,而且不需要指定resultClasses(因为咱们用的是OUT参数,不是返回结果集)。修改后的实体类如下:

@Entity
@Table(name = "user")
@NamedStoredProcedureQueries({
    @NamedStoredProcedureQuery(
        name = "LoginModel.do_login", // 用实体类名+方法名的格式,避免命名冲突
        procedureName = "login",
        parameters = {
            @StoredProcedureParameter(name = "in_user_id", type = String.class, mode = ParameterMode.IN),
            @StoredProcedureParameter(name = "in_password", type = String.class, mode = ParameterMode.IN),
            @StoredProcedureParameter(name = "out_code", type = Integer.class, mode = ParameterMode.OUT),
            @StoredProcedureParameter(name = "out_message", type = String.class, mode = ParameterMode.OUT)
        }
    )
})
public class LoginModel implements Serializable {
    private static final long serialVersionUID = 1L;
    
    @NotEmpty
    private String userid;
    @NotEmpty
    private String password;

    // 标准getter、setter方法
    public String getUserid() { return userid; }
    public void setUserid(String userid) { this.userid = userid; }
    public String getPassword() { return password; }
    public void setPassword(String password) { this.password = password; }
}

2. 更新Repository接口,添加存储过程调用方法

Spring Data JPA支持直接用@Procedure注解调用存储过程,返回的Map会自动包含所有OUT参数的键值对:

import org.springframework.data.jpa.repository.Procedure;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.Map;

@Repository
public interface LoginRepository extends CrudRepository<LoginModel, Integer> {

    // 注解name要和实体类里的@NamedStoredProcedureQuery.name完全一致
    @Procedure(name = "LoginModel.do_login")
    Map<String, Object> executeLogin(
        @Param("in_user_id") String userId,
        @Param("in_password") String password
    );
}

3. 调整Controller逻辑,处理存储过程返回结果

注入Repository后,调用存储过程,根据返回的out_code和out_message做跳转或错误提示:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import java.util.Map;

@Controller
public class LoginController {

    @Autowired
    private LoginRepository loginRepository;

    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public String doLogin(@ModelAttribute("webLoginForm") @Valid LoginModel loginModel, 
                          BindingResult bindingResult, Model model, Errors error) {
        // 先处理前端表单验证错误
        if (bindingResult.hasErrors() || error.hasErrors()) {
            return "login";
        }

        // 调用存储过程,获取返回的参数Map
        Map<String, Object> resultMap = loginRepository.executeLogin(loginModel.getUserid(), loginModel.getPassword());
        
        // 取出OUT参数
        Integer outCode = (Integer) resultMap.get("out_code");
        String outMessage = (String) resultMap.get("out_message");

        // 根据业务逻辑处理:假设out_code=0表示登录成功
        if (outCode != null && outCode == 0) {
            return "redirect:/dashboard"; // 跳转到仪表盘
        } else {
            // 把错误信息存入Model,在登录页展示
            model.addAttribute("errorMessage", outMessage);
            return "login";
        }
    }
}

4. 完善登录页的错误信息展示(以Thymeleaf为例)

在你的login.html里添加错误提示区域,用来显示存储过程返回的错误信息:

<!-- 放在登录表单上方或合适位置 -->
<div th:if="${errorMessage}" class="alert alert-danger">
    <strong>错误提示:</strong> <span th:text="${errorMessage}"></span>
</div>

5. 补充MySQL存储过程的完整逻辑

你的存储过程目前只处理了空用户ID的情况,建议补充完整的验证逻辑,比如:

CREATE PROCEDURE login(
    IN in_user_id varchar(100), 
    IN in_password varchar(100), 
    OUT out_code INT, 
    OUT out_message varchar(100)
) 
BEGIN 
    IF in_user_id IS NULL OR in_user_id = '' THEN 
        SET out_code = 1; 
        SET out_message = 'Please Enter Your First Name.'; 
    ELSEIF in_password IS NULL OR in_password = '' THEN
        SET out_code = 2;
        SET out_message = 'Please Enter Your Password.';
    ELSE
        -- 验证用户账号密码是否匹配
        SELECT COUNT(*) INTO @user_count FROM user WHERE user_id = in_user_id AND password = in_password;
        IF @user_count > 0 THEN
            SET out_code = 0;
            SET out_message = 'Login Success.';
        ELSE
            SET out_code = 3;
            SET out_message = 'Invalid User ID or Password.';
        END IF;
    END IF;
END;

内容的提问来源于stack exchange,提问作者Enamul Haque

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:26:31