Mysql存储过程知识点总结+Mybatisplus调用存储过程案例实现

Posted 温文艾尔

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mysql存储过程知识点总结+Mybatisplus调用存储过程案例实现相关的知识,希望对你有一定的参考价值。

mysql存储过程知识点总结+存储过程调用案例实现


一、存储过程

MySQL 5.0版本开始支持存储过程

**存储过程(Stored Procedure)**是一种在数据库中存储复杂程序,以便外部程序调用的一种数据库对象。

存储过程是为了完成特定功能的SQL语句集,经编译创建并保存在数据库中,用户可通过指定存储过程的名字并给定参数来调用执行。

存储过程思想上很简单,就是数据库SQL语言层面的代码封装与重用,通俗来讲存储过程其实就是能完成一定操作的一组SQL语句

二、存储过程的优缺点

优点

  • 存储过程可封装,并隐藏复杂的商业逻辑。
  • 存储过程可以回传值,并可以接受参数。
  • 存储过程无法使用SELECT指令来运行,因为他是子程序,与查看表,数据表或用户定义函数不同。
  • 存储过程可以用在数据校验,强制实行商业逻辑等。

缺点

  • 存储过程,往往定制化于特定的数据库上,因为支持的编程语言的不同。当切换到其他产商的数据库系统时,需要重写原有的存储过程
  • 存储过程的性能调校于撰写,受限于各种数据库系统

三、存储过程的创建与调用

  • 存储过程就是具有名字的一段代码,用来完成一个特定的功能
  • 创建的存储过程保存在数据库的数据字典中

1.创建存储过程:

CREATE 
	[DEFINER = {user| CURRENT_USER }]
	PROCEDURE sp_name ([proc_parameter[....]])
	[characteristic ...] routine_body
[begin_lavle:]
	BEGIN
	[statement_list]
	
	END [end_label]


	
proc_parameter:
	[IN | OUT | INOUT ] param_name type 三种类型

routine_body:校验SQL运行时的一些参数
	valid SQL routine statement
	

## 2.Mysql存储过程的关键语法: **声明语句结束符**
DELIMITER $$
或
DELIMITER //
在mysql8.0之后的版本也可直接用;结尾

声明存储过程:

CREATE PROCEDURE demo_in_oarameter(IN p_in int)

存储过程开始与结束符号

BEGIN .... END

变量赋值

SET @p_in=1

变量定义

DECLARE l_int int unsigned default 4000000

创建mysql存储过程,存储函数:

create procedure 存储过程名(参数)

存储过程体

create function 存储函数名(参数)

调用存储过程

call sp_name[(传参)]

四、存储过程的参数

MYSQL存储过程的参数用在存储过程的定义,共有三种参数类型,IN,OUT,INOUT,形式如:

CREATE PROCEDURE 存储过程名([[IN | OUT | INOUT] 参数名 数据类型...])
  • IN输入参数:表示调用者向过程传入值(传入值可以是字面量或变量)
  • OUT输出参数:表示过程向调用者传出值(可以返回多个值)(传出值只能是变量)
  • INOUT输入输出参数:既表示调用者向过程传入值,又表示过程向调用者传出值(值只能是变量)

注意:
1.如果存储过程没有参数,也必须在过程名后面写上小括号

CREATE PROCEDURE sp_name ([proc_parameter[....]])

2.确保参数的名字不等于列的名字,否则在过程体中,参数名被当做列名来处理
建议:

  • 输入值使用in参数
  • 返回值使用out参数
  • inout参数尽量少用

变量定义:
局部变量声明一定要放在存储过程的开始:

DECLARE variable_name [,varible_name...] datatype [DEFAULT value]

变量赋值:

x SET 变量名 = 表达式值 [,varible_name = expression...]

五、MybatisPlus调用存储过程

表数据
部门表t_department
在这里插入图片描述
增加部门信息我们可以写一个存储过程
完成下列几步操作:

1.插入自己指定的部门信息

2.查找插入之后部门的id

3.查找父部门的deppath

4.对自己的deppath进行更新

