【Java】【Mybatis】如何调用存储过程和存储函数

https://www.jb51.net/article/230756.htm

Mybatis调用存储过程

MyBatis支持使用存储过程的配置。当使用存储过程时,需要设置一个参数“mode”,其值有IN(输入参数)、OUT(输出参数)和INOUT(输入/输出参数)。

Mybatis定义存储过程如下:

<!-- 存储过程 -->
<select id="selectSomeThing" statementType="CALLABLE" parameterType="hashmap" resultType="com.pjb.mybatis.po.User">
    {CALL PROC_FOR_INPUT(#{information,mode=IN,jdbcType=VARCHAR})}
</select>

示例1

创建存储过程,实现分页查询用户列表,并返回数据总数和总页数,通过MyBatis调用该存储过程。

(1)在MySQL数据库中创建用户信息表(tb_user)。

-- 创建“用户信息”数据表
CREATE TABLE IF NOT EXISTS tb_user
( 
    id INT AUTO_INCREMENT PRIMARY KEY COMMENT '用户编号',
    user_name VARCHAR(50) NOT NULL COMMENT '用户姓名',
    sex CHAR(2) DEFAULT '' COMMENT '性别'
) COMMENT = '用户信息表';

(2)创建存储过程,实现分页查询用户列表,并返回数据总数和总页数。

 1 -- 将结束标志符更改为$$
 2 DELIMITER $$
 3  
 4 /*
 5   -- 存储过程:分页查询用户列表,并返回数据总数和总页数
 6   -- 输入参数:page_index:当前页码
 7   -- 输入参数:page_size:分页大小
 8   -- 输出参数:total_count:数据总数
 9   -- 输出参数:total_page:总页数
10 */
11 CREATE PROCEDURE proc_search_user(IN page_index INT,IN page_size INT, OUT total_count INT, OUT total_page INT)
12 BEGIN
13     DECLARE begin_no INT;
14     SET begin_no = (page_index-1)*page_size;
15  
16     -- 分页查询列表
17     SELECT * FROM tb_user
18     WHERE id >= (
19         SELECT id FROM tb_user
20         ORDER BY id ASC
21         LIMIT begin_no,1
22     )
23     ORDER BY id ASC
24     LIMIT page_size;
25  
26     -- 计算数据总数
27     SELECT COUNT(1) INTO total_count FROM tb_user;
28  
29     -- 计算总页数
30     SET total_page = FLOOR((total_count + page_size - 1) / page_size);
31 END$$
32  
33 -- 将结束标志符更改回分号
34 DELIMITER ;
proc_search_user

(3)创建用户信息持久化类(User.java)。

 1 package com.pjb.mybatis.po;
 2  
 3 /**
 4  * 用户信息的持久化类
 5  * @author pan_junbiao
 6  **/
 7 public class User
 8 {
 9     private int id; //用户编号
10     private String userName; //用户姓名
11     private String sex; //性别
12  
13     //省略getter与setter方法...
14 }

(4)编写SQL映射配置。

1 <!-- 存储过程:分页查询用户列表,并返回数据总数和总页数 -->
2 <select id="proc_search_user" statementType="CALLABLE" parameterType="hashmap" resultType="com.pjb.mybatis.po.User">
3     {CALL proc_search_user(#{page_index,mode=IN,jdbcType=INTEGER},
4       #{page_size,mode=IN,jdbcType=INTEGER},
5       #{total_count,mode=OUT,jdbcType=INTEGER},
6       #{total_page,mode=OUT,jdbcType=INTEGER})}
7 </select>

(5)编写执行方法。

 1 /**
 2  * 使用MyBatis调用存储过程:分页查询用户列表,并返回数据总数和总页数
 3  * @author pan_junbiao
 4  */
 5 @Test
 6 public void procSearchUser()
 7 {
 8     DataConnection dataConnection = new DataConnection();
 9     SqlSession sqlSession = dataConnection.getSqlSession();
10     //封装查询参数
11     Map params = new HashMap();
12     params.put("page_index",2);  //输入参数:当前页码
13     params.put("page_size",10);  //输入参数:分页大小
14     params.put("total_count",0); //输出参数:数据总数
15     params.put("total_page",0);  //输出参数:总页数
16     //调用存储过程
17     List<User> userList = sqlSession.selectList("test.proc_search_user",params);
18     System.out.println("查询第"+ params.get("page_index") +"页的数据,每页共"+params.get("page_size")+"条数据");
19     //遍历用户列表
20     for (User user : userList)
21     {
22         System.out.println("编号:" + user.getId() +" 姓名:" + user.getUserName() + " 性别:" + user.getSex());
23     }
24     //获取输出参数
25     System.out.println("数据总数:" + params.get("total_count"));
26     System.out.println("总页数:" + params.get("total_page"));
27     sqlSession.close();
28 }
procSearchUser

示例2

创建存储过程,实现新增用户信息,并返回自增主键,通过MyBatis调用该存储过程

(1)创建存储过程。

 1 -- 将结束标志符更改为$$
 2 DELIMITER $$
 3  
 4 /*
 5   -- 存储过程:新增用户信息,返回自增主键
 6   -- 输入参数:user_name:用户姓名
 7   -- 输入参数:sex:性别
 8   -- 输出参数:user_id:自增主键
 9 */
10 CREATE PROCEDURE proc_add_user(IN user_name VARCHAR(50),IN sex CHAR(2), OUT user_id INT)
11 BEGIN
12     -- 新增用户
13     INSERT INTO tb_user(user_name,sex) VALUE (user_name,sex);
14     
15     -- 获取自增主键
16     SELECT LAST_INSERT_ID() INTO user_id;
17 END$$
18  
19 -- 将结束标志符更改回分号
20 DELIMITER ;
proc_add_user

(2)编写SQL映射配置。

1 <!-- 存储过程:新增用户信息,返回自增主键 -->
2 <insert id="proc_add_user" statementType="CALLABLE" parameterType="com.pjb.mybatis.po.User">
3   {CALL proc_add_user(#{userName,mode=IN,jdbcType=VARCHAR},
4     #{sex,mode=IN,jdbcType=CHAR},
5     #{id,mode=OUT,jdbcType=INTEGER})}
6 </insert>

(3)编写执行方法。

 1 /**
 2  * 使用MyBatis调用存储过程:新增用户信息,返回自增主键
 3  * @author pan_junbiao
 4  */
 5 @Test
 6 public void procAddUser()
 7 {
 8     DataConnection dataConnection = new DataConnection();
 9     SqlSession sqlSession = dataConnection.getSqlSession();
10     //新增的用户对象
11     User user = new User();
12     user.setUserName("pan_junbiao的博客");
13     user.setSex("男");
14     //调用存储过程执行新增
15     int reuslt = sqlSession.insert("test.proc_add_user",user);
16     sqlSession.commit();
17     //打印结果
18     System.out.println("执行结果:"+reuslt);
19     System.out.println("自增主键:"+user.getId());
20     sqlSession.close();
21 }

执行结果:

  其实,新增数据后,获取自增主键是可以使用MyBatis提供的<selectKey>标签,SQL映射配置如下:

1 <!-- 存储过程:新增用户信息,返回自增主键 -->
2 <insert id="proc_add_user" statementType="CALLABLE" parameterType="com.pjb.mybatis.po.User">
3   <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
4       SELECT LAST_INSERT_ID()
5   </selectKey>
6   {CALL proc_add_user(#{userName,mode=IN,jdbcType=VARCHAR},
7     #{sex,mode=IN,jdbcType=CHAR})}
8 </insert>

但上述示例是为了能让该存储过程拥有一个返回的参数。

MyBatis 调用存储过程

【示例2】

创建存储函数,根据用户编号,获取用户名称,通过MyBatis调用该存储函数。

(1)创建存储函数,根据用户编号,获取用户名称。

 1 -- 将结束标志符更改为$$
 2 DELIMITER $$
 3  
 4 /*
 5   -- 存储函数:根据用户编号,获取用户名称
 6   -- 输入参数:in_id:用户编号
 7   -- 返回结果:用户名称
 8 */
 9 CREATE FUNCTION func_get_user_name(in_id INT)
10 RETURNS VARCHAR(50)
11 BEGIN
12     -- 定义返回变量
13     DECLARE out_name VARCHAR(50);
14  
15     -- 查询用户信息,获取用户名称
16     SELECT user_name INTO out_name FROM tb_user WHERE id = in_id;
17  
18     -- 返回结果
19     RETURN out_name;
20 END$$
21  
22 -- 将结束标志符更改回分号
23 DELIMITER ;
func_get_user_name

(2)编写SQL映射配置。

1 <!-- 存储函数:根据用户编号,获取用户名称 -->
2 <select id="func_get_user_name" statementType="CALLABLE" parameterType="hashMap" >
3     {#{userName,mode=OUT,jdbcType=VARCHAR} = CALL func_get_user_name(#{userId,mode=IN,jdbcType=INTEGER})}
4 </select>

(3)编写执行方法。

 1 /**
 2  * 使用MyBatis调用存储函数:根据用户编号,获取用户名称
 3  * @author pan_junbiao
 4  */
 5 @Test
 6 public void funcGetUserName()
 7 {
 8     DataConnection dataConnection = new DataConnection();
 9     SqlSession sqlSession = dataConnection.getSqlSession();
10     //封装参数
11     Map userMap = new HashMap();
12     userMap.put("userName","");
13     userMap.put("userId",8);
14     sqlSession.selectOne("test.func_get_user_name",userMap);
15     System.out.println("用户名称:" + userMap.get("userName"));
16     sqlSession.close();
17 }
posted @ 2022-12-07 19:21  陆陆无为而治者  阅读(1857)  评论(0编辑  收藏  举报