mybatis allowMultiQueries解决同时执行多条语句

项目:基于人脸识别的无卡ATM机模拟系统
在完成两个账户转账的时候,主要需要完成两个表的关联更新时(即一个账户扣钱,一个账户存钱),对我这种小白来说,通常
第一反应就是写两个sql语句,分别执行这两条语句,用web项目翻译来说就是写两个update语句然后DAO下写这两个接口,在server的同一个方法中调用这两个接口。
第二写存储过程,或者存储函数。
第三批操作,然后批量执行。
第四 也是这次纠结的然后查询出来方法,因为我突然想到plsql中都可以直接运行两条语句,那么mybatis中也应该可以,结果是果然可以。先给出答案把

只需要在jdbc:url后面跟上allowMultiQueries=true的参数

如我的jdbc:mysql://localhost:3306/xhdesing?characterEncoding=UTF-8&allowMultiQueries=true
characterEncoding 配置编码,用户防止数据库与服务器请求,防止乱码。
allowMultiQueries 配置同一标签内,用户一次执行多条语句。
allow允许
Multi多个
Queries查询

您可以跳过下面了,这里只是我艰苦的探索过程,也许还有其他的方式,希望大家评论交流,谢谢

今天纠结的实现过程

1.第一反应如下:
mapper配置文件

<mapper namespace="com.xihua.facedistinguish.dao.MenuDao">
<!-- 做减法操作 -->
<update id="transger_subtraction" parameterType="string">
        update atm_card
        set card_money = card_money-${money }
        where card_id = '${outCard }' and save_type= '${outtype }'
</update>
<!-- 做加法操作 -->
<update id="transger_add" parameterType="string">
        update atm_card
        set card_money = card_money+${money }
        where card_id = '${infoCard }' and save_type= '${infotype }'
</update>
</mapper>

DAO

public interface MenuDao {
    int transger_subtraction(@Param("outCard")String outCard, 
                @Param("outtype")String outtype,
                @Param("money")String money);
    int transger_add(@Param("infoCard")String infoCard, 
                @Param("infotype")String infotype,
                @Param("money")String money);
}

serverImp中

@Service("menuService")
public class MenuServiceImp implements MenuService{

    @Resource
    private MenuDao menuDao;
    public boolean transfer(String outCard, String infoCard, String money, String outtype, String infotype){
        boolean ok = false;
        try {
            int num1 = menuDao.transger_add(infoCard,infotype,money);
            int num2 = menuDao.transger_subtraction(outCard,outtype,  money);
            if (num1>0 and num2>0){
                ok = true;
            }  
        } catch (Exception e) {
            System.err.println(e.getMessage());
            ok = false;
        }
        return ok;
    }
}

这就是我觉得我通常第一印象想到的方法。
但是今天就觉得在PL/SQL中都可以直接运行两条更新语句而为什么我要这么复杂呢?

update atm_card   set card_money = card_money-12321   where card_id = '5137230000' and save_type= '1';   
update atm_card   set card_money = card_money+12321   where card_id = '5137230000' and save_type= '2';

那么结果来了,我觉得可以在mapper中也可以这样啊如:
解决办法
2.
spring-mybatis

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <!-- 注意这里是重点 -->
        <property name="url" value="jdbc:mysql://localhost:3306/xhdesing?characterEncoding=UTF-8&amp;allowMultiQueries=true"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
    </bean>

如果不配置上面的运行多条查询将报下面错误

### SQL: update atm_card   set card_money = card_money-12   where card_id = '5137231994032769570000' and save_type= '1'   ;   update atm_card   set card_money = card_money+12   where card_id = '5137231994032769570000' and save_type= '2'   ;
### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'update atm_card
        set card_money = card_money+12
        where card_id = '513723199403' at line 5
; bad SQL grammar []; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'update atm_card
        set card_money = card_money+12
        where card_id = '513723199403' at line 5

将这个报错的语句放在plsql中完全可以运行

mapper

<update id="transger" parameterType="string">
        update atm_card
        set card_money = card_money-${money }
        where card_id = '${outCard }' and save_type= '${outtype }'
        ;
        update atm_card
        set card_money = card_money+${money }
        where card_id = '${infoCard }' and save_type= '${infotype }'
        ;
</update>

DAO

/**
     * 转账操作,从卡1转出资金到卡2, 注意卡可以是一个用户的活期账户转给该用户的定期账户,同时也可以是某一个用户
     * 的定期账户转给活期账户,也可以是用户1转账给用户2
     * @param outCard 转出账号的id
     * @param infoCard 转入账号的id
     * @param money 转出的金额
     * @param type 转出类型【1表示活期账户,2表示转给定期账户】
     * @return 返回传出成功的行数
     */
    int transger(@Param("outCard")String outCard, @Param("outtype")String outtype,
            @Param("infoCard")String infoCard, @Param("infotype")String infotype,
            @Param("money")String money);

serverImp中

public boolean transfer(String outCard, String infoCard, String money, String outtype, String infotype){
        boolean ok = false;
        try {
            int num = menuDao.transger(outCard, outtype, infoCard, infotype , money);
            if (num>0){
                ok = true;
            }  
        } catch (Exception e) {
            System.err.println(e.getMessage());
            ok = false;
        }
        return ok;
    }

以上就是这次面临的问题以及解决过程,如有错误希望大家指出,欢迎交流。

猜你喜欢

转载自blog.csdn.net/ljcc122/article/details/79935372