MySQL存储过程

DROP PROCEDURE IF EXISTS transferMoney;
-- 实现转账功能的存储过程
CREATE PROCEDURE transferMoney (
IN fromUserId INT, -- 付款方
IN toUserId INT, -- 收款方
IN money DOUBLE, -- 转账金额
OUT state INT, -- 状态
OUT errorMsg VARCHAR(40) -- 异常信息
)
BEGIN
SET state = 0; -- 0表示正常,99表示异常
START TRANSACTION; -- 启用事务 -- 先扣除付款人的金额
UPDATE USER u SET u.money = u.money-money WHERE id = fromUserId;
IF ROW_COUNT()=0 then -- 如果影响记录为0,表示异常,标示为99
set state = 99;
set errorMsg = CONCAT('付款人金额更新影响行数为0,fromUserId:',fromUserId);
END IF; -- 再增加收款人的金额
UPDATE USER u SET u.money = u.money+money WHERE id = toUserId;
IF ROW_COUNT()=0 then -- 如果影响记录为0,表示异常,标示为99
set state = 99;
set errorMsg = CONCAT('收款人金额更新影响行数为0,toUserId:',toUserId);
END IF; -- 如果运行正常则提交,否则,回滚
IF state=0 then
COMMIT;
ELSE
ROLLBACK;
END IF;
END;

MyBatis映射文件UserMapper.xml

