zoukankan      html  css  js  c++  java
  • iBATIS笔记之数据映射工作方式

      数据映射定义在一个描述文件中。通过使用iBATIS提供的常规服务,XML描述文件会呈现在客户端对象中。为了访问你的数据地图,应用程序会向客户端对象发出请求并传递所需的statement名称。

    XML描述文件内容(也称Data Map definition file)

    EX3.1  A Simple Data Map

    <?xml version="1.0" encoding="UTF-8" ?>
      <sqlMap namespace="LineItem"
    xmlns="http://ibatis.apache.org/mapping"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
    <!--Type aliases allow you to use a shorter name for long fully qualified class names.-->
        <alias>
            <typeAlias alias="LineItem" type="NPetshop.Domain.Billing.LineItem, NPetshop.Domain" />
        </alias>
        <statements>
            <insert id="InsertLineItem" parameterClass="LineItem">
                INSERT INTO [LinesItem]
                (Order_Id, LineItem_LineNum, Item_Id, LineItem_Quantity, LineItem_UnitPrice)
                VALUES
                (#Order.Id#, #LineNumber#, #Item.Id#, #Quantity#, #Item.ListPrice#)
            </insert>
        </statements>
      </sqlMap>

    此映射从LineItem实例中获取参数传入statements中,因此添加值得sql语句从项目代码中分离出来。而且我们可以直接对应一个库方法:

    Mapper.Instance().Insert(“InsertLineItem”,lineItem);

    EX3.2  A Data Map definition file with some bells and whistles

    <?xml version="1.0" encoding="UTF-8" ?>
     <sqlMap namespace="Product"     //此命名空间和下文中的class有何关联或区别?
    xmlns="http://ibatis.apache.org/mapping"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
    //给type对应的类定义别名
    <alias>
            <typeAlias alias="Product" type="Example.Domain.Product, Example.Domain" />
         </alias>
        //设定缓存参数
        <cacheModels>
            <cacheModel id="productCache" implementation="LRU">   //???
                <flushInterval hours="24"/>   //维持时间上限为24小时
                <property name="CacheSize" value="1000" />   //保存记录数上限为1000条
            </cacheModel>
        </cacheModels>
        //设定结果映射
        <resultMaps>
            //将两个结果列和对象的两个属性建立映射
            <resultMap id="productResult" class="Product">
                <result property="Id" column="Product_Id"/>
                <result property="Description" column="Product_Description"/>
            </resultMap>
        </resultMaps>
        //设定SQL statement
        <statements>
            //”?”对应着参数位置,parameterMap表示参数来源,cacheModel表示缓存参数设定
            <select id="GetProduct" parameterMap="productParam" cacheModel="productCache">
                select * from Products where Product_Id = ?
            </select>
        </statements>
        //设定传入参数
        <parameterMaps>
            //将statement中的?与对象的Id属性建立映射
            <parameterMap id="productParam" class="Product">
                <parameter property="Id"/>
            </parameterMap>
        <parameterMaps>
      </sqlMap>

      许多敏捷型开发人员会先写成EX3.1的形式,之后再添加诸如缓存等等的特性。当你将映射从EX3.1改变成EX3.2的形式之后,虽然变的更长更复杂,但与程序代码之间的耦合降至了最低。

      在一个Data Map定义中可以依你所想添加多个cache models、别名、resultMaps、parameterMaps和statements元素,所有定义会被加载到同一个configuration中,因此你可以在一个DataMap中使用定义在另一个DataMap中的元素。

    EX3.3 Statement element syntax(句法)

    <statement id="statement.name"
        [parameterMap="parameterMap.name"]
        [parameterClass="alias"]
        [resultMap="resultMap.name"]
        [resultClass="class.name|alias"]
        [listClass="class.name|alias"]
        [cacheModel="cache.name"]
        [extends="statement.name"]
    >
        select * from Products where Product_Id = [?|#propertyName#]
        order by [$simpleDynamic$]
    </statement>

    中括号内的项是可选的,甚至有些项之间是互相排斥的。

    1. statement类型

    statement元素可以说是一种万能元素,任何sql statement都可以在此元素标记范围内定义。这很好,但更多特定的元素类型提供了更好的检错及其他的一些功能。如第一章示例中的insert元素。下表中总结了statement不同类型的元素和他们支持的属性、特殊字段。

     

    The six statement-type elements

    Statement Element

    Attributes

    Child Elements

    Methods

    <statement>

    id

    parameterClass

    resultClass

    listClass

    parameterMap

    resultMap

    cacheModel

    All dynamic elements

    Insert

    Update

    Delete

    All query methods

    <insert>

    id

    parameterClass

    parameterMap

    All dynamic elements

                <selectKey>

                <generate>

    Insert

    Update

    Delete

    <update>

    id

    parameterClass

    parameterMap

    extends

    All dynamic elements

                <generate>

    Insert

    Update

    Delete

    <delete>

    id

    parameterClass

    parameterMap

    extends

    All dynamic elements

                <generate>

    Insert

    Update

    Delete

    <select>

    id

    parameterClass

    resultClass

    listClass

    parameterMap

    resultMap

    cacheModel

    extends

    All dynamic elements

                <generate>

    Insert

    Update

    Delete

    <procedure>

    id

    parameterMap

    resultClass

    resultMap

    cacheModel

    All dynamic elements

    Insert

    Update

    Delete

    All query methods

    2.存储过程

        iBATIS将存储过程视作另一种statement类型,使用方法如下所示:

    EX3.4 A Data Map using a stored procedure

    <!-- Microsot SQL Server -->
    <procedure id="SwapEmailAddresses" parameterMap="swap-params">
        ps_swap_email_address
    </procedure>
    ...
    <parameterMap id="swap-params">
        <parameter property="email1" column="First_Email" />
        <parameter property="email2" column="Second_Email" />
    </parameterMap>

    此例的功能是交换数据库的两列中存储的两个Email地址,当然同时也对参数对象进行同样操作。

    NOTE:对于.NET而言,parameterMap是必需的,DBType, parameter direction, size, precision, scale等属性通常由框架依据你的Provider自动去发现。(基于CommandBuilder)如果你的存储过程没有参数,则此属性为可选的。

    3.SQL片段的重用

    <sql id="selectItem_fragment">
        FROM items
        WHERE parentid = #value#
    </sql>
    <select id="selectItemCount" parameterClass="int" resultClass="int">
        SELECT COUNT(*) AS total
        <include refid="selectItem_fragment"/>
    </select>
    <select id="selectItems" parameterClass="int" resultClass="Item">
        SELECT id, name
        <include refid="selectItem_fragment"/>
    </select>

    <sql>标记内的是要重用的片段,<include>标记指示要重用哪个片段。在很多情况下,也可以使用statement标记中的extends属性达到同样的目标。

    4.调解XML标记冲突

           由于在文档中同时使用了SQL语言和XML语言,因此会出现冲突。最常见的冲突就是>和<标记的冲突。SQL语言将此用作运算符,而XML以之为标记。一个简单的解决方法是,构建CDATA元素。

    <statement id=”SelectPersonsByAge” parameterClass=”int” resultClass=”Person”>
        <![CDATA[
        SELECT * FROM PERSON WHERE AGE>#value#
        ]]>
    </statement>

    5.自动生成键

           许多数据库系统支持自动生成主键域,作为一种扩展功能。有些供应商采用预生成模式,有些采用后生成模式。不管哪一种,你都可以通过iBATIS技术中的<insert>元素中插入<selectKey>节的方式,获取一个预生成的主键。

    <!—Microsoft SQL Server IDENTITY Column Example-->
    <insert id=”insert    Product-MS-SQL” parameterClass=”product”>
        insert into PRODUCT (PRD_DESCRIPTION)
        values (#description#)
    <selectKey resultClass=”int” type=”post” property=”id”>
        select @@IDENTITY as value
    </selectKey>
    </insert>

    6.<generate>标记

    使用<generate>标记,可以基于<parameterMap>元素中的参数,自动创建简单的SQL statement节。支持增删改查四种基本语句。

    <parameterMaps>
        <parameterMap id="insert-generate-params">
            <parameter property="Name" column="Category_Name"/>
            <parameter property="Guid" column="Category_Guid" dbType="UniqueIdentifier"/>
         </parameterMap>
        <parameterMap id="update-generate-params" extends="insert-generate-params">
              <parameter property="Id" column="Category_Id" />
        </parameterMap>
        <parameterMap id="delete-generate-params">
             <parameter property="Id" column="Category_Id" />
             <parameter property="Name" column="Category_Name"/>
        </parameterMap>
        <parameterMap id="select-generate-params">
             <parameter property="Id" column="Category_Id" />
             <parameter property="Name" column="Category_Name"/>
             <parameter property="Guid" column="Category_Guid" dbType="UniqueIdentifier"/>
        </parameterMap>
    </parameterMaps>
    
    <statements>
        <update id="UpdateCategoryGenerate" parameterMap="update-generate-params">
            <generate table="Categories" by="Category_Id"/>
        </update>
        <delete id="DeleteCategoryGenerate" parameterMap="delete-generate-params">
            <generate table="Categories" by="Category_Id, Category_Name"/>
        </delete>
        <select id="SelectByPKCategoryGenerate" resultClass="Category" parameterClass="Category" parameterMap="select-generate-params">
            <generate table="Categories" by="Category_Id"/>
        </select>
        <select id="SelectAllCategoryGenerate" resultClass="Category" parameterMap="select-generate-params">
            <generate table="Categories" />
        </select>
        <insert id="InsertCategoryGenerate" parameterMap="insert-generate-params">
            <selectKey property="Id" type="post" resultClass="int">
                select @@IDENTITY as value
            </selectKey>
            <generate table="Categories" />
        </insert>
    </statements>

    NOTE:对应的SQL语句是在DataMapper实例化是就创建的,所以执行时不会有性能上的影响。使用<generate>标记不支持blobs等供应商的特殊类型,也不能简化复杂的SQL语句做到化繁为简,但它却做到了简者更简。

  • 相关阅读:
    windows2008R2下iis7.5中的url重写(urlrewrite)
    C#操作IIS程序池及站点的创建配置实现代码
    C#获取IP及MAC地址 方法
    linq list select用法注意事项
    c#写windows服务 小demo
    C#创建Windows Service(Windows 服务)基础教程
    C# 编写Windows Service(windows服务程序)
    C#中DataTable中的Compute方法使用收集
    SQL Delta实用案例介绍,很好的东西,帮了我不少忙
    Linq中demo,用力看看吧
  • 原文地址:https://www.cnblogs.com/cleverJoe/p/5275428.html
Copyright © 2011-2022 走看看