MyBatis 示例之存储过程(二)

版权声明:版权归博主所有,转载请带上本文链接!联系方式:abel533@gmail.com https://blog.csdn.net/isea533/article/details/77148552

在开始阅读本篇前,建议先看前一篇:

MyBatis 示例之存储过程(一)
http://blog.csdn.net/isea533/article/details/76358365

本示例是《MyBatis 从入门到精通》书中第二个存储过程的例子,有关本示例的基础环境,可以从 http://mybatis.tk 或者 https://github.com/mybatis-book/book 获取,示例源码在 simple-all 中。

存储过程在数据库中比较常见,虽然大多数存储过程比较复杂,但是使用 MyBatis 调用时,用法都一样,因此我们这一节使用一个简单的存储过程来了解 MyBatis 中存储过程的使用方法。

基本准备

参考 MyBatis 示例之存储过程(一) 中的内容。

建存储过程

我们先创建如下的存储过程。

# 第二个存储过程
# 简单的根据用户名和分页参数进行查询,返回总数和分页数据
DROP PROCEDURE IF EXISTS `select_user_page`;
DELIMITER ;;
CREATE PROCEDURE `select_user_page`(
IN userName VARCHAR(50), 
IN _offset BIGINT, 
IN _limit BIGINT, 
OUT total BIGINT)
BEGIN
# 查询数据总数
select count(*) INTO total 
from sys_user 
where user_name like concat('%', userName, '%');
# 分页查询数据
select * 
from sys_user 
where user_name like concat('%', userName, '%')
limit _offset, _limit;
END
;;
DELIMITER ;

创建XML方法

<select id="selectUserPage" statementType="CALLABLE" useCache="false" resultMap="userMap">
    {call select_user_page(
        #{userName, mode=IN},
        #{offset, mode=IN},
        #{limit, mode=IN},
        #{total, mode=OUT, jdbcType=BIGINT}
    )}
</select>

第二个存储过程除了出参 total 外,还有返回值,所以 select 标签设置了返回值类型 resultMapuserMap 如下:

<resultMap id="userMap" type="tk.mybatis.simple.model.SysUser">
    <id property="id" column="id"/>
    <result property="userName" column="user_name"/>
    <result property="userPassword" column="user_password"/>
    <result property="userEmail" column="user_email"/>
    <result property="userInfo" column="user_info"/>
    <result property="headImg" column="head_img" jdbcType="BLOB"/>
    <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
</resultMap>

创建接口

/**
 * 使用存储过程分页查询
 * 
 * @param userName
 * @param pageNum
 * @param pageSize
 * @param total
 * @return
 */
List<SysUser> selectUserPage(Map<String, Object> params);

由于我们需要多个入参和一个出参,入参中除了 userName 属性在 SysUser 中外,其他 3 个参数都和 SysUser 无关,如果为了使用 SysUser 增加 3 个属性也可以。这里为了方法的多样化,也为了印证上一个方法中关于 Map 的用法,我们这里使用了 Map 类型作为参数。

编写测试

@Test
public void testSelectUserPage(){
    SqlSession sqlSession = getSqlSession();
    try {
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("userName", "ad");
        params.put("offset", 0);
        params.put("limit", 10);
        List<SysUser> userList = userMapper.selectUserPage(params);
        Long total = (Long) params.get("total");
        System.out.println("总数:" + total);
        for(SysUser user : userList){
            System.out.println("用户名:" + user.getUserName());
        }
    } finally {
        sqlSession.close();
    }
}

在我们测试代码的 Map 参数中不存在 total,在我们执行了存储过程方法后,通过 get 方法得到了 total 的值。上面测试代码的输出日志如下:

DEBUG [main] - ==>  Preparing: {call select_user_page( ?, ?, ?, ? )} 
DEBUG [main] - ==> Parameters: ad(String), 0(Integer), 10(Integer)
TRACE [main] - <==    Columns: id, user_name, user_password, user_email, user_info, head_img, create_time
TRACE [main] - <==        Row: 1, admin, 123456, admin@mybatis.tk, <<BLOB>>, <<BLOB>>, 2016-06-07 01:11:12.0
DEBUG [main] - <==      Total: 1
DEBUG [main] - <==    Updates: 0
总数:1
用户名:admin

为了更有效的测试这个分页查询的存储过程,你可以往数据库中增加大量数据进行测试。

阅读更多

扫码向博主提问

isea533

博客专家

MyBatis相关答疑
  • 擅长领域:
  • MyBatis
  • Spring Boo
  • Spring
去开通我的Chat快问
换一批

没有更多推荐了,返回首页