<select id="transferMoney" statementType="CALLABLE" parameterType="java.util.HashMap">
{
call transferMoney (#{fromUserId,mode=IN,jdbcType=INTEGER},
#{toUserId,mode=IN,jdbcType=INTEGER},
#{money,mode=IN,jdbcType=DOUBLE},
#{state,mode=OUT,jdbcType=INTEGER},
#{errorMsg,mode=OUT,jdbcType=VARCHAR})
}
</select>

UserServiceImpl.java代码

@Override
public void transferMoneyByProcedure(int fromUserId, int toUserId, double money) {
Map<String,Object> map = new HashMap<String,Object>();
map.put("fromUserId", fromUserId);
map.put("toUserId", toUserId);
map.put("money", money);
userDao.transferMoney(map);
//存储过程完成转账,打印执行结果,存储过程返回的out参数state, errorMsg值会保存在map中。
Logger.info(JSON.toJSONString(map));
int state = Integer.parseInt(map.get("state").toString());
if(state != 0) {
System.out.println("转账异常:"+map.get("errorMsg"));
} }

UserServiceTest.java代码

    @Test
public void testTransferMoneyByProcedure() {
int fromUserId = 1;
int toUserId = 3;
userService.transferMoneyByProcedure(fromUserId, toUserId, 1001);
}

控制台结果

[com.ssm.dao.UserDao.transferMoney] - ==>  Preparing: { call transferMoney (?, ?, ?, ?, ?) }
[com.ssm.dao.UserDao.transferMoney] - ==> Parameters: 1(Integer), 3(Integer), 1001.0(Double)
[com.ssm.common.Logger] - {"toUserId":3,"state":99,"money":1001,"errorMsg":"收款人金额更新影响行数为0,toUserId:3","fromUserId":1}
转账异常:收款人金额更新影响行数为0,toUserId:3
[org.springframework.context.support.GenericApplicationContext] - Closing org.springframework.context.support.GenericApplicationContext@7da3f9e4: startup date [Sat Oct 24 14:50:09 GMT+08:00 2015]; root of context hierarchy

数据库User表

Spring事务配置

<!-- 第一种配置事务的方式 ,tx-->
<tx:advice id="txadvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="update*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="del*" propagation="REQUIRED" rollback-for="Exception"/>
<tx:method name="*TX" propagation="REQUIRED" rollback-for="Exception"/>
<!-- 存储过程都是自带了事务处理,所以这里配置NEVER了 -->
<tx:method name="*Procedure" propagation="NEVER" rollback-for="Exception"/>
<tx:method name="*" propagation="REQUIRED" read-only="true"/>
</tx:attributes>
</tx:advice> <aop:config>
<aop:pointcut id="serviceMethod" expression="execution(* com.ssm.service.*.*(..))"/>
<aop:advisor pointcut-ref="serviceMethod" advice-ref="txadvice"/>
</aop:config>

MyBatis调用存储过程的更多相关文章

  1. MyBatis基础:MyBatis调用存储过程(6)

    1. 存储过程准备 CREATE PROCEDURE sp_task ( IN userId INT ) BEGIN SELECT * FROM task WHERE user_id = userId ...

  2. 使用mybatis调用存储过程(注解形式和配置文件形式)

    最近在看资料中涉及到mybatis,突然想到mysql中的视图.存储过程.函数.现将在使用mybatis调用mysql的存储过程使用总结下: 使用的环境:mybatis3.4.6,mysql 5.6, ...

  3. Mybatis调用存储过程报错

    Mybatis调用存储过程 贴码 123456 Error querying database. Cause: java.sql.SQLException: User does not have ac ...

  4. 关于用mybatis调用存储过程时的入参和出参的传递方法

    一.问题描述 a)         目前调用读的存储过程的接口定义一般是:void  ReadDatalogs(Map<String,Object> map);,入参和出参都在这个map里 ...

  5. mybatis 调用存储过程 返回游标 实例

    存储过程示例: create or replace procedure Fsp_Plan_CheckPrj(v_grantno varchar2, v_deptcode number, v_curso ...

  6. MyBatis——调用存储过程

    原文:http://www.cnblogs.com/xdp-gacl/p/4270352.html 一.提出需求 查询得到男性或女性的数量, 如果传入的是0就女性否则是男性 二.准备数据库表和存储过程 ...

  7. mybatis调用存储过程,获取返回的游标

    将调用存储过程参数放入map中,由于返回的游标中包含很多参数,所以再写一个resultmap与之对应,类型为hashmap.设置返回的jdbcType=CURSOR,resultMap设置为id对应的 ...

  8. mybatis调用存储过程(@Select方式)

    存储过程还不会写的同学可以参考我另一篇文章:https://www.cnblogs.com/liuboyuan/p/9375882.html 网上已经有很多用mybatis调用的教程了,但是大部分是x ...

  9. MyBatis调用存储过程,含有返回结果集、return参数和output参数

    Ibatis是我们经常使用的O/R映射框架,mybats是ibatis被Google收购后重新命名的一个工程,当然也做了大量的升级.而调用存储过程也是一次额C/S架构模式下经常使用的手段,我们知道,i ...

  10. Mybatis 调用存储过程,使用Map进行输入输出参数的传递

    做个记录,以备后用 java代码: public String texuChange() throws Exception {        try {                         ...

随机推荐

  1. Foix_Reader_6.0|PDF阅读器

    福晰PDF阅读器,是阅读器中的精品.此版本是优化版本. 00:风格前卫 01:使用简洁 下载地址:        http://yunpan.cn/cHvyUfCdMKZz6  访问密码 ead7

  2. UIScrollView和UIPageController

    实现代码: // // ViewController.m // UIpageControl // // Created by dllo on 16/3/10. // Copyright © 2016年 ...

  3. base-css

    html{ min-width: 320px;}body{ min-width: 320px; overflow-x:hidden }@media print { * { background: tr ...

  4. OC基础--内存管理中的@property关键字以及其参数

    在上一篇博客中整理的内存管理,管理类的代码量会感觉很大,而且如果对象多的话,感觉到代码有点冗余.下面就介绍Xcode中为我们自动生成内存管理代码的关键字@property 例如:在Person这个类中 ...

  5. sql-where

    查询表时不一定每一次都要将表格内的资料都完全抓出.在许多时候,我们会需要选择性地抓资料.就我们的例子来说,我们可能只要抓出营业额超过 $1,000 的资料. 要做到这一点,需要用到 WHERE 这个指 ...

  6. href的参数含有中文在IE下乱码的解决

    这是在使用kendo grid的自定义链接时遇到的一个坑,链接如下: var TempStr = "<a href='" + Url.Action("EditUse ...

  7. 使用Navicat远程管理OpenShift的数据库

    其实 phpMyAdmin 这个 web 端的 MySQL 数据库管理工具还是很好的,要不然也不会成为 MySQL 数据库的绝配.但是我想,很多人应该和重华一样,不太喜欢使用 web 端的工具,总觉得 ...

  8. BZOJ-1951 古代猪文 (组合数取模Lucas+中国剩余定理+拓展欧几里得+快速幂)

    数论神题了吧算是 1951: [Sdoi2010]古代猪文 Time Limit: 1 Sec Memory Limit: 64 MB Submit: 1573 Solved: 650 [Submit ...

  9. HD 2177(威佐夫博弈 入门)

    取(2堆)石子游戏 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  10. POJ3233Matrix Power Series(十大矩阵问题之三 + 二分+矩阵快速幂)

    http://poj.org/problem?id=3233 Matrix Power Series Time Limit: 3000MS   Memory Limit: 131072K Total ...