MyBatis调用MySQL存储过程

Posted 旅行的Java

tags:

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

mysql存储过程

先写2个mysql存储过程
1.建表语句DDL

CREATE TABLE `sys_user` (
  `user_id` varchar(32NOT NULL COMMENT '主键',
  `real_name` varchar(64DEFAULT NULL COMMENT '真实名称',
  `user_name` varchar(64NOT NULL COMMENT '用户名',
  `password` varchar(64DEFAULT NULL COMMENT '密码',
  `email` varchar(20DEFAULT NULL COMMENT '邮件',
  `phone` varchar(20DEFAULT NULL COMMENT '联系电话',
  `create_by` varchar(32DEFAULT NULL,
  `create_date` datetime DEFAULT NULL,
  `update_by` varchar(32DEFAULT NULL,
  `update_date` datetime DEFAULT NULL,
  `remarks` varchar(255DEFAULT NULL,
  `del_flag` char(1DEFAULT NULL,
  PRIMARY KEY (`user_id`),
  UNIQUE KEY `idx_sys_user_username` (`user_name`),
  UNIQUE KEY `idx_sys_user_email` (`email`),
  UNIQUE KEY `idx_sys_user_phone` (`phone`)
ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户信息表';

2.存储过程函数
(1)根据用户id查询用户信息

DROP PROCEDURE IF EXISTS `select_user_by_id`;
CREATE PROCEDURE `select_user_by_id`(IN userId VARCHAR (32),
    OUT realname VARCHAR (64),
    OUT username VARCHAR (64),
    OUT _email VARCHAR (20),
    OUT _phone VARCHAR (20),
    OUT _remarks VARCHAR (255),
    OUT createDate datetime)
BEGIN
    SELECT
        real_name,
        user_name,
        email,
        phone,
        remarks,
        create_date INTO realName,
        userName,
        _email,
        _phone,
        _remarks,
        createDate
    FROM
        sys_user
    WHERE
        user_id = userId;
END

在使用SELECT …INTO语句时,变量名和数据表中的字段名不能相同,否则接收到不到数据,笔者在测试时,如果出参_email、_phone、_remarks不加下划线(下划线在这里只是让出参和数据库表字段不一致),这三个值一直是null
(2)根据用户姓名模糊查询用户信息,返回总数和分页数据

DROP PROCEDURE IF EXISTS `select_user_page`;
CREATE  PROCEDURE `select_user_page`(IN `username` VARCHAR (64),
    IN `_offset` BIGINT,
    IN `_limit` BIGINT,
    OUT `total` BIGINT)
BEGIN
    SELECT
        count(1INTO total
    FROM
        sys_user
    WHERE
        user_name LIKE CONCAT('%', username, '%');

SELECT
    user_id AS userId,
    real_name AS realName,
    user_name AS userName,
    email,
    phone,
    create_by AS createBy,
    create_date AS createDate,
    update_by AS updateBy,
    update_date AS updateDate,
    remarks
FROM
    sys_user
WHERE
    user_name LIKE CONCAT('%', username, '%')
LIMIT _offset,
 _limit;
END

在存储过程中使用参数时,必须指定参数的mode(模式),可选的值为IN、OUT、INOUT。入参使用IN,出参使用OUT,输入输出参数用INOUT,OUT模式下必须指定jdbcType,这是因为在IN模式下,Mybatis提供了默认的jdbcType
3.mapper配置文件

<!-- 存储过程方式不支持mybatis的二级缓存 -->
    <select id="selectUserById" statementType="CALLABLE" useCache="false">
        {
            call select_user_by_id(
                #{userId,mode=IN},
                #{realname,mode=OUT,jdbcType=VARCHAR},
                #{username,mode=OUT,jdbcType=VARCHAR},
                #{email,mode=OUT,jdbcType=VARCHAR},
                #{phone,mode=OUT,jdbcType=VARCHAR},
                #{remarks,mode=OUT,jdbcType=VARCHAR},
                #{createDate,mode=OUT,jdbcType=TIMESTAMP}
            )
        }
    </select>
    <select id="selectUserPage" statementType="CALLABLE" useCache="false" 
        resultType="com.xiyue.mybatis.entity.SysUserEntity" >

        {
            call select_user_page(
                #{username,mode=IN},
                #{offset,mode=IN},
                #{limit,mode=IN},
                #{total,mode=OUT,jdbcType=BIGINT}
            )
        }
    </select>

4.测试方法

package com.xiyue.mybatis.main;
import java.io.IOException;
import java.io.Reader;
import java.util.HashMap;
import java.util.List;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import com.xiyue.mybatis.dao.SysUserDAO;
import com.xiyue.mybatis.entity.SysUserEntity;
public class TestProcedure {
    public static void main(String[] args) {
        /**
         * java 7增强了try语句的功能,圆括号可以声明、初始化一个或多个资源(必须在程序结束时显示关闭的资源)
         * try语句在该语句结束时会自动关闭这些资源
         */

        try (
            //读取配置文件信息
            Reader reader = Resources.getResourceAsReader("SqlMapConfig.xml");
            //参数为true,设置事务是自动提交
            SqlSession sqlSession = new SqlSessionFactoryBuilder().build(reader).openSession(true);
        ){
            SysUserDAO userMapper = sqlSession.getMapper(SysUserDAO.class);
            SysUserEntity aDTO = new SysUserEntity();
            aDTO.setUserId("40288ab85ce3c20a015ce3ca6df60000");
            userMapper.selectUserById(aDTO);
            System.out.println("============="+aDTO.toString());
            HashMap<String,Object> hashMap = new HashMap<String,Object>();
            hashMap.put("username""test");
            hashMap.put("offset"0);
            hashMap.put("limit"5);
            List<SysUserEntity> userPage = userMapper.selectUserPage(hashMap);
            Long total = (Long) hashMap.get("total");
            System.out.println("total==="+total);
            for (SysUserEntity userDTO : userPage) {
                System.out.println("============="+userDTO.toString());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

运行结果:

selectUserById这个存储过程没有返回值(不要和出参混淆,出参只是个变量),使用的是出参的方式来得到用户信息,使用出参方式时,通常会使用对象中的属性值接收出参的值,当使用JavaBean对象接收出参值时,字段必须要有setter方法。
selectUserPage这个存储过程有返回值,并且使用的是Map来接收出参的total值。


以上是关于MyBatis调用MySQL存储过程的主要内容,如果未能解决你的问题,请参考以下文章

12mybatis调用执行存储过程

mybatis怎么调用mysql数据库的存储过程

mybatis调用mysql存储过程返回多结果集(完整)

MyBatis调用MySQL存储过程

myBatis 调用 Oracle 存储过程,报错,求解答

使用mybatis查询mysql数据库 先调用存储过程,然后再inner join 存储过程返回的临时表出错 高手帮忙看下!