版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、.; HYPERLINK http:/ ibatisnet系列(一) 总览废话一翻后,进入今天的正题。今天的主题是Introduction,非官方正式介绍的中文版,更多详细的介绍请参阅官方文档。我们要使用它就必须要知道它是干什么用的,能为我们做哪些工作,开发效率如何,执行效率如何,技术难度怎么样。提到iBatis,大家可能会与ORM技术联系起来。是的,没错,它与ORM技术有一定程度上的联系,但是更确切地讲,它并不是一种很正统的ORM解决方案。因为它不像NHibernate那样,具备全自动的数据操作,包括查询,插入,更新,删除;也没有像它那样,与数据库的约束关系有紧密的联系(对NHibernat
2、e的了解不多,如果有不妥之处,希望能留下你们的臭鸡蛋,等着下回用)。iBatis为我们提供了一种更为灵活的方便的可控的方式去实现类ORM的解决方案。我们需要自己来控制SQL语句,这样做有好处在于,我们可以更灵活地根据我们的需求,编写更加具备性能,功能优势的SQL语句,但它的缺点同样明显,我们还是需要管理和编写SQL语句。但是值得感到高兴的是,我们只需要提供这些SQL语句,和为它提供它所需的参数外,接下来的事情就无需我们参与了。这也是iBatis最核心的功能,也是它为我们所做最多的工作了。根据配置好的SQL语句和参数条件,它会动态生成一条可执行的SQL语句,然后根据具体传进来的参数值,为这些SQ
3、L参数提供不同的具体值。然后根据配置好的数据访问驱动,自动为DbCommand添加DbParameter,自动执行SQL语句,使用IDataReader返回出数据集,生成并返回一个或多个强类型数据类对象(数据集用IList集合对象表示)。我曾经在Community Server中也见过类似的返回强类型数据对象的实现,但是需要很多的代码,与直接返回DataTable相比,重复代码会更多。所有的这些在iBatis中,只需要提供一个配置文件,调用它提供的SqlMapper实例对象中的方法就可以很简单容易地实现了。当然你也许会说,那这样如果系统比较大的话,可能就需要很多的配置文件了。是的,又陷了另一个
4、极端了。怎么办呢?没办法,鱼和熊掌不能兼得啊。这里还不得不重点强调一下,如果你是经常在存储过程中拼接SQL语句的话,那我就更加推荐你马上就开始使用iBatis吧。提到数据操作,就不能不提到数据的安全性和完整性问题了,也就是数据操作的事务问题。如果你是直接使用A进行事务操作的话,那您可能需要写更多的代码了,当然我们可以使用Enterprise Library来简化我们的工作。那现在通过一段简单的代码也看一下在iBatis中该如何实现事务吧:using ( IDalSession session = sqlMap.BeginTransaction() ) Item item = (Item) sq
5、lMap.QueryForObject(getItem, itemId); item.Description = newDescription; sqlMap.Update(updateItem, item); session.Complete(); / Commit就这么简单的代码,它就会帮我们自动管理事务了。这期间如果出现异常,我们仍然可以捕获到异常信息。OK,通过上面的介绍,我们已经能够了解到一个大概了。总结一下,它帮我们自动管理和执行SQL语句,并且返回强类型的数据对象。从上面的一段简单的代码中,你可能已经感觉到了它的使用有多么的简单!并且如果需要的还能够返回生成的DbCommand,
6、支持我们通过它返回DataTable或者其它的Ado操作返回。但是,这时你会马上产生另一个疑虑了,我们的工作还是很多啊,比如,编写数据类和配置文件可能工作量并不亚于直接使用A返回DataTable所写的代码,并且会更加的没有技术含量。所以,对于这些的代码,我们尽量能通过一些代码生成工具(我是使用CodeSmith)自动生成大部分,然后再根据我们需要进行修改。再来看看执行效率吧,尽管iBatis或多或少用到反射技术,但由于使用配置文件的形式,性能影响已经降到最低了。我曾经做过一个测试,用它添加多条记录和使用UpdateDataSet成批提交数据(相同的数据)的方式进行过比较,总体时间效率不会更差
7、,反而会更快一点。最后不得不再提一点,它的缓存机制做得很好,相同的SQL语句,可以根据不同的条件值,缓存用这个条件执行查询时的输出数据。它的缓存过期策略是封闭的。详细细节,相信随着深入会有所涉及。对它的介绍就先告一段落了,下一篇将会首先介绍一下它的配置工作环境,重点在于介绍如何使用log4net记录日志。iBatisnet系列(二) 配置运行环境和日志处理刚爬完鼓山回来,想到这篇刚刚开始,不敢怠慢,洗完澡休息一下就到电脑旁边来了。现在我开始介绍一下iBatis的配置和日志处理吧。iBatis基本的运行环境配置主要由两个文件组成,分别是SqlMap.config和Provider.config。
8、它们是必需的两个配置文件,基中SqlMap.config的功能类似于web.config或者app.config,是iBatis核心的配置文件,它的存放路径也跟应用程序配置文件一样,必须放在应用程序的运行目录下并且它的文件名是保留的,不可改变的。而Provider.config是一个数据驱动提供类的配置,它的文件名是可以随意改变的,因为通过SqlMap.config的一个配置节可以配置它的引用。SqlMap.config包括以下一些主要的配置节,根据需要,有的配置节并不是必须的:1. properties :可以根据需要配置一些常量属性。如果这些属性有很多的话可以单独写一个文件里面,再通过re
9、source(或url, embedded分别是引用url和编译在程序中的资源文件)属性引用进来。如: 这个配置节是可选的。2. settings:包括有三个配置段: useStatementNamespaces:在文档中说明它的作用是配置在使用语句ID的时候要不要加命名空间,例中$useStatementNamespaces就是使用properties中的一个属性,默认是false。cacheModelsEnabled 是配置要不要启用iBatis的缓存模型,默认是true。validateSqlMap 是配置要不要启示验证映射文件,默认是false。 3. providers :配置数据驱
10、动提供类配置文件的路径和文件名。 4. database : 数据库的信息,包括使用哪些数据库驱动和数据连接字符串的配置。 5. alias : 类型别名的配置,为了使用更方便的使用类(类名更短),就需在这里进行别名的配置。 6. typeHandlers :这个就相对比较复杂些了,到目前我也没有使用到。从字面上理解,它是一个类型的处理器,它的作用是当你使用的数据库当中有iBatis不支持或不认识的字段(或者不希望默认的处理方式),那就可以为它取一个名字,并且指定对应的.NET类型来处理它。 7. sqlMaps :用来包含当前已经写好的,并且需要用到的数据类映射文件。 !- - !- Rem
11、 : If used as embbeded Resources, use -以上就是Sqlmap.config的基本内容了。注意,以上凡是涉及到引用外部文件的都支持resouce,url,embedded 三种方式。Provider.config的配置类很简单,在默认的Provider.config中已经有很多不同数据库的数据驱动,而在SqlMapp.config的database配置的provider属性就是使用Provider.config中已有的不同驱动中的一个。以下是添加一个A 2.0 数据访问驱动:OK,以上就是SqlMap.config和Provider.config的基本内容。
12、下面我来介绍一下如果利用log4net来记录iBatisnet的一些运行日志记录。这也是我当初花了很多的时间才解决的一个问题,因为记录这些日志太重要了,它可以记录下每次生成并执行的SQL语句,对我们排除配置错误有非常重大的意义。而如果你是使用最新版的(当前是1.3.0),但是文档使用的是1.2.1的话,那可能你怎么折腾都无法搞出结果来。按照1.2.1的文档介绍那样在web.config(app.config) 加上合适的配置节后,然后把log4net.dll和IBatisNet.Common.Logging.Log4Net.dll拷到bin目录下后,你可能会认为跟文档介绍的一样,生成一个log
13、.txt,并记录下日志。但事实不是这样的,在1.3.0的版本中还需要再加上一个配置节组: 配置组的配置值如下: !- - 经过以上的配置后,再运行程序,就会创建log.txt并且记录日志了。注意:即使是按以上的配置后,有可能还是无法记录日志,那就可能是log4net.dll和IBatisNet.Common.Logging.Log4Net.dll的中的一个或两个没有拷到bin目录,正常情况下,我们不需引用这两个程序集,只需把它们拷到运行目录下,即使你需要记录日志,但找不到他们,程序仍然能正常执行而不会抛出异常,如果你没有经验的话,解决这个问题可能需要你很多的时间。以上就是今天要介绍的内容了,H
14、ope this helps。附注:1 参考资料:Data Mapper Guide-1.2.1.chm ;DataMapper-1.2.1.chm2 配置文件智能提示:把provider.xsd SqlMap.xsd SqlMapConfig.xsd 三个文件拷贝到VS 2005 :C:Program FilesMicrosoft Visual Studio 8XmlSchemas (安装目录)VS 2003 :C:Program FilesMicrosoft Visual Studio .NET 2003Common7Packagesschemasxml (安装目录)下,就可以在VS ID
15、E下编写配置文件时得到Intellisense的帮助,前提是配置的文件的第一个节点写正确的命名空间和XSD文件。3 HYPERLINK http:/ DEMO HYPERLINK http:/ 下载。使用VS 2005 ,你可能需要安装有免费版本的SQL 2005。-iBatis.Net系列(三) 映射文件基础iBatis的核心就在于映射文件(Data Map XML File)。在映射文件里可以定义包括要执行各种SQL语句,存储过程,输入参数映射,返回结果映射,缓存机制,并且能通过几种相对比较复杂的配置实现对象之间的关联关系和延迟加载。这也是iBatis区别ORM框架的,具备更灵活性,更高性
16、能的关键所在。配置文件可以写得很简单,也可以很复杂。复杂配置文件也是出于更好的设计,更好性能,更好扩展性方面的目的。再复杂的配置文件也是有限的,一个映射文件包括:Mapped Statements、Parameter Maps、Result Maps、Cache Models几个主要的配置,还包括命名空间的配置,类型别名(前一篇中有介绍)的配置。1Mapped Statements :顾名思义就是映射的语句声明。它是整个iBatis配置核心的核心,真正将被执行的SQL语句(或存储过程)都是必须在这里被显式声明。在Mapped Statements里可以包含有:statement、select、
17、insert、update、delete、procedure这6种不同的语句类型。从词面理解相信就可以了解到这些类型功能的一大半了。statement可以包含所有类型的SQL语句(存储过程),它是一个泛泛的语句配置,没特别明确的职责,相反,其它5种类型的语句配置就是专门负责各种不同的SQL语句。下面这张图列出了各种类型的语句的不同职责和调用方法。 2Parameter Maps :参数映射的配置,它是被用来向一个语句(statement)提供所需参数的配置。每一个Parameter Maps都有一个自己的ID,在需要的时候需要在statement 的 parameterMap属性中提供它的ID
18、。但是对一个语句来说,它并不是必须,在iBatis中还支持内联参数(Inline Parameter Maps)的形式,我们不需单独写一个Parameter Maps配置,只需要向parameterClass提供参数的类型,可以是元数据类型,复合数据类型,IDictionary数型的弱类型对象(使用key,value的键值对)。在内部访问数据类型的时候只使用#property#的形式访问对应的属性值。注意:在任何地方使用到的parameterClass类型如果是一个元数据类型(int,string etc),都需要使用#value#的形式的来访问它的值。3Result Maps :返回结果的映
19、射关系配置,就是列与属性的对应关系。在statement中使用resultMap属性来指定一个结果映射。对一个statement来说,resultMap也不是必须的,同样的,它仍然可以被resultClass给代替,因为如果返回出结果数据集的列名跟数据对象的属性相同的话,它会自动去匹配,但是它不保证所有列都被会被正确映射(当某列名在对象中找不对应的属性名,这列值将不被处理)。而resultMap则不同,如果已经在resultMap中定义将要使用到列或属性在结果集或数据对象中不存在,将会被认为是错误的,将会抛出异常。通过上面的表可以看到insert,update,delete三种语句类型是没有r
20、esultMap和resultClass,因为原则上来说,它们的操作是没有必要返回结果集。注意:如果在一个statement中同时指定了resultMap和resultClass属性的话,那将会优先使用resultMap。同时result Map也是一个实现对象复杂查询功能的重要手段,如:result map的继承(与discriminator配合使用),对象的1.1、1.N关系查询。4Cache Model :缓存模型。使用在Cache Model中定义好的缓存机制,只需在查询语句配置的cacheModel属性就可以很容易地缓存查询返回的数据集。在iBatis中提供了三种的类型的缓存模式(M
21、emory,LRU,FIFO)算法。三种算法主要在于静态过期策略上的不同,而它们都有相同的动态过期依赖策略,即可以设置执行哪些statement时,缓存过期。注意:iBaits的缓存模型正常情况是非常好用的,但是因为缓存过期策略上的封装性,它在多个服务器,负载平衡场景下还是有它的局限性。iBatis.Net系列(五) ParameterMap在用Ado.Net进行数据库访问操作中,最麻烦的就是准备DbCommand必须为它添加DbParameter,特别是当要传的参数特别多的情况下,数据访问层的很多代码都是花在这里。iBatis的ParameterMap配置就是针对这个问题所提出的一种解决方案
22、,基于xml的配置,把字段名和对象的属性对应起来,通过运行时的一些工作,自动为DbCommand提供它所需的参数集合。从而避免了我们直接写很多重复代码。 在Employees_ParameterMap.xml配置文件中: SELECT EmployeeID,LastName,FirstName FROM Employees WHERE EmployeeID = #EmployeeID# OR LastName = #LastName#使用的是内联参数映射的方式,语句的在执行查询时只需为它提供Employee类型的对象,它就会自动去读自己需要的EmployeeID,LastName属性的值,返回
23、查询结果。在执行时它所执行的语句如下:SELECT EmployeeID,LastName,FirstName FROM Employees WHERE EmployeeID = param0 OR LastName = param1所需的参数的提供方式如下:param0=EmployeeID,12, param1=LastName,8bbb7bfb-c并且,在iBatis中还会指出各个参数的类型:param0=Int32, System.Int32, param1=String, System.String对于下面这个配置: SELECT EmployeeID,LastName,FirstN
24、ame FROM Employees WHERE EmployeeID = #EmployeeID# OR LastName = #LastName# OR Country = #Country# 它所使用的ParameterMap配置如下: 在每一个Parameter映射元素可以指定每个属性对应的列,它的类型和对应的数据库的类型,还可以指定当它为空值时的默认值,具体可以参看官方文档。但是可以看到,我们期待它能和内联参数一样的使用方法,如上配置的那样。可是行不行呢?从程序的执行结果来看,是不可以的。由于之前在配置SQL语句的时候基本都是使用内联参数没有特别注意到这点。在使用Parameter
25、Map的时候是不能用#property#的形式显示地指定要使用的属性参数,只能通过“?”,顺序替代每一个parameter元素,如下: SELECT EmployeeID,LastName,FirstName FROM Employees WHERE EmployeeID = ? OR LastName = ? OR Country = ? 可以看到,由于没有明显地指出EmployeeID对应哪个属性,那如果把上面的parameter元素调换一下,那么EmployeeID所对应的参数值就发生变化了。同时,也是这个原因,通过这种方式的参数映射,就无法重复利用每个参数了。如果仔细观察会发现,既然都
26、指定了column属性了,那它为什么不会自动去配置呢?其实在这边column属性是不起作用的,它只会作用在执行存储过程的时候。也就是说上面的Parameter元素中的column属性不是必须的。下面是一个存储过程的例子: InsertEmployee InsertEmployee接受两个参数LastName和FirstName。我给它提供的映射参数如下: 上面这样的配置的结果是(其中逗号后面的是值):LastName=LastName,9a8bc059-3, FirstName=FirstName,46887db0-2但是当我把他们的位置调换了一下。它的结果如下:LastName= First
27、Name,9a8bc059-3, FirstName=LastName,46887db0-2也就是对储存过程也是一样的,参数映射关系仍然与parameter元素的顺序息息相关的。Column属性仍然没有显示出它的作用。所以使用ParameterMap还有是有一定的局限性的。但是对存储过程来说,就必须使用这样的方式,因为它只支持ParameterMap为它提供参数,而不支持内联参数。最后总结列出几点ParameterMap需要特别注意的几个细节:1在配置ParameterMap的时候,如果传入的参数对像是元数据类型(int,string etc),那么在配置Parameter元素的时候,prop
28、erty的属性名使用value。通过这种情况主要使用在为存储指定参数的情况下。2如果ParameterMap中配置的parameter元素不包含在传入参数对象中(属性或IDictionary对象的一个key,value项),将会产生异常,而不管在statement中有没有用到。3在使用parameterMap的extends属性时,它将会继承extends值对应的parameterMap配置,并且会继承它的所有的参数映射,并且顺序是从继承的那配置为基准开始计算。这个在需要用到extends属性的时候要特别注意。4.在为存储过程传参过程要特别注意,参数映射与存储过程的参数之间的顺序对应要正确。而
29、且必须为提供与存储过程足够的参数(parameter配置足够多),即使存储过程的部分参数已经有默认值了。否则将抛出System.ArgumentOutOfRangeException异常。 5正常情况下,应该尽量使用内联参数。iBatis.Net系列(六) ResultMap自从五一写了三篇关于iBatis.Net的post后,一直都没有更新相关的文章的。一方面是因为自己的能力有限,不够自信,那三篇连发表在首页的信心都没有。另一方面是因为最近确实很忙,工作上的事情就可以让我忙得晕头转向的,实在没有时间抽空来写Blog了。但想想,忙只是一个借口,看到 HYPERLINK http:/ Dflyi
30、ng Chen在这两个月在CnBlogs所取得的成就就让我惭愧不已,本身自己水平就不能与人家相提并论,却总是拿“忙”来挡箭牌,实在是不该啊。 酒话过后,进入本次的主题,我们将来讨论一下在iBatis中非常重要的一个内容,在我个人看来,能否真正用好iBatis的一个关键,这就是ResultMap。字面上理解,它就是结果集的映射,就是将返回的记录逐个字段的映射赋值给对象的属性上。其实如果没有特殊需求的话我们完全可以使用ResultClass来代替它,因为如果字段与属性一模一样的话,查询出来数据集会自动匹配到ResultClass指定的类的实例对象,如果字段名不在属性中的话,那这个字段将不会被返回的
31、实例体类对象接受,相当于没有查询出这个字段一样的。每个ResultMap都有一个自己的ID,如果你在sqlmap.config中没有配置使用命名空间的话,那么这个ResulteMap ID是全局(这点在所有的iBatis配置元素都是一样的),ResultMap一个重要的属性的是class,它将决定这个ResultMap对应的实例的类,换句话讲,它的作用是指出结果集要映射的数据类型。在extends属性中可以设置它将要继承的ResultMap,如果给他指定的了值,那么它将会从super Resultmap继承所的映射配置字段。定义如下: 如果你有正确配置了iBatis的XSD架构文件的话,那么这
32、时候就会提示resultMap的定义是不完全的。没错,接下来就是要定义Result元素。每一个result元素都是定义一个字段与数据类属性对应的映射。在每一个result元素有比较多的属性参数,其中property和column是必须的,其它的参数属性都是可选的。所以我们在每一个resultMap中必须定义超过一个以上的result定义。通常以下的配置就可以完成基本的配置了。 但如果你需要更多的要求的话,result map仍然能够最大限度的满足你。columnIndex属性提供了我们将数据集的第几个下标字段映射到指定的数据对象属性的方案,但是这种方式应该尽量的少用,你会发现这对我们以后的维护
33、和可读性会产生很大的副作用。dbType属性明确指出这个字段对应的数据库的类型,大多数情况我很少会用到。type属性则明确指出这个字段将对应的数据对象属性的数据类型,通常如果你想保证类型安全的话,设置这个属性是很必要的。resultMapping属性则稍微复杂一些,它是用在一种场景下,如果一个数据类的属性本身不是基元数据类型,而是一个复杂数据类型的话,那我们就不可能很简单地给它一个简单的result元素就了事了,还必须给他一个完整的resultMap。而resultMapping属性就是为了完成这个功能而存在的。它的属性值是一个已存在的resultMap的ID。nullValue属性就没什么好
34、讲的了,它是给出当这个字段的值为null的时候,它的默认值是多少。select属性同resultMapping一样比较复杂一样,先说一下它的属性值必须是一个返回数据集合的查询语句的ID,能配置这个属性的数据类属性可以是一个基元类型,复合类型,也可以是一个包括多条数据的集合类型,这些类型都行,没有问题的。它的一处重要的存在意义就在于描述不同表之间的关系问题,通过本次的查询,你想不通过join的手段从另一个表查询相关字段的时候,你就可以使用select属性。如下: SELECT * FROM Children WHERE ParentID = #id# 这样就可以做到不用通过编程的方式来表示不同表
35、的关联关系和数据读取问题。但是这样有可能存在一种问题,如果你每次都要读取数据的时候,你会发现你会产生更多次的与数据库交互的情况,并且即使你不是每次都需要这数据,那会不会造成数据读取的浪费呢?接下来的lazyLoad属性就为我们提供了第二种问题的解决方案了,那就是数据的延迟加载,没错,延迟加载可以大大改善数据访问的性能,它只是要需的时候才去读取这些数据,对于主从表关系的时候,这样的方式可能是最好的解决方式了。 OK,关于ResultMap的介绍就先到此为止,接下来我要记录一下,我在使用过程中遇到的一些问题: 一在使用ResultMap的时候,你要特别注意,如果你在ResultMap中给出的配置字
36、段,但是你返回的数据集的时候却没有返回这个字段,那程序将出抛出异常。但是相反的,如果你返回了一些字段,却没有在ResultMap给出配置定义的话,那么那些字段将不会被处理而不会给你任何的提示,相当没有查询出这些字段。你要特别注意这个问题。 二如果没有特别需求的情况,我建议还是把数据类的属性设计成与数据库字段字一样的比较,这样如果一般情况下我们都可以不用写这个ResultMap,事实上如果没有这样的特殊要求,那么去写这个ResultMap仍然是一件非常耗时,并且容易出错的一份差事。 三在使用lazyLoad的时候要特别注意,不是什么类型的数据都可以lazyLoad的,只有是实现的IList的接口
37、的类型,并且数据类的属性定义为IList类型的字段才能被lazyLoad。(关于是否只有IList类型的属性才能被lazyLoad的问题还需要探讨一下,因为就我使用的经验只有这种类型才可以,甚至是Generic版的IList都不支持)。而且你在使用它的时候,还不能把这个IList类型的属性转换成你真正的数据类型。因为在运行时,这个属性会被包装成一个动态的类型,这个动态类型仍然实现了IList接口,就是因为这个动态类型才扩展了我们可以lazyLoad的功能。这时候在程序中使用的是运行时的动态类型所以你没办法进行强类型转换。 问题暂时没有想到更多了,如果以后还有关于resultMap的问题,我都会
38、更新上来,也希望大家一起来指正我的一些错误和不足,一起完善。不要让我的一些错误的实践误导了初学者,谢谢 HYPERLINK http:/ ibatis使用存储过程传递参数SQL Map通过元素支持存储过程。下面的例子说明如何使用具有输出参数的存储过程。 call swap_email_address (?, ?) 调用上面的存储过程将同时互换两个字段(数据库表)和参数对象(Map)中的两个email http:/ Clinton Begin 著 刘涛() 译 开发指南 iBATIS SQL Maps Page 21 of 62 地址。如果参数的mode属性设为INOUT或OUT,则参数对象的值
39、被修改。否则保持不变。 注意!要确保始终只使用JDBC标准的存储过程语法。参考JDBC的CallableStatement文档以获得更详细的信息。 -IBatisNet基础组件 DomSqlMapBuilder,其作用是根据配置文件创建SqlMap实例。可以通过这个组件从Stream, Uri, FileInfo, or XmlDocument instance 来读取sqlMap.config文件。SqlMap是IBatisnet的核心组件,提供数据库操作的基础平台。SqlMap可通过DomSqlMapBuilder创建。 Assembly assembly = Assembly.Load(
40、IBatisNetDemo); Stream stream = assembly.GetManifestResourceStream(IBatisNetDemo.sqlmap.config); DomSqlMapBuilder builder = new DomSqlMapBuilder(); sqlMap = builder.Configure( stream ); SqlMap是线程安全的,也就是说,在一个应用中,可以共享一个SqlMap实例。 SqlMap提供了众多数据操作方法,下面是一些常用方法的示例,具体说明文档参见 ibatis net doc,或者ibatisnet的官方开发手册
41、。SqlMap基本操作示例例1:数据写入操作(insert、update、delete)SqlMap.BeginTransaction();Person person = new Person();Person.FirstName = “Zhang”;Person.LastName = “shanyou”;int Id = (int) SqlMap.Insert(InsertPerson, person);SqlMap.CommitTransaction();.例2:数据查询:Int Id = 1;Person person = SqlMap.QueryForObject(, Id);retu
42、rn person;例3:在指定对象中存放查询结果:Int Id = 1;Person person = new Person();person = SqlMap.QueryForObject(GetBirthday, Id, person);return person;例4:执行批量查询(Select)IList list = null;list = SqlMap.QueryForList(SelectAllPerson, null);return list;例5:查询指定范围内的数据(Select)IList list = null;list = SqlMap.QueryForList(S
43、electAllPerson, null, 0, 40);return list;例6:结合RowDelegate进行查询:public void RowHandler(object obj, IList list)Product product = (Product) object;product.Quantity = 10000;SqlMapper.RowDelegate handler = new SqlMapper.RowDelegate(this.RowHandler);IList list = sqlMap.QueryWithRowDelegate(getProductList,
44、null, handler);例7:分页查询(Select)PaginatedList list = sqlMap.QueryForPaginatedList (“getProductList”, null, 10);list.NextPage();list.PreviousPage();例8:基于Map的批量查询(select)IDictionary map = sqlMap.QueryForMap (“getProductList”, null, “productCode”);Product p = (Product) map“EST-93”;OR映射相对于Nhibernate等ORM实现
45、来说,IBatisnet的映射配置更为直接,下面是一个典型的配置文件:!模块配置 !statement配置 select PER_ID, PER_FIRST_NAME, PER_LAST_NAME, PER_BIRTH_DATE, PER_WEIGHT_KG, PER_HEIGHT_M from PERSON select PER_ID, PER_FIRST_NAME, PER_LAST_NAME, PER_BIRTH_DATE, PER_WEIGHT_KG, PER_HEIGHT_M from PERSON where PER_ID = #value# $selectKey insert i
46、nto Person ( PER_FIRST_NAME, PER_LAST_NAME, PER_BIRTH_DATE, PER_WEIGHT_KG, PER_HEIGHT_M) values (#FirstName#,#LastName#,#BirthDate#, #WeightInKilograms#, #HeightInMeters#) delete from Person where PER_ID = #Id# 可以看到,映射文件主要分为两个部分:模块配置和Statement配置。模块配置包括:1、typeAlias节点定义了本映射文件中的别名,以避免过长变量值的反复书写,此例中通过ty
47、peAlias节点为类“IBatisNetDemo.Domain.Person”定义了一个别名“Person”,这样在本配置文件中的其他部分,需要引用“IBatisNetDemo.Domain.Person”类时,只需以其别名替代即可。2、cacheModel节点定义了本映射文件中使用的Cache机制: 这里声明了一个名为“person-cache”的cacheModel,之后可以在Statement声明中对其进行引用: select PER_ID, PER_FIRST_NAME, PER_LAST_NAME, PER_BIRTH_DATE, PER_WEIGHT_KG, PER_HEIGHT
48、_M from PERSON 这表明对通过id为SelAllPerson的“Select Statement”获取的数据,使用CacheModel “person-cache”进行缓存。之后如果程序再次用此Satement进行数据查询。即直接从缓存中读取数据,而不需再去数据库查询。CacheModel主要有几个配置点:参数描述flushInterval设定缓存有效期,如果超过此设定值,则将此CacheModel缓存清空CacheSize本Cachemodel中最大的数据对象数量flushOnExecute指定执行特定的Statement时,将缓存清空。如UpdatePerson操作将更新数据库
49、中用户信息,这将导致缓存中的数据对象与数据库中的实际数据发生偏差,因此必须将缓存清空以避免脏数据的出现。3、resultMaps节点resultMaps实现dotnet实体到数据库字段的映射配置: Statement配置:Statement配置包含了数个与Sql Statement相关的节点,元素是一个通用的能够包容任意类型sql的元素。我们可以用更多细节的元素。这些细节元素提供更好的错误检查以及一些更多的功能。(例如,一个插入函数能够返回数据库自动生成的key)。以下表格总结了声明类型元素以及他们的特性和属性。Statement ElementAttributesChild Elements
50、Methodsid parameterClass resultClass parameterMap resultMap cacheModel xmlResultName (Java only)All dynamic elementsinsert update delete All query methodsid parameterClass parameterMapAll dynamic elements (.NET only)insert update delete id parameterClass parameterMapAll dynamic elements (.NET only)i
51、nsert update deleteid parameterClass parameterMapAll dynamic elements (.NET only)insert update deleteid parameterClass resultClass parameterMap resultMap cacheModelAll dynamic elements (.NET only)All query methodsid parameterClass resultClass parameterMap resultMap xmlResultName (Java only)All dynam
52、ic elements insert update delete All query methods其中,statement最为通用,它可以代替其余的所有节点。除statement之外的节点对应于SQL中的同名操作(procedure对应存储过程)。使用Statement定义所有操作,缺乏直观性,建议在开发中根据操作目的,各自选用对应的节点名加以说明。一方面,使得配置文件更加直观,另一方面,也可以借助xsd对i节点声明进行更有针对性的检查,以避免配置上的失误。 select * from PRODUCT where PRD_ID = ?|#propertyName# order by $sim
53、pleDynamic$其中“ ”包围的部分为可能出现的配置项,各参数说明见下表。具体的使用方法参见IBatisNet官方文档。参数描述parameterMap参数映射,需结合parameterMap节点对映射关系加以定义,对于存储过程之外的statement而言,建议使用parameterClass作为参数配置方式,一方面避免了参数映射配置工作,另一方面其性能表现更加出色parameterClass参数类。指定了参数类型的完整类名(包括命名空间),可以通过别名避免每次书写冗长的类名resultMap结果映射,需结合resultMap节点对映射关系加以定义resultClass结果类。指定了结果
54、类型的完整类名(包括命名空间),可以通过别名避免每次书写冗长的类名cacheModelStatement对应的Cache模块一般而言,对于insert、update、delete、select语句,优先采用parameterClass和resultClass.。paremeterMap使用较少,而ResultMap则大多用于存储过程处理和查询。存储过程相对而言比较封闭(很多情况下需要调用现有的存储过程),其参数名和返回的数据字段命名往往不符合dotnet编程的命名规范)。使用resultMap建立字段名同Dotnet对象的属性之间的映射关系就非常有效。另一方面,由于通过ResultMap指定了
55、字段名和字段类型,ibatisnet无需再通过来动态获取字段信息,在一定程度上也提升了性能。下面特别说明一下ibatisnet对Stored Procedures的处理,iBatis数据映射把存储过程当成另外一种声明元素。示例演示了一个基于存储过程的简单数据映射。ps_swap_email_address. prc_InsertCategory. prc_InsertAccount. 示例是调用存储过程swapEmailAddress的时候将会在数据库表的列和两个email地址之间交换数据,参数对象亦同。参数对象仅在属性被设置成INOUT或者OUT的时候才会被修改。否则,他们将不会被修改。当然
56、,不可变得参数对象是不会被修改的,比如string.Net中,parameterMap属性是必须的。DBType,参数方向,大小由框架自动发现的。(使用CommandBuilder实现的) HYPERLINK http:/ IBatisNet配置 结合上面示例中的IbatisNet配置文件,下面对配置文件中各节点的说明: !- Rem : If used via a DataAccess context, properties tag will be ignored - 1. properties节点可以根据需要配置一些常量属性。如果这些属性有很多的话可以单独写一个文件里面,再通过resour
57、ce(或url, embedded分别是引用url和编译在程序中的资源文件)属性引用进来properties 节点参数参数描述resource指定the properties文件从application的根目录进行加载resource=properties.configurl指定the properties文件从文件的绝对路径进行加载url=c:WebMyAppResourcesproperties.config-or-url=file:/c:WebMyAppResourcesproperties.configembedded指定文件可以作为程序集的资源文件进行加载embedded= data
58、base.config, IBatisNetDemo”上面例子中Properties文件的配置如下: 下面解释一下这个文件的节点参数Property节点参数参数描述key定义key (variable) 名字key=usernamevalue定义DataMapper 中使用的 key的值value=mydbuser2. setting节点Setting节点参数参数描述cacheModelsEnabled 是否启用sqlMap上的缓存机制Example: cacheModelsEnabled=”true”Default: true (enabled)useStatementNamespaces 是否使用Satement命名空间,这里的命名空间指的是映射文件中sqlMap节点的namespace属性,如上例中针对Person表的映射文件sqlMap节点 这里,指定了此sqlM
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026中国华电集团有限公司河南公司招聘4人笔试备考试题及答案解析
- 2026内蒙古行政执法(阿拉善盟岗位)“兼通蒙古语言文字”岗位蒙古语言文字翻译水平加试笔试备考试题及答案解析
- 2026中国科学院广州地球化学研究所蚁瑞钦研究员与林莽研究员博士后招聘(广东)笔试备考题库及答案解析
- 2026湖北武汉东湖新技术开发区消防救援大队招聘政府专职消防员30人笔试备考题库及答案解析
- 2026广东中山市神湾镇中心幼儿园第一期招聘编外人员4人笔试备考试题及答案解析
- 2026年芜湖职业技术学院单招职业技能考试参考题库含详细答案解析
- 2026福建龙岩新罗区大池中心幼儿园招聘3人笔试备考试题及答案解析
- 2026福建厦门市集美区博雅实验幼儿园非在编人员招聘2人笔试备考题库及答案解析
- 2026年上半年洛阳新安县城镇公益性岗位招聘56名笔试备考题库及答案解析
- 2026年芜湖臻鑫智镁科技有限公司公开招聘笔试备考题库及答案解析
- 学习走好中国特色金融发展之路建设金融强国心得体会、交流研讨
- 【课件】2025年危险化学品典型事故分析-终版
- 医院精神科患者风险评估标准
- 5.1《四大地理区域的划分》教案-2025-2026学年湘教版地理八年级下册
- 雨课堂学堂在线学堂云国际关系:理论与实践西安外国语大学单元测试考核答案
- 个人投资业务管理办法
- 空调延长质保协议书
- 《危险货物运输》课件
- 询问供应商放假通知范文
- 系统servo guide mate常用调整项目入门指导
- 一元强弱酸的比较课件高二上学期化学人教版选择性必修1
评论
0/150
提交评论