iBatis 基础知识
1. 与VS集成(智能感应)
每一个配置文件(SqlMap.config,SQL 映射文件,providers.config)都与一个XML Schema文件关联。这种关联的好处在于,可以对文档进行验证(在运行时完成),使用编辑器的特性如智能感知/内容自动完成。
要在VS.NET的XML编辑器中的Schema和我们的配置文件之间建立关联,应该将Schema文件(SqlMap.xsd,SqlMapConfig.xsd,providers.xsd)添加到VS.NET项目或者VS.NET安装目录。显然第二种选择会让我们一劳永逸。VS.NET安装目录可能是:
C:\Program Files\Microsoft Visual Studio 8\Xml\Schemas(VS.NET 2005)
或
C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Packages\schemas\xml(VS.NET 2003)
或
C:\Program Files\Microsoft Visual Studio .NET\Common7\Packages\schemas\xml(VS.NET 2002)。
将Schema文件注册到VS.NET后,我们就可以在VS.NET中享用智能感知和配置文档验证了。
2. 三个配置文件说明
(1) 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" >
<properties >
<property resource="properties.config"/> //标准的属性文件
<property resource="properties.config"/>
<property resource="properties.config"/>
<property key="host.config" key="ibatis.com" />
</properties>
<settings>
<setting useStatementNamespaces="false"/>
<setting cacheModelsEnabled="true"/>
<setting validateSqlMap="false"/>
</settings>
<providers embedded="resources.providers.config, IBatisNet.Test"/>
<database>
// 连接SQL Server
<provider name="sqlServer1.1"/>
<dataSource name="NPetshop"
connectionString="data source=(local)\NetSDK;database=${database};
user id=${username};password=${password};"/>
//连接Oracle
<provider name="oracleClient1.0"/>
<dataSource name="iBatisNet"
connectionString="Data Source=${datasource};User Id=${userid};Password=${password}"/>
</database>
<typeHandlers>
<typeHandler type="bool" dbType="Varchar" callback="YesNoBool"/>
</typeHandlers>
<sqlMaps>
<sqlMap resource="${root}Maps/Account.xml"/>
<sqlMap resource="${root}Maps/Category.xml"/>
<sqlMap resource="${root}Maps/Product.xml"/>
</sqlMaps>
</sqlMapConfig>
节点说明:
<properties>元素
可以同时指定几个不同属性文件,或者使用<property>元素直接向SqlMap.config文件添加键值对
<property key="host.config" key="ibatis.com" />
配置文件中的同一个值会出现在多处。通常情况下,我们将程序在服务器间迁移时,某些配置选项的值要进行修改。为了更好地管理这些配置选项的值,我们可指定一个标准的属性文件(含有name=value对),将DataMapper的部分配置转移到其中。在属性文件中的值将成为shell变量,可以在DataMapper配置文件和Data Map定义文件中使用。例如,如果属性文件中包含了
<?xml version="1.0" encoding="utf-8" ?>
<settings>
<add key="UserId" value="sa" />
</settings
那么在DataMapper配置文件(SqlMap.config)中的任何元素都可以使用变量${UserId}来插入值”sa”。
特性说明:
resource |
指定要从应用程序根目录加载的属性文件。 <properties resource="properties.config" /> |
url |
指定属性文件的绝对路径 <properties url="c:\Web\MyApp\Resources\properties.config" /> |
embedded |
指定要从程序集的资源中加载的属性文件。该特性的语法为’[extendednamespace.]filename, assemblyName’。 |
key |
定义一个属性键(变量)名 Key="username" |
<providers>元素
iBATIS的DataMapper发行包包含了一个标准的providers.config,其中一共有13种Provider元素
如果您使用的是SQL Server 2005,那么可以打开MARS(Multiple Active Result Set)选项,即设置allowMARS=”true”,并在连接字符串中添加MultipleActiveResultSets=true。
providers.config文件位于DataMapper发行包的根目录。
检查enable 特性值
resource |
指定providers.config文件相对于应用程序根目录的相对路径。因为根目录因项目类型而有所不同,因此最好使用属性文件来表示相对路径。 resource=”${root}providers.config” |
url |
指定providers.config文件的绝对路径。 url="c:\Web\MyApp\Resources\ providers.config" /> -or- |
embedded |
指定要从程序集的资源中加载的providers.config文件。该特性的语法为’[extendednamespace.]filename, assemblyName’。 embedded=”Resources.providers.config, MyApp.Data” |
<settings>元素
在<settings>元素中我们可以配置这些选项,对相应的DataMapper实例进行优化。每一个<settings>特性都有一个默认值,因此,您可以省略其中的特性甚至是整个<settings>元素。<settings>的特性值及其含义为:
cacheModelsEnabled |
该选项在全局范围内启用或禁用一个DataMapper实例的所有Cache Model。这在调试时可能会很方便。 Example:cacheModelsEnabled=”true” 默认值 :true(启用) |
useStatementNamespaces |
如果启用该选项,那么在引用映射语句时必须总是使用完全限定的名称,即Sql Map的命名空间和语句的id。如queryForObject(“Namespace.statementId”); Example:useStatementNamespaces=”false” 默认值 :false(禁用) |
validateSqlMap |
该选项在全局范围内启用或禁用了针对Sql Map文件的校验。这在调试时可能会很方便。 Example:validateSqlMap=”true” 默认值 :false(禁用) |
useReflectionOptimizer |
该选项在全局范围内启用或禁用在访问C#对象属性或字段对反射的使用。反射优化器会提供获取、生成、实例化参数和返回结果对象的类型。 Example:useReflectionOptimizer =”true” 默认值 :true(启用) |
<tyeAlias>元素
alias |
该元素的唯一性名称。 alias=”Category” |
type |
要代替类型的完全限定名称。 type="IBatisInAction.Domain.Category, IBatisInAction.Domain" |
<typeHandle>
<typeHandler>元素用于对自定义类型处理器(Custom Type Handler)的配置。Custom Type Handler扩展了DataMapper的功能,可以处理如下的情形:特定于数据库Provider的类型,数据库Provider未处理的类型,在特定程序中特殊设计。
<typeHandler type="guid" dbType="Varchar" callback="GuidVarchar" />
(2)SqlMap.xml
映射语句类型
语句类型 |
特性 |
子元素 |
用途 |
详细内容参考 |
<select> |
id parameterClass resultClass listClass parameterMap resultMap cacheModel extends |
所有动态元素 |
查询数据 |
4.2节; |
<insert> |
id parameterClass parameterMap |
所有动态元素<selectKey> <generate> |
插入数据 |
5.2节; |
<update> |
id |
所有动态元素 |
更新数据 |
5.3节; |
<delete> |
id |
所有动态元素 |
删除数据 |
5.3节; |
<procedure> |
id |
所有动态元素 |
执行存储过程 |
5.5节; |
<statement> |
id parameterClass resultClass listClass parameterMap resultMap cacheModel |
所有动态元素 |
可以包含任意类型的语句,几乎无所不能 |
6.3.1节; |
3. SqlMap 的API
ISalMapper 接口方法很多,常用的有:
(1).QueryforObject()方法
从数据库中获取单行数据
object QueryForObject(string statementName, object parameterObject);
(2)QueryForList() 方法
得到多行记录
IList QueryForList(string statementName, object parameterObject);
(3) QueryForDictionary() 方法
QueryForMap() java版
QueryForMap()方法从数据库获取一行或多行记录,将结果转换为C#对象,然后放在一个IDictionary(而不是IList)中返回。它有两个版本:
4. 映射语句学习
(1)<select>
#:
Select …… from where id=#value# 或者 id=#value:int# 设置类型
#表示该语句接收一个简单的参数
$占位符
表示使用文本替换 语法,讲一个值直接插入SQL
SQL非法注入
<select id="getByLikeCity" resultClass="Account">
select
若是传入burg’; drop table Account; --
(使用$)
自动结果映射
使用情况:单列查询,固定列列表查询以及动态列列表查询
<select id="getAccountRemapExample" resultClass="hashtable" >
accountId = #accountId#
结果映射
<result Map>特性
<resultMap id="get-product-result" class="product">
<result property="id" column="PRD_ID"/>
<result property="description" column="PRD_DESCRIPTION"/>
<result property="subCode" column="PRD_SUB_CODE" nullValue="-9999" />
</resultMap>
ResultMap
特性 |
描述 |
id |
必需的,为Result Map提供唯一标识。 |
class |
可选的,指定当前Result Map使用的类。可以设置为类的完整名称或别名。 |
extends |
可选的,指定要进行“继承”的Result Map |
子元素特性
特性 |
描述 |
property |
必需的,表示结果对象的属性名称。 |
column |
必需的,指定结果集中的列名称,使用该列来产生当前属性。 |
columnIndex |
可选的,指定列的索引,该特性对性能会有轻微的帮助。99%的应用程序中是不需要的,而且它还会牺牲可维护性和可读性。另外一些provider中,该特性可能对性能没有任何帮助。 |
dbType |
用于显式地指定列的类型。由于CLR和数据库中类型的不一致,该特性比较有用,尤其是对datetime和string类型。 |
type |
用于显式地指定结果对象属性的CLR类型。通常属性的类型可通过反射获得,但在映射到Hashtable之类的对象时就无能为力了。 |
隐式的结果映射
如果SQL语句返回的列与结果对象的属性相匹配,那么显式的Result Map就不再必要了
<statement id="selectProduct" resultClass="Product">
select
id,
description
from PRODUCT
where id = #value#
</statement>
如果列名和属性名称不一致,可以使用列的别名
<statement id="selectProduct" resultClass="Product">
select
PRD_ID as id,
PRD_DESCRIPTION as description
from PRODUCT
where PRD_ID = #value#
</statement>
当然,此时就不能指定dbType、nullValue或者其它的特性了
返回IDictionary类型的结果
需要的只是包含数据的键/值列表,Result Map可以生成一个IDictionary类型的实例,其语法与普通的POCO对象一样:
<resultMap id="select-product-result" class="hashtable">
<result property="id" column="PRD_ID"/>
<result property="code" column="PRD_CODE"/>
<result property="description" column="PRD_DESCRIPTION"/>
<result property="suggestedPrice" column="PRD_SUGGESTED_PRICE"/>
</resultMap>
在这个例子中,iBATIS会为每一行创建一个Hashtable实例,这个实例包含了返回的数据,属性名id、code等均作为Hashtable的key,列的值则作为Hashtable的值。
也可以使用IDictionary类型作为隐式的Result Map:
<statement id="selectProductCount" resultClass="hashtable">
select * from PRODUCT
</statement>