准备工作
1.
下载
ibatis
软件包(
http://ibatis.apache.org/dotnetdownloads.html
)。
2.
创建测试数据库,并在数据库中创建一个
Person 表,其中包含三个字段:
Name Type Size
PER_ID Long Integer 4
not null
PER_FIRST_NAME nvarchar 40 not null
PER_LAST_NAME nvarchar 40 not null
PER_BIRTH_DATE DateTime 8
PER_WEIGHT_KG float 8
PER_HEIGHT_M float 8
3. 为了在开发过程更加直观,我们需要将ibatisnet日志打开以便观察ibatinets运作的细节。
ibatisnet采用
IBatisNet.Common.Logging.Log4Net,就是使用Log4Net纪录日志的包装。在Web.config中增加下面的配置内容:
<
configSections
>
<
sectionGroup
name
=
"iBATIS">
<
section
name
=
"logging"type="IBatisNet.Common.Logging.ConfigurationSectionHandler, IBatisNet.Common" />
</
sectionGroup
>
<
section
name
=
"log4net"type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</
configSections
>
<
iBATIS
>
<
logging
>
<
logFactoryAdapter
type
=
"IBatisNet.Common.Logging.Impl.Log4NetLoggerFA, IBatisNet.Common.Logging.Log4Net">
<
arg
key
=
"configType"value="inline" />
<arg
key
="showLogName" value="true" />
<arg
key
="showDataTime" value="true" />
<arg
key
="level" value="ALL" />
<arg
key
="dateTimeFormat" value="yyyy/MM/dd HH:mm:ss:SSS" />
</
logFactoryAdapter
>
</
logging
>
</
iBATIS
>
<!--
This section contains the log4net configuration settings
-->
<
log4net
>
<!--
Define some output appenders
-->
<
appender
name
=
"RollingLogFileAppender"type="log4net.Appender.RollingFileAppender">
<
param
name
=
"File"value="log.txt" />
<
param
name
=
"AppendToFile"value="true" />
<
param
name
=
"MaxSizeRollBackups"value="2" />
<
param
name
=
"MaximumFileSize"value="100KB" />
<
param
name
=
"RollingStyle"value="Size" />
<
param
name
=
"StaticLogFileName"value="true" />
<
layout
type
=
"log4net.Layout.PatternLayout">
<
param
name
=
"Header"value="[Header]/r/n" />
<
param
name
=
"Footer"value="[Footer]/r/n" />
<
param
name
=
"ConversionPattern"value="%d [%t] %-5p %c [%x] - %m%n" />
</
layout
>
</
appender
>
<
appender
name
=
"ConsoleAppender"type="log4net.Appender.ConsoleAppender">
<
layout
type
=
"log4net.Layout.PatternLayout">
<
param
name
=
"ConversionPattern"value="%d [%t] %-5p %c [%x] <%X{auth}> - %m%n" />
</
layout
>
</
appender
>
<!--
Set root logger level to ERROR and its appenders
-->
<
root
>
<
level
value
=
"DEBUG" />
<
appender-ref
ref
=
"RollingLogFileAppender" />
<
appender-ref
ref
=
"ConsoleAppender" />
</
root
>
<!--
Print only messages of level DEBUG or above in the packages
-->
<
logger
name
=
"IBatisNet.DataMapper.Configuration.Cache.CacheModel">
<
level
value
=
"DEBUG" />
</
logger
>
<
logger
name
=
"IBatisNet.DataMapper.Configuration.Statements.PreparedStatementFactory">
<
level
value
=
"DEBUG" />
</
logger
>
<
logger
name
=
"IBatisNet.DataMapper.LazyLoadList">
<
level
value
=
"DEBUG" />
</
logger
>
<
logger
name
=
"IBatisNet.DataAccess.DaoSession">
<
level
value
=
"DEBUG" />
</
logger
>
<
logger
name
=
"IBatisNet.DataMapper.SqlMapSession">
<
level
value
=
"DEBUG" />
</
logger
>
<
logger
name
=
"IBatisNet.Common.Transaction.TransactionScope">
<
level
value
=
"DEBUG" />
</
logger
>
<
logger
name
=
"IBatisNet.DataAccess.Configuration.DaoProxy">
<
level
value
=
"DEBUG" />
</
logger
>
</
log4net
>
构建IBatisNet基础代码
IBatisNet
基础代码包括:
1
.
IBatisNet
实例配置
iBatis基本的运行环境配置主要由两个文件组成,分别是SqlMap.config和Provider.config。它们是必需的两个配置文件,基中SqlMap.config的功能类似于web.config或者app.config,是iBatis核心的配置文件,它的存放路径也跟应用程序配置文件一样,必须放在应用程序的运行目录下并且它的文件名是保留的,不可改变的。而Provider.config是一个数据驱动提供类的配置,它的文件名是可以随意改变的,因为通过SqlMap.config的一个配置节可以配置它的引用。
SqlMap.config包括以下一些主要的配置节,根据需要,有的配置节并不是必须的:
1. properties :可以根据需要配置一些常量属性。如果这些属性有很多的话可以单独写一个文件里面,再通过resource(或url, embedded分别是引用url和编译在程序中的资源文件)属性引用进来。如:
<properties resource="../../database.config">
<property key="useStatementNamespaces" value="false"/>
</properties>
这个配置节是可选的。
2. settings:包括有三个配置段:
<setting useStatementNamespaces="${useStatementNamespaces}"/>
<setting cacheModelsEnabled="true"/>
<setting validateSqlMap="false"/>
useStatementNamespaces:在文档中说明它的作用是配置在使用语句ID的时候要不要加命名空间,例中${useStatementNamespaces}就是使用properties中的一个属性,默认是false。
cacheModelsEnabled 是配置要不要启用iBatis的缓存模型,默认是true。
validateSqlMap 是配置要不要启示验证映射文件,默认是false。
3. providers :配置数据驱动提供类配置文件的路径和文件名。
<providers resource="providers.config"/>
4. database : 数据库的信息,包括使用哪些数据库驱动和数据连接字符串的配置。
<database>
<!-- Optional ( default ) -->
<provider name="sqlServer1.1"/>
<dataSource name="iBatisNet"
connectionString=""/>
</database>
5. alias : 类型别名的配置,为了使用更方便的使用类(类名更短),就需在这里进行别名的配置。
<alias>
<typeAlias alias="ArrayList" type="System.Collections.ArrayList,mscorlib"/>
</alias>
6. typeHandlers :这个就相对比较复杂些了,到目前我也没有使用到。从字面上理解,它是一个类型的处理器,它的作用是当你使用的数据库当中有iBatis不支持或不认识的字段(或者不希望默认的处理方式),那就可以为它取一个名字,并且指定对应的.NET类型来处理它。
<typeHandlers>
<typeHandler type="bool" dbType="Varchar" callback="OuiNonBool"/>
</typeHandlers>
7. sqlMaps :用来包含当前已经写好的,并且需要用到的数据类映射文件。
<sqlMaps>
<!-- <sqlMap url="E:/Projet/iBatis/trunk/cs/mapper/IBatisNet.DataMapper.Test/${directory}/MSSQL/SqlClient/Account.xml"/> -->
<sqlMap resource="Mappers/ContentMapper.xml"/>
<!-- Rem : If used as embbeded Resources, use
<sqlMap embedded="Maps.MSSQL.SqlClient.Account.xml, IBatisNet.DataMapper.Test"/>-->
</sqlMaps>
以上就是Sqlmap.config的基本内容了。注意,以上凡是涉及到引用外部文件的都支持resouce,url,embedded 三种方式。
一个典型的配置文件如下(具体配置项目的含义见后):
<?xml version="1.0" encoding="utf-8"?>
<sqlMapConfig xmlns="http://ibatis.apache.org/dataMapper" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
<!-- Rem : If used via a DataAccess context, properties tag will be ignored
<properties resource="../../database.config"/> -->
<properties embedded="database.config, IBatisNetDemo"/>
<settings>
<setting useStatementNamespaces="${useStatementNamespaces}"/>
<setting cacheModelsEnabled="true"/>
<setting validateSqlMap="false"/>
</settings>
<!-- Optional if resource -->
<providers embedded="providers.config,IBatisNetDemo"/>
<!-- ==== SqlClient configuration ========= -->
<!-- Rem : If used via a DataAccess context, database tag will be ignored -->
<database>
<!-- Optional ( default ) -->
<provider name="sqlServer1.1"/>
<dataSource name="iBatisNet" connectionString="data source=localhost;database=Northwind;user id=sa;password=;connection reset=false;connection lifetime=5; min pool size=1; max pool size=50"/>
</database>
<sqlMaps>
<!-- user via embedded-->
<sqlMap embedded="Map.SqlClient.Person.xml,IBatisNetDemo"/>
</sqlMaps>
</sqlMapConfig>
2. PO(Plain Ordinary Object)
下面是我们用作示例的一个PO:
[Serializable]
public class Person
{
private int id;
private string firstName;
private string lastName;
private DateTime? birthDate;
private double? weightInKilograms;
private double? heightInMeters;
public Person() { }
public int Id
{
get { return id; }
set { id = value; }
}
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
public string LastName
{
get { return lastName; }
set { lastName = value; }
}
public DateTime? BirthDate
{
get { return birthDate; }
set { birthDate = value; }
}
public double? WeightInKilograms
{
get { return weightInKilograms; }
set { weightInKilograms = value; }
}
public double? HeightInMeters
{
get { return heightInMeters; }
set { heightInMeters = value; }
}
}
3.映射文件
与Hibernate 不同。因为需要人工编写SQL 代码,IBatisNet 的映射文件一般采
用手动编写(通过Copy/Paste,手工编写映射文件也并没想象中的麻烦)。
针对上面PO 的映射代码如下:
<?xml version="1.0" encoding="utf-8" ?>
<sqlMap namespace="Person" xmlns="http://ibatis.apache.org/mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
<alias>
<typeAlias alias="Person" type="IBatisNetDemo.Domain.Person,IBatisNetDemo" />
</alias>
<resultMaps>
<resultMap id="SelectAllResult" class="Person">
<result property="Id" column="PER_ID" />
<result property="FirstName" column="PER_FIRST_NAME" />
<result property="LastName" column="PER_LAST_NAME" />
<result property="BirthDate" column="PER_BIRTH_DATE" />
<result property="WeightInKilograms" column="PER_WEIGHT_KG" />
<result property="HeightInMeters" column="PER_HEIGHT_M" />
</resultMap>
</resultMaps>
<statements>
<select id="SelectAllPerson" resultMap="SelectAllResult">
select
PER_ID,
PER_FIRST_NAME,
PER_LAST_NAME,
PER_BIRTH_DATE,
PER_WEIGHT_KG,
PER_HEIGHT_M
from PERSON
</select>
<select id="SelectByPersonId" resultClass="Person" parameterClass="int">
select
PER_ID,
PER_FIRST_NAME,
PER_LAST_NAME,
PER_BIRTH_DATE,
PER_WEIGHT_KG,
PER_HEIGHT_M
from PERSON
where PER_ID = #value#
</select>
<insert id="InsertPerson" parameterclass="Person" >
<selectKey property="Id" type="post" resultClass="int">
${selectKey}
</selectKey>
insert into Person
( PER_FIRST_NAME,
PER_LAST_NAME,
PER_BIRTH_DATE,
PER_WEIGHT_KG,
PER_HEIGHT_M)
values
(#FirstName#,#LastName#,#BirthDate#, #WeightInKilograms#, #HeightInMeters#)
</insert>
<update id="UpdatePerson"
parameterclass="Person">
<![CDATA[ update Person set
PER_FIRST_NAME =#FirstName#,
PER_LAST_NAME =#LastName#,
PER_BIRTH_DATE =#BirthDate#,
PER_WEIGHT_KG=#WeightInKilograms#,
PER_HEIGHT_M=#HeightInMeters#
where
PER_ID = #Id# ]]>
</update>
<delete id="DeletePerson" parameterclass="Person">
delete from Person
where
PER_ID = #Id#
</delete>
</statements>
</sqlMap>
从上面的映射文件可以看出,通过<insert>、<delete>、<update>、
<select>四个节点,我们分别定义了针对Person 对象的增删改查操作。在这
四个节点中,我们指定了对应的SQL 语句,以update节点为例:
……
<update id=" UpdatePerson" ⑴
parameterClass="Person"> ⑵
<![CDATA[⑶
update Person set ⑷
PER_FIRST_NAME =#FirstName#,⑸
PER_LAST_NAME =#LastName#, ⑹
PER_BIRTH_DATE =#BirthDate#,
PER_WEIGHT_KG=#WeightInKilograms#,
PER_HEIGHT_M=#HeightInMeters#
where
PER_ID = #Id# ⑺]]>
</update>
……
⑴ ID
指定了操作ID,之后我们可以在代码中通过指定操作id 来执行此节点所定
义的操作,如:
SqlMap.Update("UpdatePerson", person);
ID设定使得在一个配置文件中定义两个同名节点成为可能(两个update节
点,_____以不同id区分)
< div align="left">
⑵ parameterClass