如何使用mybatis调用存储过程

如何使用mybatis调用存储过程

先提供一个秒杀逻辑(https://github.com/cdefgab1234/seckill)的存储过程:

--秒杀执行存储过程
DELIMITER $$
-- 运行第二次,这是为了能多次运行
DROP PROCEDURE IF EXISTS `execute_seckill`$$
-- 参数: in 输入参数; out 输出参数
-- row_count() 返回上一条修改类型的(delete,insert,update)sql影响的行数
-- row_count(); 0:未修改数据  >0影响行数  <0 sql错误,未执行sql
CREATE DEFINER=`root`@`localhost` PROCEDURE `execute_seckill`(IN v_seckill_id BIGINT,IN v_phone BIGINT,IN v_kill_time TIMESTAMP,OUT r_result INT)
BEGIN
        DECLARE insert_count INT DEFAULT 0;
        START TRANSACTION;
        INSERT IGNORE success_killed(seckill_id,user_phone,create_time)
          VALUES(v_seckill_id,v_phone,v_kill_time);

        SELECT ROW_COUNT() INTO insert_count;
        IF (insert_count = 0) THEN
           ROLLBACK;
           SET r_result = -1;
        ELSEIF(insert_count<0) THEN
           ROLLBACK;
           SET r_result = -2;
        ELSE
           UPDATE seckill
           SET number=number-1
           WHERE seckill_id = v_seckill_id
            AND end_time > v_kill_time
            AND start_time < v_kill_time
            AND number > 0;

         SELECT ROW_COUNT() INTO insert_count;
	IF (insert_count=0) THEN
	    ROLLBACK;
	    SET r_result=0;
	ELSEIF (insert_count <0) THEN
	    ROLLBACK;
	    SET r_result = -2;
	ELSE
	    COMMIT;
	    SET r_result = 1;
	END IF;
        END IF;
    END$$

DELIMITER ;

START TRANSACTION; -- 一个小链接http://www.cnblogs.com/langtianya/p/4777662.html

sql调用存储过程语法(猴头符号是必须的)

SET @r_result = 3

-- 执行存储过程
CALL execute_seckill(1003,1998998988,NOW(),@r_result);
-- 获取结果
select @r_result

-- 存储过程
-- 1.存储过程优化:
-- 2.不要过度依赖存储过程
-- 3.简单逻辑可以应用存储过程
mybatis配置文件的写法(一个有模有样的存储过程有in和out参数):


    
它的接口:

/**
     * 直接使用存储过程完成秒杀
     * @param paramMap
     */
    void killByProcedure(Map paramMap);

@service层调用的方法:

 public SeckillExecution executeSeckillProcedure(long seckillId, long userPhone, String md5)  {
        if(md5==null || !md5.equals(getMd5(seckillId))){
            return new SeckillExecution(seckillId,SeckillStatEnum.DATA_REWRITE);
        }
        Date killTime = new Date();
        Map map = new HashMap();
        map.put("seckillId",seckillId);
        map.put("phone",userPhone);
        map.put("killTime",killTime);
        map.put("result",null);
        //执行存储过程,result被复制
        try {
            seckillDao.killByProcedure(map);
            int result = MapUtils.getInteger(map, "result", -2);
            if (result == 1) {
                SuccessKilled sk = successKilledDao.queryByIdWithSeckill(seckillId, userPhone);
                return new SeckillExecution(seckillId, SeckillStatEnum.SUCCESS, sk);
            } else {
                return new SeckillExecution(seckillId, SeckillStatEnum.stateOf(result));
            }
        }catch (Exception e){
            logger.error(e.getMessage(),e);
            return new SeckillExecution(seckillId,SeckillStatEnum.INNER_ERROR);
        }

    }
MapUtils.getInteger();方法是commons-collection的一个方法:找map中键值为“result”的方法,null则为-2

和stringUntils都是项目中千锤百炼出来的工具类项目,很好用。可以看源码,确实方便。








你可能感兴趣的:(mybatis,sql,mysql)