iBatis.Net+mysql访问存储过程的问题

来源:互联网 发布:樱井知香2010年番号 编辑:程序博客网 时间:2024/06/10 23:37

准备选用iBatis.Net做博客的数据持久层,准备写几个demo测测。看它能和mysql数据库友好的玩耍不。


刚开始还挺好的,iBatis.Net能访问mysql数据库。但到了一个存储过程的demo时,好运气终于用光了。我就在网查了查iBatis调用存储过程的例子(IBatisNet系列-执行存储过程,IBatis.Net如何获取存储过程的Output的参数值)。

看了这篇文章,我本以为问题已经解决。可以继续愉快的玩耍了。这个是我代码。


1.存储过程及部分sql(mysql)

create table `SysNum`(  Id int AUTO_INCREMENT not null  ,Name varchar(100) not null comment '表名'  ,Num bigint not null default 0 comment '该表对应的编号'  ,Status int default 0 not null  ,`Time` TIMESTAMP default now() not null  ,primary key `P_Id`(`Id`)  ,unique key `U_Name`(`Name`))ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='编号表';create PROCEDURE proc_GetSysNum(in name varchar(100),out n bigint) comment '获取编号'begindeclare value bigint default (select exists (select Num from SysNum where Name=name));set @m=0;if value<>1 thenbegininsert into SysNum(Name,Num,Status)values(name,(select @m:=1),0);end;elsebeginupdate SysNum set Num=@m:=Num+1 where Name=name;set n=@m;end;select n;end if;end;

===2014.12.24修正。Name=name永远为true。

DROP PROCEDURE IF EXISTS Duger.proc_GetSysNum;CREATE PROCEDURE Duger.`proc_GetSysNum`(in m varchar(100),out n bigint)    COMMENT '获取编号'beginset @v:= (select exists (select Num from SysNum where Name=m));set @m=0;if @v<>1 theninsert into SysNum(Name,Num,Status)values(m,(select @m:=1),0);elseupdate SysNum set Num=@m:=Num+1 where Name=m;end if;set n=@m;select n;end;
===end

2.providers.config。sqlServer2.0是后续还mssql测试加进去的。如果需要启用一个数据库。需要把enabled属性节点设为true。

<?xml version="1.0" encoding="utf-8"?><providers xmlns="http://ibatis.apache.org/providers" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><clear/>  <provider     name="MySql"     description="MySQL, MySQL provider 1.0.7.30072"     <span style="color:#ff0000;">enabled</span>="true"     assemblyName="MySql.Data, Version=6.9.5.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" connectionClass="MySql.Data.MySqlClient.MySqlConnection"     commandClass="MySql.Data.MySqlClient.MySqlCommand"     parameterClass="MySql.Data.MySqlClient.MySqlParameter"     parameterDbTypeClass="MySql.Data.MySqlClient.MySqlDbType"     parameterDbTypeProperty="MySqlDbType"     dataAdapterClass="MySql.Data.MySqlClient.MySqlDataAdapter"     commandBuilderClass="MySql.Data.MySqlClient.MySqlCommandBuilder"     usePositionalParameters="false"     useParameterPrefixInSql="true"     useParameterPrefixInParameter="true"     <span style="color:#ff0000;">parameterPrefix="?"</span>    allowMARS="false"      />  <provider    name="sqlServer2.0"    <span style="color:#ff0000;">enabled</span>="false"    description="Microsoft SQL Server, provider V2.0.0.0 in framework .NET V2.0"    assemblyName="System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"    connectionClass="System.Data.SqlClient.SqlConnection"    commandClass="System.Data.SqlClient.SqlCommand"    parameterClass="System.Data.SqlClient.SqlParameter"    parameterDbTypeClass="System.Data.SqlDbType"    parameterDbTypeProperty="SqlDbType"    dataAdapterClass="System.Data.SqlClient.SqlDataAdapter"    commandBuilderClass=" System.Data.SqlClient.SqlCommandBuilder"    usePositionalParameters = "false"    useParameterPrefixInSql = "true"    useParameterPrefixInParameter = "true"    parameterPrefix="@"    allowMARS="false"    /></providers>
3.sqlMap.config 我是用嵌入资源这个模式弄的。

