11.3 注解调用存储过程 项目结构 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 E:\workspace_web2 \MyAProcedureTest ├─src │ ├─db.properties │ ├─domain │ │ └─User.java │ ├─fractory │ │ └─SqlSessionFratoryTools.java │ ├─log4j.xml │ ├─mapper │ │ └─UserMapper.java │ ├─mybatis -config.xml │ ├─procedure.sql │ ├─tb_user.sql │ └─test │ ├─DeleteTest.java │ ├─InsertTest.java │ ├─SelectAllTest.java │ ├─SelectByIdTest.java │ └─UpdateTest.java └─WebContent ├─META -INF │ └─MANIFEST.MF └─WEB -INF └─lib ├─commons -logging -1.2.jar ├─log4j -1.2.17.jar ├─log4j -api -2.3.jar ├─log4j -core -2.3.jar ├─mybatis -3.4.5.jar └─mysql -connector -java -5.1.44-bin.jar
数据库表 tb_user.sql
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 DROP TABLE IF EXISTS `tb_user` ;CREATE TABLE `tb_user` ( `id` int (11 ) NOT NULL AUTO_INCREMENT, `name` varchar (18 ) DEFAULT NULL , `sex` char (2 ) DEFAULT NULL , `age` int (11 ) DEFAULT NULL , PRIMARY KEY (`id` ) ) ENGINE =InnoDB DEFAULT CHARSET =utf8mb4; INSERT INTO `tb_user` VALUES ('1' , '小明' , '男' , '21' );INSERT INTO `tb_user` VALUES ('2' , '小王' , '男' , '22' );INSERT INTO `tb_user` VALUES ('3' , '小丽' , '女' , '18' );INSERT INTO `tb_user` VALUES ('4' , '小芳' , '女' , '18' );
创建存储过程 procedure.sql
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 drop procedure if exists insert_user;DELIMITER && CREATE PROCEDURE insert_user ( OUT v_id int , in v_name varchar (18 ), in v_sex varchar (19 ), in v_age int ) BEGIN INSERT INTO tb_user (name ,sex,age) VALUES (v_name,v_sex,v_age); SET v_id=LAST_INSERT_ID (); END && DELIMITER ; drop procedure if exists select_all_user;delimiter && create procedure select_all_user()begin select id ,name ,sex,age from tb_user; end && DELIMITER ; drop procedure if exists select_user_by_id;DELIMITER && create procedure select_user_by_id(IN in_id INTEGER )begin select id ,name ,sex,age from tb_user where id =in_id; end && DELIMITER ; drop procedure if exists update_user_by_id;delimiter && create procedure update_user_by_id ( IN p_id int , IN p_name varchar (18 ), IN p_sex varchar (19 ), IN p_age int ) begin update tb_user set name =p_name,sex=p_sex,age=p_age where id =p_id; end && delimiter ; drop procedure if exists delete_user_by_id;delimiter && create procedure delete_user_by_id(IN p_id integer )begin delete from tb_user where id =p_id; end && delimiter ;
持久化对象 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package domain;public class User { private Integer id; private String name; private String sex; private Integer age; public User () { super (); } @Override public String toString () { return "User [id=" + id + ", name=" + name + ", sex=" + sex + ", age=" + age + "]" ; } }
mapper接口 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 package mapper;import java.util.List;import org.apache.ibatis.annotations.Delete;import org.apache.ibatis.annotations.Insert;import org.apache.ibatis.annotations.Options;import org.apache.ibatis.annotations.Select;import org.apache.ibatis.annotations.Update;import org.apache.ibatis.mapping.StatementType;import domain.User;public interface UserMapper { @Select ("{call select_all_user()}" ) @Options (statementType=StatementType.CALLABLE) List<User> selectAllUser () ; @Select ("{call select_user_by_id(#{id,mode=IN})}" ) @Options (statementType=StatementType.CALLABLE) User selectUserById (Integer id) ; @Insert ("{call insert_user(" + "#{id,mode=OUT,jdbcType=INTEGER}," + "#{name,mode=IN}," + "#{sex,mode=IN}," + "#{age,mode=IN}" + ")}" ) @Options (statementType=StatementType.CALLABLE) Integer insertUser (User user) ; @Update ("{call update_user_by_id(" + "#{id,mode=IN}," + "#{name,mode=IN}," + "#{sex,mode=IN}," + "#{age,mode=IN}" + ")}" ) @Options (statementType=StatementType.CALLABLE) void updateUserById (User user) ; @Delete ("{call delete_user_by_id(#{id,mode=IN})}" ) @Options (statementType=StatementType.CALLABLE) void deleteUserById (Integer id) ; }
UserMapper.java
只是将之前写在XML
文件当中调用存储过程的SQL
语句写在了注解当中,注意需要使用@Options(statementType=StatementType.CALLABLE)
提供调用存储过程的CALLBALE
选项,其他并无不同。
调用存储过程查询select操作 查询全部 存储过程如下:
1 2 3 4 5 6 7 8 9 # 创建select_user存储过程 drop procedure if exists select_all_user; delimiter && create procedure select_all_user () begin select id,name,sex,age from tb_user ;end && DELIMITER ;
查询所有的mapper
接口方法如下:
1 2 3 @Select ("{call select_all_user()}" )@Options (statementType=StatementType.CALLABLE)List<User> selectAllUser () ;
select_all_user
这个存储过程没有参数,直接在前面加上call
调用即可,注意存储过程时不要忘了加上括号,也就是:call 存储过程名称 括号
, 还有就是放在注解中的存储过程调用语句要用大括号包裹起来,至于为什么,我还不知道,先这样背着.
测试类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 package test;import java.util.List;import org.apache.ibatis.session.SqlSession;import domain.User;import fractory.SqlSessionFratoryTools;import mapper.UserMapper;public class SelectAllTest { public static void main (String[] args) { SqlSession sqlSession = null ; try { sqlSession = SqlSessionFratoryTools.getSqlSession(); UserMapper userMapper = sqlSession.getMapper(UserMapper.class); List<User> users = userMapper.selectAllUser(); System.out.println("----------------------------------" ); users.forEach(user-> System.out.println(user)); sqlSession.commit(); } catch (Exception e) { sqlSession.rollback(); e.printStackTrace(); } finally { if (sqlSession != null ) sqlSession.close(); } } }
运行效果 1 2 3 4 5 6 7 8 9 DEBUG [main] ==> Preparing: {call select_all_user()} DEBUG [main] ==> Parameters: DEBUG [main] <== Total: 4 DEBUG [main] <== Updates: 0 ---------------------------------- User [id=1 , name=小明, sex=男, age=21 ] User [id=2 , name=小王, sex=男, age=22 ] User [id=3 , name=小丽, sex=女, age=18 ] User [id=4 , name=小芳, sex=女, age=18 ]
根据id查询 用到的存储过程如下:
1 2 3 4 5 6 7 8 9 drop procedure if exists select_user_by_id;DELIMITER && create procedure select_user_by_id(IN in_id INTEGER )begin select id ,name ,sex,age from tb_user where id =in_id; end && DELIMITER ;
mapper
接口方法如下:
1 2 3 @Select ("{call select_user_by_id(#{id,mode=IN})}" )@Options (statementType=StatementType.CALLABLE)User selectUserById (Integer id) ;
注意存储过程的参数写法,#{id,mode=IN}
这个是mybatis
的表达式,该表达式中第一项id
是参数名称,第二项mode=IN
表示这个参数是存储过程的输入参数。
测试类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 package test;import org.apache.ibatis.session.SqlSession;import domain.User;import fractory.SqlSessionFratoryTools;import mapper.UserMapper;public class SelectByIdTest { public static void main (String[] args) { SqlSession sqlSession = null ; try { sqlSession = SqlSessionFratoryTools.getSqlSession(); UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user = userMapper.selectUserById(1 ); System.out.println("-----------------------------------------------" ); System.out.println(user); sqlSession.commit(); } catch (Exception e) { sqlSession.rollback(); e.printStackTrace(); } finally { if (sqlSession != null ) sqlSession.close(); } } }
运行效果如下:
1 2 3 4 5 6 DEBUG [main] ==> Preparing: {call select_user_by_id(?)} DEBUG [main] ==> Parameters: 1 (Integer) DEBUG [main] <== Total: 1 DEBUG [main] <== Updates: 0 ----------------------------------------------- User [id=1 , name=小明, sex=男, age=21 ]
使用存储过程进行update操作 对应的存储过程如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 drop procedure if exists update_user_by_id;delimiter && create procedure update_user_by_id ( IN p_id int , IN p_name varchar (18 ), IN p_sex varchar (19 ), IN p_age int ) begin update tb_user set name =p_name,sex=p_sex,age=p_age where id =p_id; end && delimiter ;
mapper
接口方法如下:
1 2 3 4 5 6 7 8 @Update ("{call update_user_by_id(" + "#{id,mode=IN}," + "#{name,mode=IN}," + "#{sex,mode=IN}," + "#{age,mode=IN}" + ")}" ) @Options (statementType=StatementType.CALLABLE)void updateUserById (User user) ;
测试类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 package test;import org.apache.ibatis.session.SqlSession;import domain.User;import fractory.SqlSessionFratoryTools;import mapper.UserMapper;public class UpdateTest { public static void main (String[] args) { SqlSession sqlSession = null ; try { sqlSession = SqlSessionFratoryTools.getSqlSession(); UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user = userMapper.selectUserById(3 ); System.out.println("----------------------------------" ); if (user != null ) { System.out.println("更新之前的数据:" + user); System.out.println("----------------------------------" ); user.setName("李四" ); user.setSex("男" ); user.setAge(22 ); userMapper.updateUserById(user); System.out.println("----------------------------------" ); user = userMapper.selectUserById(user.getId()); System.out.println("----------------------------------" ); System.out.println("更新之后的数据:" + user); } sqlSession.commit(); } catch (Exception e) { sqlSession.rollback(); e.printStackTrace(); } finally { if (sqlSession != null ) sqlSession.close(); } } }
运行结果如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 DEBUG [main] ==> Preparing: {call select_user_by_id(?)} DEBUG [main] ==> Parameters: 3 (Integer) DEBUG [main] <== Total: 1 DEBUG [main] <== Updates: 0 ---------------------------------- 更新之前的数据:User [id=3 , name=小丽, sex=女, age=18 ] ---------------------------------- DEBUG [main] ==> Preparing: {call update_user_by_id(?,?,?,?)} DEBUG [main] ==> Parameters: 3 (Integer), 李四(String), 男(String), 22 (Integer) DEBUG [main] <== Updates: 1 ---------------------------------- DEBUG [main] ==> Preparing: {call select_user_by_id(?)} DEBUG [main] ==> Parameters: 3 (Integer) DEBUG [main] <== Total: 1 DEBUG [main] <== Updates: 0 ---------------------------------- 更新之后的数据:User [id=3 , name=李四, sex=男, age=22 ]
调用存储过程进行delete操作 测试的存储过程如下:
1 2 3 4 5 6 7 8 9 drop procedure if exists delete_user_by_id;delimiter && create procedure delete_user_by_id(IN p_id integer )begin delete from tb_user where id =p_id; end && delimiter ;
对应的mapper
接口方法如下:
1 2 3 @Delete ("{call delete_user_by_id(#{id,mode=IN})}" )@Options (statementType=StatementType.CALLABLE)void deleteUserById (Integer id) ;
测试类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 package test;import org.apache.ibatis.session.SqlSession;import domain.User;import fractory.SqlSessionFratoryTools;import mapper.UserMapper;public class DeleteTest { public static void main (String[] args) { SqlSession sqlSession = null ; try { sqlSession = SqlSessionFratoryTools.getSqlSession(); UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user = userMapper.selectUserById(2 ); if (user != null ) { System.out.println("------------------------------------------" ); System.out.println("即将删除用户:" + user); System.out.println("------------------------------------------" ); userMapper.deleteUserById(user.getId()); } sqlSession.commit(); } catch (Exception e) { sqlSession.rollback(); e.printStackTrace(); } finally { if (sqlSession != null ) sqlSession.close(); } } }
运行效果:
1 2 3 4 5 6 7 8 9 10 DEBUG [main] ==> Preparing: {call select_user_by_id(?)} DEBUG [main] ==> Parameters: 2 (Integer) DEBUG [main] <== Total: 1 DEBUG [main] <== Updates: 0 ------------------------------------------ 即将删除用户:User [id=2 , name=小王, sex=男, age=22 ] ------------------------------------------ DEBUG [main] ==> Preparing: {call delete_user_by_id(?)} DEBUG [main] ==> Parameters: 2 (Integer) DEBUG [main] <== Updates: 1
调用存储过程进行insert操作 用到的存储过程定义如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 drop procedure if exists insert_user;DELIMITER && CREATE PROCEDURE insert_user ( OUT v_id int , in v_name varchar (18 ), in v_sex varchar (19 ), in v_age int ) BEGIN INSERT INTO tb_user (name ,sex,age) VALUES (v_name,v_sex,v_age); SET v_id=LAST_INSERT_ID (); END && DELIMITER ;
对应的mapper
接口的方法:
1 2 3 4 5 6 7 8 @Insert ("{call insert_user(" + "#{id,mode=OUT,jdbcType=INTEGER}," + "#{name,mode=IN}," + "#{sex,mode=IN}," + "#{age,mode=IN}" + ")}" ) @Options (statementType=StatementType.CALLABLE)Integer insertUser (User user) ;
测试类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 package test;import org.apache.ibatis.session.SqlSession;import domain.User;import fractory.SqlSessionFratoryTools;import mapper.UserMapper;public class InsertTest { public static void main (String[] args) { SqlSession sqlSession = null ; try { sqlSession = SqlSessionFratoryTools.getSqlSession(); UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user = new User(); user.setName("小张" ); user.setSex("男" ); user.setAge(22 ); userMapper.insertUser(user); System.out.println("---------------------------------------" ); System.out.println("生成的主键:" + user.getId()); sqlSession.commit(); } catch (Exception e) { sqlSession.rollback(); e.printStackTrace(); } finally { if (sqlSession != null ) sqlSession.close(); } } }
运行效果如下:
1 2 3 4 5 DEBUG [main] ==> Preparing: {call insert_user(?,?,?,?)} DEBUG [main] ==> Parameters: 小张(String), 男(String), 22 (Integer) DEBUG [main] <== Updates: 1 --------------------------------------- 生成的主键:5
原文链接: 11.3 注解调用存储过程