MyCat1.6带返回参数存储过程调用示例
来源:互联网 发布:java web简单小项目 编辑:程序博客网 时间:2024/06/05 00:38
本例环境:SpringMVC3.x + Mybatis3.x + Mycat1.6 + Mysql5.6
1、创建带出参存储过程
DELIMITER && CREATE PROCEDURE `test_proc`( in a_id int , out a_goods_id int)BEGIN SELECT a.goods_id INTO a_goods_id FROM es_goods_community a WHERE a.id=a_id ; END &&DELIMITER ;备注:这里的存储过程比较简单,就是根据一个表的ID,返回一个表的另外一个字段,本例中a_goods_id为出参。
2、mybatis映射文件
<select id="testCallProc" resultType="java.lang.Integer"> <!-- statementType="CALLABLE" --> <![CDATA[ /*!mycat:sql=select 1 from es_goods_community where seller_id=26*/{call test_proc( #{id,mode=IN,jdbcType=INTEGER}, @goodsId )};select @goodsId; ]]> </select>
这里的关键:statementType="CALLABLE"不需要加上,而是把存储过程当成一条普通的SQL语句,发送给mycat执行,mycat根据注解路由到具体的后端节点,然后执行之,并返回结果,还需要在后面使用selelect语句返回OUT参数。在call语句中,出参用@加变量名定义,名字与select语句中的名字保持一样即可。
为什么要这样写呢?原因如下:
1、mycat已经声明,存储过程的调用通过注解来支持(主要原因,调用存储过程的语句无法定位路由信息),如果statementType="CALLABLE",mysql客户端(本例指mysql驱动包)会把语句当存储过程来看到,势必需要知道存储过程的元数据(出参列表)。故在mybatis文件中,call语句之前需要待上注解,但这和mycat驱动包处理存储过程的代码产生了矛盾,如下代码:
public CallableStatement(MySQLConnection conn, String sql, String catalog, boolean isFunctionCall) throws SQLException { super(conn, sql, catalog); this.callingStoredFunction = isFunctionCall; if (!this.callingStoredFunction) { if (!StringUtils.startsWithIgnoreCaseAndWs(sql, "CALL")) { // @1 // not really a stored procedure call fakeParameterTypes(false); //@2 } else { determineParameterTypes(); //@3 } generateParameterMap(); } else { determineParameterTypes(); generateParameterMap(); this.parameterCount += 1; } this.retrieveGeneratedKeys = true; // not provided for in the JDBC spec }
代码来源与mysql-connector-java-5.1.30.jar中CallableStatement,现在做个简单的解读:
代码@1,判断SQL语句是否以CALL语句开头,如果不是,则调用代码@2fakeParameterTypes方法, 我可以很负责任人的告诉你,该方法只是固定返回一个参数列表,完全与调用的存储过程的出参列表不匹配
代码@3,调用后端连接,得到存储过程的源信息:发送的语句为:SELECT name, type, comment FROM mysql.proc WHERE name like '存储过程名' and db <=> '数据库名' ORDER BY name, type;
但mycat的处理如下:io.mycat.server.ServerConnection 的public void execute(String sql, int type) 方法:
跟进MysqlProcHandler.handle方法得知,mycat只是返回空数据给前端连接,并没有去后端执行该语句。所以,mybatis配置文件的statementType不能陪在为CALLABLE的原因。
3、DAO与控制层的代码就在这里省略。完整的代码如下:http://git.oschina.net/zhcsoft/StudyDemo 包路径为:persistent.prestige.web下。
备注:不能在mysql客户端连接工具(连接mycat)中直接运行:
call test_proc(140,@goodsId)};select @goodsId;得不到正确的数据原因分析:
因为在客户端查询分析器中执行该命令,,是分两条语句 call test_proc(140,@goodsId); select @goodsId;两条命令发送给mycat执行的,这样发送到后端的连接,两次不一定使用相同的Connection连接,所以无法得到值,
call test_proc(140,@goodsId); select @goodsId; 必须当成一个multi-statement语句一起发送给mycat,才能正确得到结果。
再次声明:完整的示例代码地址:http://git.oschina.net/zhcsoft/StudyDemo
0 0
- MyCat1.6带返回参数存储过程调用示例
- asp.net调用带返回值参数的存储过程
- PHP_PDO 调用mysql 带返回参数的存储过程
- C#调用存储过程带输出参数或返回值
- Hibernate3调用带返回参数的mysql存储过程
- c#调用带参数或返回值的存储过程
- Hibernate调用存储过程示例(有参数,返回结果集)
- 存储过程带返回参数
- 调用带参数存储过程
- 带参数的存储过程示例
- 调用带 返回值 的存储过程
- c#带输入输出参数调用存储过程
- VB.net 调用带参数存储过程
- ASP调用带参数存储过程
- VC++调用带参数的存储过程
- 调用带输出参数的存储过程
- 带输出参数的存储过程调用
- C#调用带参数的存储过程
- ubantu 删除掉的文件回收站里没有
- 初始化列表
- 结合mysqlbinlog与mysqldump进行MySQL数据备份与恢复(适用于较小的数据量)
- Android 新建文件夹、生成文件并向文件写入文本内容
- Android OkHttp3简介和使用详解
- MyCat1.6带返回参数存储过程调用示例
- iOS导航栏自定义按钮导致点击范围过大的问题
- android5.1 增加ethernet设置(DHCP与Static ip)
- 网络管理
- 用mysqldump备份及结合binlog日志恢复的全过程
- Java-运算符
- 编辑距离及编辑距离算法
- CMMI成熟度等级说明
- centos mysql 环境搭建