MyBatis 示例之存储过程(一)
来源:互联网 发布:怎么看淘宝店铺的收支 编辑:程序博客网 时间:2024/06/03 14:59
本示例是《MyBatis 从入门到精通》书中第一个存储过程的例子,有关本示例的基础环境,可以从 http://mybatis.tk 或者 https://github.com/mybatis-book/book 获取,示例源码在 simple-all 中。
存储过程在数据库中比较常见,虽然大多数存储过程比较复杂,但是使用 MyBatis 调用时,用法都一样,因此我们这一节使用一个简单的存储过程来了解 MyBatis 中存储过程的使用方法。
基本准备
存储过程涉及表 sys_user,建表语句如下。
DROP TABLE IF EXISTS `sys_user`;CREATE TABLE `sys_user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '用户ID', `user_name` varchar(50) DEFAULT NULL COMMENT '用户名', `user_password` varchar(50) DEFAULT NULL COMMENT '密码', `user_email` varchar(50) DEFAULT 'test@mybatis.tk' COMMENT '邮箱', `user_info` text COMMENT '简介', `head_img` blob COMMENT '头像', `create_time` datetime DEFAULT NULL COMMENT '创建时间', PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=1035 DEFAULT CHARSET=utf8 COMMENT='用户表';
准备测试数据如下。
INSERT INTO `sys_user` VALUES ('1', 'admin', '123456', 'admin@mybatis.tk', '管理员用户', 0x1231231230, '2016-06-07 01:11:12');INSERT INTO `sys_user` VALUES ('1001', 'test', '123456', 'test@mybatis.tk', '测试用户', 0x1231231230, '2016-06-07 00:00:00');
对应实体类SysUser
如下:
/** * 用户表 */public class SysUser implements Serializable { private static final long serialVersionUID = 1L; /** * 用户ID */ private Long id; /** * 用户名 */ private String userName; /** * 密码 */ private String userPassword; /** * 邮箱 */ private String userEmail; /** * 简介 */ private String userInfo; /** * 头像 */ private byte[] headImg; /** * 创建时间 */ private Date createTime; //省略 getter 和 setter}
建存储过程
我们先创建如下的存储过程。
# 第一个存储过程# 根据用户 id 查询用户其他信息# 方法看着很奇葩,但是展示了多个输出参数DROP PROCEDURE IF EXISTS `select_user_by_id`;DELIMITER ;;CREATE PROCEDURE `select_user_by_id`(IN userId BIGINT,OUT userName VARCHAR(50),OUT userPassword VARCHAR(50),OUT userEmail VARCHAR(50),OUT userInfo TEXT,OUT headImg BLOB,OUT createTime DATETIME)BEGIN# 根据用户 id 查询其他数据select user_name,user_password,user_email,user_info,head_img,create_timeINTO userName,userPassword,userEmail,userInfo,headImg,createTime from sys_userWHERE id = userId;END;;DELIMITER ;
创建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}, #{userEmail, mode=OUT, jdbcType=VARCHAR}, #{userInfo, mode=OUT, jdbcType=VARCHAR}, #{headImg, mode=OUT, jdbcType=BLOB, javaType=_byte[]}, #{createTime, mode=OUT, jdbcType=TIMESTAMP} )}</select>
在调用存储过程的方法中,我们需要把 statementType
设置为 CALLABLE
,在使用 select
元素中调用存储过程时,由于存储过程方式不支持 MyBatis 的二级缓存(后面章节会介绍),为了避免缓存配置导致出错,我们直接将 select
元素的 useCache
属性设置为 false
。
在存储过程中使用参数时,除了写上必要的属性名外,还必须指定参数的 mode
(模式),可选值为 IN、OUT、INOUT 三种,入参使用 IN,出参使用 OUT,输入输出参数使用 INOUT。从上面代码可以轻易看出 IN 和 OUT 的两种模式的区别,那就是 OUT 模式的参数,必须指定 jdbcType。这是因为在 IN 模式下,MyBatis 提供了默认的 jdbcType
,在 OUT 模式下没有提供,因此必须指定 jdbcType
,另外在使用 Oracle 数据库时,如果入参存在 null 的情况,那么也必须指定 jdbcType
。
除了上面提到的这几点外,headImg
还特别设置了 javaType
。在 MyBatis 映射的 Java 类中我们都不推荐使用基本类型,但是数据库 BLOB 类型对应的 Java 类型我们通常都是写成 byte[] 字节数组,因为 byte[] 数组不会有默认值的问题,所以不会影响我们一般的使用。但是在不指定 javaType
的情况下,MyBatis 默认使用 Byte
类型。由于我们使用的 byte
是基本类型,所以设置 javaType
的时候,基本类型要使用带下划线方式的类型,在这里就是 byte[]
,_byte
对应的是基本类型,byte
对应的是 Byte
类型,在使用 javaType
时一定要注意。
创建接口
/** * 使用存储过程查询用户信息 * * @param user * @return */void selectUserById(SysUser user);
因为我们这个存储过程没有返回值(不要和出参混淆),所以我们返回值类型使用 void,如果你把返回值设置为 SysUser
或 List<SysUser>
也不会报错,但是任何时候返回值都是 null
。
编写测试
@Testpublic void testSelectUserById(){ SqlSession sqlSession = //获取SqlSession的方法 try { //这个例子的XML和接口都定义在UserMapper中 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); SysUser user = new SysUser(); user.setId(1L); userMapper.selectUserById(user); Assert.assertNotNull(user.getUserName()); System.out.println("用户名:" + user.getUserName()); } finally { sqlSession.close(); }}
执行测试,输出如下日志:
DEBUG [main] - ==> Preparing: {call select_user_by_id( ?, ?, ?, ?, ?, ?, ? )} DEBUG [main] - ==> Parameters: 1(Long)用户名:admin
使用出参方式的时候,通常情况下我们会使用对象中的属性接收出参的值,或者使用 Map
类型方法入参接收返回值。这两种情况下有很大的区别。当我们使用 POJO 对象接收出参时,我们必须保证所有出参在 POJO 中都有对应的属性存在,否则就会抛出类似 “Could not set property 'xxx'”
的错误,这是由于 POJO 对象中不存在出参对应的 setter 方法导致的。使用 Map 类型时就不需要必须存在该属性,当 Map 接收了存储过程的出参时,可以通过 Map
对象的 get("属性名")
方法获取出参的值。
错误提示
除了上面提到的错误外,当你在执行存储过程时,还可能会遇到下面的错误:
Parameter number x is not an OUT parameter
这个错误可能的原因是因为你调用的存储过程不存在,或者 MyBatis 中写的出参和数据库存储过程的出参对应不上而导致的。
- MyBatis 示例之存储过程(一)
- MyBatis 示例之存储过程(二)
- MyBatis 示例之存储过程(三)
- MyBatis 示例之存储过程
- MyBatis示例---存储过程
- mybatis调用存储过程 示例
- Mybatis之-调用存储过程
- ORACLE存储过程(一)之初次见面
- Mybatis基础操作之存储过程
- MyBatis学习之调用存储过程
- mybatis基础操作之存储过程
- MySQL之存储过程(一)
- 存储过程(一)
- 存储过程(一)
- 存储过程(一)
- 存储过程(一)
- 存储过程(一)
- 【Mybatis学习】Mybatis学习之调用Mysql存储过程(1传入2输出)
- HDU
- Shell脚本的学习&&sed
- 马拦过河卒
- hdu1695 GCD
- NYISTSWOJ 5864 题目不详(好坑的题...)
- MyBatis 示例之存储过程(一)
- Linux的三个时间参数
- linux中的日志服务
- linux卸载openjdk
- 莫比乌斯函数模版
- 4. 对象的组合
- 华为机试——句子逆序
- AJAX简介
- 第一章人工智能之机器学习算法体系汇总