西西软件园多重安全检测下载网站、值得信赖的软件下载站!
软件
软件
文章
搜索

首页西西教程数据库教程 → IBatis.Net 中的数据类型转换解决方案

IBatis.Net 中的数据类型转换解决方案

相关软件相关文章发表评论 来源:西西整理时间:2012/6/4 16:15:35字体大小:A-A+

作者:佚名点击:59次评论:0次标签: Access

  • 类型:编程辅助大小:134KB语言:中文 评分:3.3
  • 标签:
立即下载

这两天被一个问题折磨得死去活来,终于解决了,写下来以备参考:

问题是这样的:

我在项目中使用了IBatis.Net,数据库使用的是 MS Access。因为Access数据库没有float或double类型,只有Currency类型可以用作浮点数。所以我定义了类似如下的对象,表,以及SQL语句:

1.对象

        public class Mark

        {

                public string Subject{...}

                public int Year{...}

                public double Point{...}

        }

2.数据库Mark

Subject       Text

Year           Number

Point          Currency

3.SQL statement

        <statements>

                <selectid="Query"parameterMap="pMarkMap"resultMap="rMarkMap">

                        Select Subject, Year, Point

                        From Mark

                        <dynamicprepend="Where">

                                <isNotNullprepend="AND"property="Subject">

                                        Subject = #Subject#

                                </isNotNull>

                                <isNotNullprepend="AND"property="Year">

                                        Year = #Year#

                                </isNotNull>

                        </dynamic>

                </select>

        </statements>

4.查询数据库

        Mark mark = new Mark();

        mark.Year = 2005;

        ISqlMapper mapper = Mapper.Instance();

        Object obj = mapper.QueryForObject("Mark.Query", mark);

        mark = obj as Mark;

        ArrayList list = new ArrayList();

        list.Add(obj);

        Grid.DataSource = list;

结果抛出异常:"Specified cast is not valid."

这个问题困扰了我两天,最后才发现两个解决办法:

1.      将对象中的Point属性的类型改成 decimal. 这种方法固然简单,可是在数据库中使用Currency乃不得已,在SQL Server中却有Float类型可以使用,IBatis自动支持从.NET的double类型到数据库Float类型的转换。所以如果为了Currency而使用decimal,则后台数据库变成SQLServer或是Oracle时,在数据库端不得不使用Decimal/Money等类型。或者修改程序中的decimal定义为double类型,这都不是很合理。所以,下面是一个相对复杂一点却合理的解决方法。

注:IBatis.Net自动支持的类型转换请参阅<<DataMapper Developer Guide>> version 1.5.0 – Chapter 3.6, 3.7: Supported database types

2.      使用自定义类型转换函数

·          定义类

using System;

using IBatisNet.Common;

using IBatisNet.DataMapper.TypeHandlers;

namespace TestIBatis

{

        public class DoubleCurrencyTypeHandler :

                IBatisNet.DataMapper.TypeHandlers.ITypeHandlerCallback

        {

                #region ITypeHandlerCallback Members

// 此类型的null值

                public object NullValue

                {

                        get

                        {

                                return null;

                        }

                }

                public object ValueOf(string s)

                {

                        // 这个函数用于将nullValue值翻译成要比较的null值

// 如果没有,则推荐返回字符串s

                        return s;

                }

                public object GetResult(IResultGetter getter)

                {

                        // 用于将从数据库读取的值转换成.NET中的值

                        // 这里我们知道Currency可以转成decimal类型,

// 再用显示转换将decimal转换成double

                        decimal v1 = Convert.ToDecimal(getter.Value);

                        double v2 = (double)v1;

                        return v2;

                }

                public void SetParameter(IParameterSetter setter, object parameter)

                {

                        // TODO:  将.NET中的double型转换成decimal,再转换成Currency

                        decimal v1 = Convert.ToDecimal(parameter);

                        setter.Value = v1;

                }

                #endregion

        }

}

·          定义SQL中的parameterMap 及 resultMap

在SqlMap.config中加入下面的语句

  <alias>

        <typeAliasalias="DoubleCurrency"

type="TestIBatis.DoubleCurrencyTypeHandler, TestIBatis"/>

  </alias>

  <typeHandlers>

        <typeHandlertype="double"dbType="Currency"callback="DoubleCurrency"/>

  </typeHandlers>

在SQL statement所在的Mark.xml文件里加上如下语句

        <alias>

                <typeAliasalias="Mark"type="TestIBatis.Mark, TestIBatis"/>

        </alias>

        <parameterMaps>

                <parameterMapid="pMarkMap"class="Mark">

                        <parameterproperty="Subject"column="Subject"/>

                        <parameterproperty="Year"column="Year"

type="Int32"dbType="Integer"/>

                        <parameterproperty="Point"column="Point"

type="double"dbType="Currency"/>

                </parameterMap>

        </parameterMaps>

        <resultMaps>

                <resultMapid="rMarkMap"class="Mark">

                        <resultproperty="Subject"column="Subject"/>

                        <resultproperty="Year"column="Year"type="Int32"dbType="Integer"/>

                        <resultproperty="Point"column="Point"

type="double"dbType="Currency"/>

                </resultMap>

        </resultMaps>

        <statements>

                <selectid="Query"parameterMap="pMarkMap"resultMap="rMarkMap">

                        Select Subject, Year, Point

                        From Mark

                        <dynamicprepend="Where">

                                <isNotNullprepend="AND"property="Subject">

                                        Subject = #Subject#

                                </isNotNull>

                                <isNotNullprepend="AND"property="Year">

                                        Year = #Year#

                                </isNotNull>

                        </dynamic>

                </select>

        </statements>

运行程序,一切正常

注:关于自定义类型转换,请参阅<<DataMapper Developer Guide>> version 1.5.0 – Chapter 3.5.5 – Custom Type Handlers

    相关评论

    阅读本文后您有什么感想? 已有人给出评价!

    • 8 喜欢喜欢
    • 3 顶
    • 1 难过难过
    • 5 囧
    • 3 围观围观
    • 2 无聊无聊

    热门评论

    最新评论

    发表评论 查看所有评论(0)

    昵称:
    表情: 高兴 可 汗 我不要 害羞 好 下下下 送花 屎 亲亲
    字数: 0/500 (您的评论需要经过审核才能显示)