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. G-nav-03

    /*dele masthead.css style*/.masthead .navigation .btn.btn-masthead.btn-apply:after { content: ''; di ...

  2. 【poj3177】 Redundant Paths

    http://poj.org/problem?id=3177 (题目链接) 题意 给出一个n个节点m条边的无向图,求最少连几条边使图中没有桥. Solution 我们可以发现,用最少的边使得图中没有桥 ...

  3. android studio问题-ICCP:Not recognizing known sRGB profile

    转:http://my.oschina.net/1pei/blog/479162 PNG格式:每个PNG文件是由一个PNG标识(signature),后面跟一些数据块(chunk),每个chunk由 ...

  4. groovy-实现接口

    Groovy提供了一些非常方便的方法来实现接口 使用闭包实现接口 只有一个方法的接口可以使用闭包来实现,例如 1 // a readable puts chars into a CharBuffer ...

  5. Sublime Text 3 笔记

    Nearly all of the interesting files for users live under the data directory. The data directory is ~ ...

  6. 修改host

    需修改手机/etc/hosts文件.将” 118.194.60.190 域名” 添加 手机的/etc/hosts文件.手机需有root权限,操作如下:1. C:\Documents and Setti ...

  7. Sphinx学习之sphinx的安装篇

    一.  Sphinx简介 Sphinx是由俄罗斯人Andrew Aksyonoff开发的一个全文检索引擎.意图为其他应用提供高速.低空间占用.高结果 相关度的全文搜索功能.Sphinx可以非常容易的与 ...

  8. php扩展redis

    Redis安装整理(window平台) +php扩展redis 分类: Web开发2013-03-23 18:51 8258人阅读 评论(3) 收藏 举报                        ...

  9. Java Web 设置默认首页

    一.问题描述 这里所谓的默认首页,是指在访问项目根目录时(如 http://localhost:8080/zhx-web/ )展示的页面,通过在web.xml里配置 <welcome-file- ...

  10. 用css3制作旋转加载动画的几种方法

    以WebKit为核心的浏览器,例如Safari和Chrome,对html5有着很好的支持,在移动平台中这两个浏览器对应的就是IOS和Android.最近在开发一个移动平台的web app,那么就有机会 ...