Ibatisnet Quick Start
准备工作1. 下载ibatis软件包(http://ibatis.apache.org/dotnetdownloads.html)。2. 创建测试数据库,并在数据库中创建一个Person 表,其中包含三个字段:Name Type SizePER_ID Long Integer 4 not nullPER_FIRST_NAME nvarchar 40 not nullPER_LAST_NAME nvarchar 40 not nullPER_BIRTH_DATE DateTime 8PER_WEIGHT_KG float 8PER_HEIGHT_M float 83. 为了在开发过程更加直观,我们需要将ibatisnet日志打开以便观察ibatinets运作的细节。ibatisnet采用IBatisNet.Common.Logging.Log4Net,就是使用Log4Net纪录日志的包装。在Web.config中增加下面的配置内容:<configSections> <sectionGroupname='iBATIS'> <sectionname='logging'type='IBatisNet.Common.Logging.ConfigurationSectionHandler, IBatisNet.Common' /> </sectionGroup> <sectionname='log4net'type='log4net.Config.Log4NetConfigurationSectionHandler, log4net' /></configSections><iBATIS> <logging> <logFactoryAdaptertype='IBatisNet.Common.Logging.Impl.Log4NetLoggerFA, IBatisNet.Common.Logging.Log4Net'> <argkey='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 --> <appendername='RollingLogFileAppender'type='log4net.Appender.RollingFileAppender'> <paramname='File'value='log.txt' /> <paramname='AppendToFile'value='true' /> <paramname='MaxSizeRollBackups'value='2' /> <paramname='MaximumFileSize'value='100KB' /> <paramname='RollingStyle'value='Size' /> <paramname='StaticLogFileName'value='true' /> <layouttype='log4net.Layout.PatternLayout'> <paramname='Header'value='[Header]\r\n' /> <paramname='Footer'value='[Footer]\r\n' /> <paramname='ConversionPattern'value='%d [%t] %-5p %c [%x] - %m%n' /> </layout> </appender> <appendername='ConsoleAppender'type='log4net.Appender.ConsoleAppender'> <layouttype='log4net.Layout.PatternLayout'> <paramname='ConversionPattern'value='%d [%t] %-5p %c [%x] <%X{auth}> - %m%n' /> </layout> </appender> <!-- Set root logger level to ERROR and its appenders --> <root> <levelvalue='DEBUG' /> <appender-refref='RollingLogFileAppender' /> <appender-refref='ConsoleAppender' /> </root> <!-- Print only messages of level DEBUG or above in the packages --> <loggername='IBatisNet.DataMapper.Configuration.Cache.CacheModel'> <levelvalue='DEBUG' /> </logger> <loggername='IBatisNet.DataMapper.Configuration.Statements.PreparedStatementFactory'> <levelvalue='DEBUG' /> </logger> <loggername='IBatisNet.DataMapper.LazyLoadList'> <levelvalue='DEBUG' /> </logger> <loggername='IBatisNet.DataAccess.DaoSession'> <levelvalue='DEBUG' /> </logger> <loggername='IBatisNet.DataMapper.SqlMapSession'> <levelvalue='DEBUG' /> </logger> <loggername='IBatisNet.Common.Transaction.TransactionScope'> <levelvalue='DEBUG' /> </logger> <loggername='IBatisNet.DataAccess.Configuration.DaoProxy'> <levelvalue='DEBUG' /> </logger> </log4net> 构建IBatisNet基础代码IBatisNet 基础代码包括:1. IBatisNet 实例配置一个典型的配置文件如下(具体配置项目的含义见后):<?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' style="COLOR: black" <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' resultparameterstyle="COLOR: black" 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' parameter> <selectKey property='Id' type='post' resultstyle="COLOR: black" ${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' parameterstyle="COLOR: black" <![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' parameterstyle="COLOR: black" delete from Person where PER_ID = #Id# </delete> </statements></sqlMap> 从上面的映射文件可以看出,通过<insert>、<delete>、<update>、<select>四个节点,我们分别定义了针对Person 对象的增删改查操作。在这四个节点中,我们指定了对应的SQL 语句,以update节点为例:……<update id=' UpdatePerson' ⑴parameter⑵<![CDATA[⑶ update Person set ⑷ PER_FIRST_NAME =#FirstName#,⑸ PER_LAST_NAME =#LastName#, ⑹ PER_BIRTH_DATE =#BirthDate#, PER_WEIGHT_KG=#WeightInKilograms#, PER_HEIGHT_M=#HeightInMeters# wherePER_ID = #Id#⑺]]></update>……⑴ ID指定了操作ID,之后我们可以在代码中通过指定操作id 来执行此节点所定义的操作,如:SqlMap.Update('UpdatePerson', person);ID设定使得在一个配置文件中定义两个同名节点成为可能(两个update节点,_____以不同id区分)⑵ parameterClass指定了操作所需的参数类型,此例中update 操作以IBatisNetDemo.Domain.Person类型的对象作为参数,目标是将提供的Person实例更新到数据库。parameterstyle="COLOR: black"类的别名,别名可通过typeAlias节点指定,如示例配置文件中的:<typeAlias alias='Person' type='IBatisNetDemo.Domain.Person,IBatisNetDemo' />⑶ <![CDATA[……]]>通过<![CDATA[……]]>节点,可以避免SQL 中与XML 规范相冲突的字符对XML映射文件的合法性造成影响。⑷ 执行更新操作的SQL,这里的SQL 即实际数据库支持的SQL 语句,将由IBatisNet填入参数后交给数据库执行。⑸ SQL中所需的用户名参数,“# FirstName #”在运行期会由传入的Person对象的FirstName属性填充。⑹ SQL 中所需的用户性别参数“# LastName #”,将在运行期由传入的user 对象的LastName属性填充。⑺ SQL中所需的条件参数“#id#”,将在运行期由传入的Person对象的Person属性填充。对于这个示例,IBatisNet在运行期会读取id 为“UpdatePerson”的update节点的SQL定义,并调用指定的user对象的对应getter方法获取属性值,并用此属性值,对SQL中的参数进行填充后提交数据库执行。此例对应的应用级代码如下,其中演示了IBatisNet SQLMap的基本使用方法:private static SqlMapper sqlMap;public BaseService(){ Assembly assembly = Assembly.Load('IBatisNetDemo'); Stream stream = assembly.GetManifestResourceStream('IBatisNetDemo.sqlmap.config'); DomSqlMapBuilder builder = new DomSqlMapBuilder(); sqlMap = builder.Configure( stream ); };其中,SqlMapper是IbatisNet运作的核心,所有的操作均通过SqlMapper实例完成。这个例子中我将所有的配置文件按照资源文件方式存放,所以从程序集去加载sqlmap.config文件。可以看出,对于应用层而言,程序员面对的是传统意义上的实体(数据)对象,而不是ADO.NET中的DataReader或者DataTable/DataSet,这使得我们控制最终的数据操作方式,通过Sql的优化来获得最佳的数据库执行效能,这在依赖SQL自动生成的“全自动”ORM机制中是难以实现的。
原文在 cnblogs: http://www.cnblogs.com/shanyou/articles/376094.html