MyBatis 示例之存储过程

存储过程在数据库中比较常见,虽然大多数存储过程比较复杂,但是使用 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='用户表';1234567891011 准备测试数据如下。

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');12 对应实体类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}1234567891011121314151617181920212223242526272829303132333435 建存储过程

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

第一个存储过程

根据用户 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 ;12345678910111213141516171819202122 创建XML方法

{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} )}1234567891011 在调用存储过程的方法中,我们需要把 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);1234567 因为我们这个存储过程没有返回值(不要和出参混淆),所以我们返回值类型使用 void,如果你把返回值设置为 SysUser或 List 也不会报错,但是任何时候返回值都是 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(); } }123456789101112131415 执行测试,输出如下日志:

DEBUG [main] - ==> Preparing: {call select_user_by_id( ?, ?, ?, ?, ?, ?, ? )} DEBUG [main] - ==> Parameters: 1(Long) 用户名:admin123 使用出参方式的时候,通常情况下我们会使用对象中的属性接收出参的值,或者使用Map 类型方法入参接收返回值。这两种情况下有很大的区别。当我们使用 POJO 对象接收出参时,我们必须保证所有出参在 POJO 中都有对应的属性存在,否则就会抛出类似“Could not set property 'xxx'”的错误,这是由于 POJO 对象中不存在出参对应的 setter 方法导致的。使用 Map 类型时就不需要必须存在该属性,当 Map 接收了存储过程的出参时,可以通过 Map 对象的 get("属性名") 方法获取出参的值。

错误提示

除了上面提到的错误外,当你在执行存储过程时,还可能会遇到下面的错误:

Parameter number x is not an OUT parameter

这个错误可能的原因是因为你调用的存储过程不存在,或者 MyBatis 中写的出参和数据库存储过程的出参对应不上而导致的。

一个程序员学习平台分享给你们,让你在实践中积累经验掌握原理。主要方向是JAVA工程师。如果你想拿高薪,想突破瓶颈,想跟别人竞争能取得优势的,想进BAT但是有担心面试不过的,可以加我的Java学习交流群:450936584

注:加群要求

1、大学学习的是Java相关专业,毕业后面试受挫,找不到对口工作可以 2、在公司待久了,现在过得很安逸,但跳槽时面试碰壁。需要在短时间内进修、跳槽拿高薪的 3、参加过线下培训后,知识点掌握不够深刻,就业困难,想继续深造 4、已经在Java相关部门上班的在职人员,对自身职业规划不清晰,混日子的 5、有一定的C语言基础,接触过java开发,想转行的 小号勿扰,不喜勿加

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: MyBatis是一种持久层框架,可以用来调用MySQL存储过程。使用MyBatis调用MySQL存储过程的步骤如下: 1.在MySQL数据库中创建存储过程。 2.在MyBatis的配置文件中配置存储过程调用语句。 3.在Java代码中使用MyBatis的API调用存储过程示例: 1. 创建存储过程 ``` DELIMITER $$ CREATE PROCEDURE get_student_by_id (IN p_student_id INT) BEGIN SELECT * FROM student WHERE id = p_student_id; END $$ DELIMITER ; ``` 2. 配置Mybatis ``` <select id="getStudentById" parameterType="int" statementType="CALLABLE"> {call get_student_by_id(#{studentId,jdbcType=INTEGER,mode=IN})} </select> ``` 3. 在Java代码中调用存储过程 ``` SqlSession sqlSession = sqlSessionFactory.openSession(); try { StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class); Student student = studentMapper.getStudentById(1); ... } finally { sqlSession.close(); } ``` 希望这对你有帮助。 ### 回答2: MyBatis一个非常流行的Java ORM框架,其优点在于它可以自定义SQL语句,更加精准地控制SQL操作。在项目开发中,有时需要调用MySQL存储过程。下面将详细介绍如何使用MyBatis调用存储过程。 首先,在MyBatis的Mapper.xml文件中定义存储过程调用。在这个文件中,你需要: 1. 定义一个`<select>`语句,用于调用存储过程并获取数据。 2. 设置存储过程的名称。 3. 传递存储过程的参数以及它们的数据类型。 下面是示例代码: ```xml <select id="callProcedure" statementType="CALLABLE" parameterType="hashmap" resultType="hashmap"> CALL procedure_name(#{param2,mode=IN,jdbcType=VARCHAR},#{param3,mode=IN,jdbcType=VARCHAR},#{results,mode=OUT,jdbcType=CURSOR,javaType=java.sql.ResultSet,resultMap=resultMap}) </select> ``` 其中,statementType属性设置为`CALLABLE`,表示这是一个调用存储过程的语句。parameterType属性表示参数类型。resultType属性表示存储过程返回的结果集类型。 上述代码中,`#{param2}`和`#{param3}`分别表示存储过程的两个输入参数。`#{results}`表示存储过程的输出参数,也就是结果集。 在这个示例中,我们默认结果集的类型为`ResultSet`,并将其映射到了另一个resultMap中。而`#{results, mode=OUT, jdbcType=CURSOR}`这个语句则告诉MyBatis将结果集的游标传递给数据库驱动程序。 这样,你就可以使用MyBatis调用MySQL存储过程了。在调用存储过程之前,你需要将存储过程的定义写入数据库中。这可以通过使用MySQL的命令行或者直接使用MySQL Workbench添加存储过程实现。 总结来说,要使用MyBatis调用MySQL存储过程,你需要定义用于调用存储过程的语句,并在其中设置存储过程的名称、参数和结果集类型等信息。除此之外,你还需要将存储过程定义写入数据库中,才能实现MyBatis和MySQL存储过程的联动。 ### 回答3: MyBatis 是一款主流的 ORM 框架,可以提供持久层的数据访问和对象映射的支持。在实际开发中,经常需要调用存储过程来完成一些业务操作,本文将介绍如何使用 MyBatis 调用 MySQL 存储过程。 首先,在 MySQL 中创建一个存储过程。例如,下面创建了一个存储过程,用来查询所有用户的信息: ``` DELIMITER // CREATE PROCEDURE get_all_users() BEGIN SELECT * FROM users; END // DELIMITER ; ``` 接下来,在 MyBatis 中定义一个接口,用来调用存储过程。例如: ``` public interface UserMapper { @Select("CALL get_all_users()") @Results({ @Result(property = "id", column = "id"), @Result(property = "name", column = "name"), @Result(property = "gender", column = "gender"), @Result(property = "age", column = "age"), @Result(property = "email", column = "email"), @Result(property = "phone", column = "phone"), @Result(property = "address", column = "address"), }) List<User> getAllUsers(); } ``` MyBatis 提供了 `@Select` 注解来执行 SQL 语句,包括调用存储过程。在查询所有用户的操作中,我们使用 `CALL` 关键字来调用 `get_all_users` 存储过程。 由于存储过程的返回结果不是一个表,而是一组输出参数,我们需要通过 `@Result` 注解来映射存储过程的输出参数到 Java 对象的属性上。在上述代码中,我们映射了 `id`、`name`、`gender`、`age`、`email`、`phone` 和 `address` 这七个字段。 最后,在我们的代码中调用该接口即可: ``` SqlSessionFactory sessionFactory = ...; try (SqlSession session = sessionFactory.openSession()) { UserMapper mapper = session.getMapper(UserMapper.class); List<User> users = mapper.getAllUsers(); // ... } ``` 总的来说,使用 MyBatis 调用 MySQL 存储过程非常简单。只需要定义接口,并使用 `@Select` 和 `@Result` 注解来执行存储过程和映射输出参数,即可完成该操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值