MyBatis调用MySQL存储过程
Posted 旅行的Java
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MyBatis调用MySQL存储过程相关的知识,希望对你有一定的参考价值。
mysql存储过程
先写2个mysql存储过程
1.建表语句DDL
CREATE TABLE `sys_user` (
`user_id` varchar(32) NOT NULL COMMENT '主键',
`real_name` varchar(64) DEFAULT NULL COMMENT '真实名称',
`user_name` varchar(64) NOT NULL COMMENT '用户名',
`password` varchar(64) DEFAULT NULL COMMENT '密码',
`email` varchar(20) DEFAULT NULL COMMENT '邮件',
`phone` varchar(20) DEFAULT NULL COMMENT '联系电话',
`create_by` varchar(32) DEFAULT NULL,
`create_date` datetime DEFAULT NULL,
`update_by` varchar(32) DEFAULT NULL,
`update_date` datetime DEFAULT NULL,
`remarks` varchar(255) DEFAULT NULL,
`del_flag` char(1) DEFAULT 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(1) INTO 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存储过程的主要内容,如果未能解决你的问题,请参考以下文章
使用mybatis查询mysql数据库 先调用存储过程,然后再inner join 存储过程返回的临时表出错 高手帮忙看下!