存储过程
前言
已经有大佬写了文章解读的很好了,在这里:传送门, 其实存储过程就相当于是把一些复杂的sql提前封装存储在数据库中, 并且可以设定自定义入参和出参 , 只需调用存储名即可. 也就类似于java中封装了一个方法, 只需要调用方法名即可 , 可以根据传参去执行逻辑并返回
正文
存储过程是一种在数据库中存储的预编译的程序,具有以下优点和缺点:
优点:
- 提高性能:存储过程在数据库服务器上进行预编译,可以减少网络传输的开销和数据库查询的执行时间,从而提高性能
- 重用性:存储过程可以被多个应用程序或用户重复调用,提供了代码的重用性,减少了重复编写相同逻辑的代码的工作量
- 安全性:通过存储过程,可以限制对数据库的直接访问,只允许通过存储过程执行特定的操作,提高了数据的安全性
- 简化复杂操作:存储过程可以包含复杂的业务逻辑和多个SQL语句,通过封装这些逻辑,可以简化应用程序的开发和维护工作
缺点:
- 学习和维护成本:存储过程需要使用特定的编程语法和数据库特定的存储过程语言,需要学习和掌握这些技术才能进行开发和维护
- 难以调试:存储过程的调试相对于应用程序来说更加困难,因为它们在数据库服务器上运行,无法像应用程序一样方便地进行调试和跟踪
- 限制跨数据库移植性:存储过程的语法和功能在不同的数据库系统中可能有所不同,因此,如果需要将应用程序迁移到不同的数据库系统,可能需要进行一些修改和调整
- 数据库依赖性:存储过程的逻辑是存储在数据库中的,这意味着应用程序与特定的数据库紧密耦合,难以在不同的数据库之间切换或迁移
下面是几个存储过程的创建案例, 在主体部分可以做很多东西 , 可以根据自定义的传参和出参做很多条件判断和执行语句
案例一:执行主体sql循环语句
--创建一个名为LoopExample的存储过程
CREATE PROCEDURE LoopExample()
--开始存储过程的主体
BEGIN
--声明一个名为i的整数类型变量,并将其初始值设置为0, 每次执行+1, 循环十遍执行
DECLARE i INT DEFAULT 0;
WHILE i < 10 DO
SET i = i + 1;
--要循环执行的sql主体
select name from study1 LIMIT 1;
--结束循环体
END WHILE;
--结束存储过程的主体
END;
--调用名为LoopExample的存储过程
CALL LoopExample();
--删除名为LoopExample的存储过程
drop PROCEDURE LoopExample;
案例二:根据传参执行指定语句, 然后赋值给出参变量
--开始创建存储过程
-- 解释一下, INTO customer_name 这部分指定了结果将被存储在名为"customer_name"的变量中。查询的结果将被赋值给这个变量
CREATE PROCEDURE get_customer_details(IN customer_id INT, OUT customer_name VARCHAR(255))
BEGIN
SELECT name INTO customer_name FROM study1 WHERE id = customer_id;
END;
--调用存储过程
CALL get_customer_details(1, @name);
--查出变量的值
SELECT @name;
下面是一个简单的示例,演示了如何在MyBatis Plus中使用存储过程:
- 创建存储过程:
CREATE PROCEDURE GetUserInfo(IN userId INT, OUT userName VARCHAR(50))
BEGIN
SELECT name INTO userName FROM users WHERE id = userId;
END;
- 创建自定义Mapper接口:
import org.apache.ibatis.annotations.Param;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface UserMapper extends BaseMapper<User> {
void getUserInfo(@Param("userId") int userId, @Param("userName") String userName);
}
- 在Mapper XML文件中编写存储过程调用的SQL语句:
<!-- UserMapper.xml -->
<mapper namespace="com.example.UserMapper">
<select id="getUserInfo" statementType="CALLABLE">
{CALL GetUserInfo(#{userId, mode=IN}, #{userName, mode=OUT, jdbcType=VARCHAR})}
</select>
</mapper>
- 在Java代码中调用存储过程:
@Autowired
private UserMapper userMapper;
public void executeStoredProcedure(int userId) {
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("userId", userId);
userMapper.getUserInfo(paramMap);
String userName = (String) paramMap.get("userName");
System.out.println("User Name: " + userName);
}