5.父部门的isParent更新为1 ```

存储过程MyaddDep

USE `yeb`$$

DROP PROCEDURE IF EXISTS `MyAddDep`$$

CREATE DEFINER=`root`@`localhost` PROCEDURE `MyAddDep`(IN depName VARCHAR(32),IN parentId INT,IN enabled BOOLEAN,OUT result INT,OUT result2 INT)
BEGIN
	DECLARE did INT;
	DECLARE parPath VARCHAR(64);
	-- 1.插入自己指定的部门信息
	INSERT INTO t_department SET NAME=depName,parentId=parentId,enabled=enabled;
	SELECT ROW_COUNT() INTO result; -- result为插入语句作用的行数
	-- 2.查找插入之后部门的id
	SELECT LAST_INSERT_ID() INTO did; -- did现在是插入部门信息的id
	SET result2=did;
	-- 3.查找父部门的depPath
	SELECT depPath INTO parPath FROM t_department WHERE id=parentId;
	-- 4.对自己的deppath进行更新
	UPDATE t_department SET depPath=CONCAT(parPath,'.',did) WHERE id=did;
	-- 5.父部门的isParent更新为1
	UPDATE t_department SET isParent=TRUE WHERE id=parentId;
END$$

DELIMITER ;

controller

package com.wql.server.controller;


import com.wql.server.pojo.Department;

import com.wql.server.pojo.RespBean;
import com.wql.server.service.IDepartmentService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author wql
 * @since 2021-05-03
 */
@RestController
@RequestMapping("/system/basic/department")
public class DepartmentController {

    @Autowired
    IDepartmentService departmentService;

    @ApiOperation("增加部门信息")
    @PutMapping("/")
    public RespBean addDep(@RequestBody  Department department){
        return departmentService.addDep(department);
    }
}

DepartmentServiceImpl

package com.wql.server.service.impl;


import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wql.server.mapper.DepartmentMapper;
import com.wql.server.pojo.Department;
import com.wql.server.pojo.RespBean;
import com.wql.server.service.IDepartmentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author wql
 * @since 2021-05-03
 */
@Service
public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Department> implements IDepartmentService {


    @Autowired
    DepartmentMapper departmentMapper;


    /**
     *增加部门信息
     * @param department
     * @return
     */
    @Override
    public RespBean addDep(Department department) {
        department.setEnabled(true);
        //存储过程的返回值存储在result中
        departmentMapper.addDep(department);
        int result = department.getResult();
        if(result==1){
            return RespBean.success("添加成功",department);
        }
        return RespBean.error("添加失败");
    }
}

Mapper

package com.wql.server.mapper;


import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wql.server.pojo.Department;
import com.wql.server.pojo.RespBean;

import java.util.List;

/**
 * <p>
 *  Mapper 接口
 * </p>
 *
 * @author wql
 * @since 2021-05-03
 */
public interface DepartmentMapper extends BaseMapper<Department> {


    void addDep(Department department);
}

Mapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wql.server.mapper.DepartmentMapper">

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.wql.server.pojo.Department">
        <id column="id" property="id" />
        <result column="name" property="name" />
        <result column="parentId" property="parentId" />
        <result column="depPath" property="depPath" />
        <result column="enabled" property="enabled" />
        <result column="isParent" property="isParent" />
    </resultMap>
    
    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List">
        id, name, parentId, depPath, enabled, isParent
    </sql>

    <select id="addDep" statementType="CALLABLE">
        call addDep(#{name,mode=IN,jdbcType=VARCHAR},#{parentId,mode=IN,jdbcType=INTEGER},
         #{enabled,mode=IN,jdbcType=BOOLEAN},#{result,mode=OUT,jdbcType=INTEGER},#{id,mode=OUT,jdbcType=INTEGER})
    </select>

</mapper>

调用解析:
在这里插入图片描述

STATEMENT:直接操作sql语句,不会去进行预处理的操作,获取数据要采用$符

PREPARED:预处理一些参数,可以进行预编译,获取数据采用#

CALLABLE:执行数据库中的存储过程

如果不指定的话默认为PREPARED

测试存储过程的调用是否成功
我们为财务部增加一个子部门:测试部门2
原来,isParent为0
在这里插入图片描述

在这里插入图片描述
增加测试部门2之后
在这里插入图片描述
depPath正确,isParent也变成了1,测试结束

以上是关于Mysql存储过程知识点总结+Mybatisplus调用存储过程案例实现的主要内容,如果未能解决你的问题,请参考以下文章

mysql存储过程知识点难学吗?

MySQL知识点总结

mysql 存储过程总结(一)

mysql基础总结

知识点:Mysql 基本用法之存储过程

MySQL基础知识和常用命令总结