http://www.cnblogs.com/13590/archive/2013/03/01/2938126.html
<?xml version="1.0" encoding="UTF-8"?> <sqlMap namespace="Product" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="SqlMap.xsd"> <alias> <typeAlias alias="Product" type="NPetshop.Domain.Catalog.Product, NPetshop.Domain"/> </alias> <cacheModels> <cacheModel id="ProductList-cache" implementation="MEMORY"> <flushInterval hours="24"/> <property name="Type" value="Weak"/> </cacheModel> </cacheModels> <resultMaps> <resultMap id="ProductResult" class="Product"> <result property="Id" column="Product_Id"/> <result property="Name" column="Product_Name"/> <result property="Description" column="Product_Description"/> </resultMap> <resultMap id="ProductList" class="Product" extends="ProductResult"> <result property="Category" resultMapping="Category.CategoryResult"/> </resultMap> </resultMaps> <!-- ============================================= MAPPED STATEMENTS ============================================= --> <statements> <select id="GetProductListByCategory" cacheModel="ProductList-cache" resultMap="ProductList" parameterClass="string"> select Product_Id, Product_Name, Product_Description, P.Category_Id, Category_Name, Category_Description from Products as P, Categories as C where C.Category_ID= P.Category_ID and P.Category_Id = #value# </select> <select id="GetProduct" resultMap="ProductResult" parameterClass="string"> select Product_Id, Product_Name, Product_Description from Products where Product_Id = #value# </select> <select id="SearchProductList" resultMap="ProductResult"> select Product_Id, Product_Name, Product_Description from Products <dynamic prepend="WHERE"> <iterate property="KeywordList" open="" close="" conjunction="OR"> lower(Product_Name) like #KeywordList[]# OR lower(Category_ID) like #KeywordList[]# OR lower(Product_Description) like #KeywordList[]# </iterate> </dynamic> </select> </statements> </sqlMap>
type:缓存的类型,iBatis.Net中有4种类型,分别为MEMORY、LRU、FIFO、OSCACHE。
其中MEMORY是内存缓存,LRU是使用最近最少使用策略,FIFO是使用先进先出策略,OSCACHE是通过第三方的缓存插件来实现。
id:是cacheModel的一个标识,标识该缓存的名字,供后面设置使用。
readOnly:指缓存的数据对象是只读还是可读写,默认为"true",即只读,这里的只读并不是意味着数据对象一旦放入缓存中就无法再对数据进行修改。而是当数据对象发生变化的时候,如数据对象的某个属性发生了变化,则此数据对象就将被从缓存中废除,下次需要需重新从数据库读取数据,构造新的数据对象。而readOnly="false"则意味着缓存中的数据对象可更新。
serialize:是否从缓存中读取同一个对象,还是对象的副本。该参数只有在readOnly为false的情况下才有效, 因为缓存是只读的,那么为不同会话返回的对象肯定是一个,只有在缓存是可读写的时候,才需要为每个会话返回对象的副本。
flushInterval:指定缓存自动刷新的时间,可以为hours、minutes、seconds和milliseconds。需要注意的是,这个间隔时间不是时间到了,在缓存里的信息会自动刷新,而是在间隔时间过后,下次查询将不会从缓存中去取值,而会用SQL去查询,同时将查询的结果更新缓存的值。
flushOnExecute:指定在发生哪些操作时,更新缓存。
property:针对cacheModel的额外的一些属性配置,不同type的cacheModel将会有自己专有的一些property配置,如:
FIFO: <property name="CacheSize" value="100" />
LRU: <property name="CacheSize" value="100" />
MEMORY: <property name="Type" value="WEAK" />
3 语句配置
语句配置(Mapped Statements):顾名思义就是映射的语句声明。它是XML数据映射文件的核心,在iBatis.Net框架中真正和数据库打交道的被执行的SQL语句(或存储过程)都必须在这里被显式声明。语句配置可以包含有:statement、select、insert、update、delete和procedure这6种不同的语句类型。其中statement可以包含所有类型的SQL语句(存储过程),它是一个泛泛的语句配置,没特别明确的职责,相反,其它5种类型的语句配置就是专门负责各种不同的SQL语句。下面这张表列出了各种类型的语句的不同职责和调用方法。
Statement类型 |
属性 |
子元素 |
方法 |
<statement> |
id parameterClass resultClass parameterMap resultMap cacheModel |
所有动态元素 |
update delete 所有的查询方法 |
<insert> |
id parameterClass parameterMap |
所有的动态元素 <selectKey> |
insert update delete |
<update> |
id parameterClass parameterMap |
所有的动态元素 |
insert update delete |
<delete> |
id parameterClass parameterMap |
所有的动态元素 |
insert update delete |
<select> |
id parameterClass resultClass parameterMap resultMap cacheModel |
所有的动态元素 |
所有的查询方法 |
<procedure> |
id parameterClass resultClass parameterMap resultMap |
所有的动态元素 |
insert update delete 所有的查询方法 |
4 特殊配置
4.1 XML转义字符
很多时候在SQL语句中会用到大于或者下于符号(即:><),这个时候就与XML规范相冲突,影响XML映射文件的合法性。通过加入CDATA节点来避免这种情况的发生,如:
<statement id="SelectPersonsByAge" parameterClass="int" resultClass="Person">
<![CDATA[
SELECT * FROM PERSON WHERE AGE > #value#
]]>
</statement>
4.2自动生成主键
目前很多数据库都支持为新插入的记录自动生成主键,Oracle也提供这种功能,通过序列加触发器来解决。这当然很方便,但是当希望在插入一条记录后立即获得该记录的主键值,问题就出现了,因为很可能为此不得不新写一条语句去获取该主键值。iBatis.Net提供了一种比较好的解决方式。通过在XML数据映射文件中的<selectKey>元素来获取这些自动生成的主键值并将其保存在对象中。
如上面的"添加"操作配置信息修改为:
<insert id="InsertSysuser" parameterClass="Sysuser">
<selectKey resultClass="int32" property="Userid" type="pre">
SELECT DEAN.SEQ_SYSUSER_USERID.NEXTVAL AS Userid FROM DUAL
</selectKey>
INSERT INTO DEAN.SYSUSER (USERID,PASSWORD,LOGINNAME,SEX,BIRTHDAY,IDCARD,OFFICEPHONE,FAMILYPHONE,MOBILEPHONE,EMAIL,ADDRESS,ZIPCODE,REMARK,STATUS)
VALUES (#Userid#,#Password#,#Loginname#,#Sex#,#Birthday#,#Idcard#,#Officephone#,#Familyphone#,#Mobilephone#,#Email#,#Address#,#Zipcode#,#Remark#,#Status#)
</insert>
粗体部分为新加的selectKey节点。#Userid#参数将使用节点中从序列里选出的值进行填充。修改调用的代码:
ISqlMapper mapper = Mapper.Instance(); //得到ISqlMapper实例
Int32 result = (Int32)mapper.Insert("SysuserMap.InsertSysuser", model);//调用Insert方法
Label1.Text = "添加用户成功,result返回UserID为" + Convert.ToString(result) + ",Sysuser实例model的UserID为" + Convert.ToString(model.Userid);
运行程序,这样result就得到想要获取的键值,同时Sysuser的实例化对象model的UserID属性也返回了该条新记录的键值。
4.3 #与$的选择
在XML数据映射文件中,参数用#号来表示。如前面提到的#Userid#,同时也可以使用$来标识。两者有什么区别,以及如何选择呢?
(1)#是把传入的数据当作参数,如 order by #field# ,如果#field#传入的值是字符型,传入值为id, 则sql语句会生成order by "id",很明显生成的sql语句提交给数据库执行会报错。#参数往往用在需传入实际变量值的情况,如where id=#id#,变量#id#传入10,则sql语句会生成where id=10。
(2)$采用拼接方式生成sql语句,即传入的数据直接生成在sql语句里,如 order by $field$,如$field$传入的是id,则sql语句会生成order by id。$参数方式一般用于传入数据库对象。例如传入表名。不过要特别提醒,因为使用该参数是直接组成sql语句,所以需注意防止sql注入。
4.4 LIKE语句处理
在查询处理过程中,模糊查询经常会用到。iBatis如何处理这种模糊查询呢?处理Like模糊查询iBatis提供以下两种方法:
(1)使用#参数: 配置如Where UserName Like #param#||'%', 采用参数传递的方式,如#param#传入字符d,生成的sql语句为Where UserName Like 'd%',其他模糊情况同理可以相应配置出来。
(2)使用$参数:配置如Where UserName Like '$param$%' ,采用字符串替换,就是用参数的值替换param,如$param$传入字符d,也可以生成相同的语句。
$方式会引起sql注入风险,实际的使用中,建议大家都使用第一种配置方式来处理LIKE模糊查询。
5 结语
以上程序在Windows7(64位)+VS2012+Oracle 11g(64位)上测试通过。