iBATIS typeHandler selectKey

typeHandler 是针对把数据库里面的某列的数据类型转换的应用程序中的数据类型,简单的说就是把 type=>dbType  反之把dbType=>type. 例如数据库某列的内容是longbolb类型的,实际存的就是byte[] 数组. 那我repository 通过select 以后要把longbolb 直接返回stream(流) 因为IBatis直接返回的是byte[] 那么我们就要把通过typeHandler 把byte[] 再转换成stream.

如下面例子(msyql)

表(t_temp)

列名   数据类型
_Id

char(36)

_Content

longblob

实体类

public class Temp {

    public Guid Id { get; set; }

    public Stream Content { get; set; }
}

这个时候就要把数据库的content字段转换成流.typehanlder 就上场了.转换很简单自己写一个类实现IBatis提供的接口ITypeHandlerCallback就可以了如下

public class StreamTypeHandler : ITypeHandlerCallback
    {
        public void SetParameter(IParameterSetter setter, object parameter)
        {
            if (parameter is Stream)
            {
                var s = (Stream) parameter;
                var data = new byte[s.Length];
                s.Read(data, 0, data.Length);

                setter.Value = data;
            }
        }

        public object GetResult(IResultGetter getter)
        {
            var bytes = getter.Value as byte[];
            if (bytes != null)
            {
                var stream = new MemoryStream(bytes);
                return stream;
            }


            return null;
        }

        public object ValueOf(string s)
        {
            return s;
        }

        public object NullValue
        {
            get { return null; }
        }
    }

里面的get和set 就是把数据库返回的类型转换成想要的数据类型.

有了typehanler 就是在什么地方用的问题了.照API上的说的有两个地方可以放.

1,sqlmap.config 里面的

<typeHandlers>
    <typeHandler type="System.IO.Stream" dbType="BLOB" callback="HS.Core.Utils.StreamTypeHandler, HS.Core" />
  </typeHandlers>

在sqlmap.config里面配置以后在你要用的任意一个xxx.map.xml 文件里面都的parameterMap 或者 resultMap 标签就都可以使用了.例如

<resultMap id="temp_map" class="HS.Core.Temp,HS.Core">
      <result property="id" type="guid" column="_Id"/>
      <result property="Content" type="System.IO.Stream" column="_Content"/>
    </resultMap>

2,在xxx.map.xml中使用 typehandler 指定.

<resultMap id="temp_map" class="HS.Core.Temp,HS.Core">
      <result property="id" type="guid" column="_Id"/>
      <result property="Content" typeHandler="HS.Core.Utils.StreamTypeHandler, HS.Core" column="_Content"/>
    </resultMap>

之前,自己按照API的例子,做了一个Id的GUID的typeHandler.然后插入数据库.

 <alias>
    <typeAlias alias="Guidchar" type="HS.Core.Utils.GuidVarcharTypeHandlerCallback,HS.Core"/>
  </alias>
  <parameterMaps>
    <parameterMap id="terminal_pare" class="HS.Core.Terminal,HS.Core">
      <parameter property="Id" column="_ID" typeHandler="Guidchar"/>
      <parameter property="Name" column="_Name"/>
      <parameter property="Key" column="_Key"/>
      <parameter property="Ip" column="_IP"/>
      <parameter property="Port" column="_Port"/>
      <parameter property="AeTitle" column="_AeTitle"/>
      <parameter property="Place" column="_Address"/>
      <parameter property="Remark" column="_Remark"/>
      <parameter property="UpdateTime" column="_UpdateTime"/>
      <parameter property="State" column="_State"/>
    </parameterMap>
 </parameterMaps>

然后插入数据库

<insert id="InsertThermal" parameterMap="thermal_pare">
      <selectKey property="Id" resultClass="guid" type="post">
        <![CDATA[
        select uuid() as value;
        ]]>
      </selectKey>
      <generate table="hs_printers"/>
    </insert>

这里用了自动列,(selectKey)在运行时,死活说类型转换错误.

原来:selectKey 不能是 typehandler的....IBatis默认是支持guid类型的.所以自己是脱了裤子放屁....

原文地址:https://www.cnblogs.com/Dtscal/p/4897793.html