MyBatis学习笔记(7)------存储过程
MyBatis调用存储过程
在调用存储过程的方法中,需要把 statementType 设置为 CALLABLE,在使用 select 标签调用存储过程时,由于存储过程方式不支持 MyBatis 的二级缓存,因此将 userCache 属性设置为 false。
在存储过程中使用参数时,除了属性名,还必须指定参数的 mode,可选值为
- IN:入参
- OUT:出参
- INOUT:输入输出参数
OUT 模式的参数必须指定 jdbcType ,因为在 IN 模式下,MyBatis 提供了默认的 jdbcType 。
在 Oracle 数据库中,如果入参存在 null 的情况,那么入参也必须指定 jdbcType。
数据库的 BLOB 类型对应的 Java 类型通常写成 byte[] 字节数组的形式。
由于 byte 是基本类型,所以设置 javaType 时要使用带下划线的方式: _byte[] 或 _byte。
使用出参方式时,可以使用对象中的属性接参,也可以使用 Map 类型接收返回值。当使用 JavaBean 对象接收出参时,必须保证所有出参在 JavaBean 中都有对应的属性存在;使用 Map 类型时就不需要保证所有出参都有对应的属性,可以通过 Map 对象的 get(“属性名”) 方法获取出参的值。
示例一:
存储过程:
CREATE DEFINER=`root`@`localhost` PROCEDURE `select_user_by_id`(
IN `userId` bigint,
OUT `userName` varchar(50),
OUT `userPassword` varchar(50),
OUT `userInfo` varchar(50),
OUT `createTime` datetime)
BEGIN
#根据用户id查询用户信息
SELECT user_name,user_password,user_info,create_time
INTO userName,userPassword,userInfo,createTime
FROM sys_user
where id = userId;
END
XML:
<select id="selectUserById" statementType="CALLABLE" useCache="false">
{call select_user_by_id(
#{id, mode=IN},
#{userName, mode=OUT, jdbcType=VARCHAR},
#{userPassword, mode=OUT, jdbcType=VARCHAR},
#{userInfo, mode=OUT, jdbcType=VARCHAR},
#{createTime, mode=OUT, jdbcType=TIMESTAMP}
)}
</select>
这个存储过程没有返回值只有出参。
示例二:
存储过程:
//分页按userName模糊查询
CREATE DEFINER=`root`@`localhost` 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
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>
Mapper 接口:
/**
* 使用存储过程分页查询
* @param userName
* @param pageNum
* @param pageSize
* @param total
* @return
*/
List<SysUser> selectUserPage(Map<String, Object> params);
测试方法:
@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", 5);
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());
System.out.println("密码:" + user.getUserPassword());
}
} finally {
// TODO: handle finally clause
sqlSession.close();
}
}