<?xml version="1.0" encoding="utf-8"?><sqlMapConfig  xmlns="http://ibatis.apache.org/dataMapper"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">  <settings>    <setting useStatementNamespaces="false" />  </settings>  <!--db provider配置文件路径-->  <providers resource="providers.config" />  <!--db provider类型及连接串-->  <!--<database>    <provider name="sqlServer2.0" />    <dataSource name="write" connectionString="Rc9xsKSnf5cbEUwkWZq1i3eVDcuKLDIjcszp6GwxvlSD6D96EZcEBeL8KmZhwQ9Y" />  </database>-->  <database>    <provider name="MySql" />    <dataSource name="write" connectionString="sKkQ8sJwJ2ElfkH7ycmzsP5+V7TJp05bSeT71UoE85DOarPUz65eYDxX8Ar0KxN1gmOQKs8QlMxhufcxrymLoGhcFvyFP8RY" />  </database>  <sqlMaps>    <!-- user via embedded-->    <sqlMap embedded="DataMap.User.xml,Duger.Net.Dal" />    <sqlMap embedded="DataMap.SysNum.xml,Duger.Net.Dal" />    <!--<sqlMap resource="Maps/test.xml"/>-->  </sqlMaps></sqlMapConfig>

4.dal层的xml资源文件

  <statements>    <procedure id="GetSysNum" parameterMap="mapid">      proc_GetSysNum    </procedure>    <procedure id="GetSysNum2" parameterMap="mapid"><!--后来用mssql测试看到底哪里错了。使用的-->      proc_GetSysNum    </procedure>  </statements>  <parameterMaps>    <parameterMap id="mapid" class="Hashtable">       <parameter property="name"/>      <parameter property="n" column="n" direction="Output"/>    </parameterMap>  </parameterMaps>
===2014.12.24修正。参数名要保持一致。

  <parameterMaps>    <parameterMap id="mapid" class="Hashtable">       <parameter property="m"/>      <parameter property="n" column="n" direction="Output"/>    </parameterMap>  </parameterMaps>

===end

5..net代码

            Hashtable table=new Hashtable {{"name", model.Name}, {"n", model.Num}};            var i2 = Write.QueryForObject("GetSysNum", table);            Console.WriteLine(i2 + "|" + table["n"]);

===2014.12.24修正。参数名要保持一致。

            Hashtable table=new Hashtable {{"m", model.Name}, {"n", model.Num}};            var i2 = Write.QueryForObject("GetSysNum", table);            Console.WriteLine(i2 + "|" + table["n"]);
===end

我就用上面的代码做单元测试。然后一直报错。然后在不归路上越行越远。

最开始报的就是这个错误。我很快就把dal层的xml里面的column="n"删掉了。


这个错误没出现了。但又出现了一个新的错误。


注意最后一个方法。点进入看到该方法的实现如下。可以推断parameterName就是?那个不是问号,后面没东西了。这时候还要引入一个话题(mysql中的?和@,这两货貌似都可以搞参数化查询。但又有些区别。25楼有人说了一下,不知真假。但跟ibatis.net又有什么关联呢?还是跟驱动程序的版本有关?http://bbs.csdn.net/topics/300025212

    private MySqlParameter InternalGetParameter(string parameterName)    {      int index1 = this.IndexOf(parameterName);      if (index1 >= 0)        return this.items[index1];      if (parameterName.StartsWith("@", StringComparison.Ordinal) || parameterName.StartsWith("?", StringComparison.Ordinal))      {        int index2 = this.IndexOf(parameterName.Substring(1));        if (index2 != -1)          return this.items[index2];      }      throw new ArgumentException("Parameter '" + parameterName + "' not found in the collection.");    }

现在看起来就是不知道在哪一步判断失败,导致参数名称(n)加不上去。最后在这个方法里抛出异常了。

好吧。我回到了providers.config里看到provider的属性节点是这样的(parameterPrefix="?")。然后换成了"@",再次进行单元调试。测试通过。


我勒个去。这是为什么了。。。还有,从这个可以看出。存储过程都调用成功了。但最后处理的时候出了问题。还有我的mysql驱动是(mysql-connector-net-6.9.5-src)。

0 0
原创粉丝点击