Ibatis学习随笔
< person >  
   
< id > 1 id >
   
< firstName > Clinton firstName >
   
< lastName > Begin lastName >
   
< birthDate > 1900-01-01 birthDate >
   
< weightInKilograms > 89 weightInKilograms >
   
< heightInMeters > 1.77 heightInMeters >  
person >
一、SQL MAP Statement 
        一个简单的sql map statement。它通过最简单的方式实现了对数据库的添加、删除、修改。
xml version="1.0" encoding="UTF-8" ?>
DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "http://www.ibatis.com/dtd/sql-map-2.dtd" >
< sqlMap  namespace ="Tuser" >
    
< typeAlias  alias ="tuser"  type ="com.ibatis.pojo.TuserPO" />
     
< select  id ="getTuser"  resultClass ="tuser" >  
           

             select id,vname from tuser where id=#value#
            
]]>
     
select >  

     
< insert  id ="insrtTuser"  parameterClass ="tuser" >
         

             insert into tuser values(#id#,#vname#)
         
]]>
     
insert >
     
< update  id ="updateTuser"  parameterClass ="tuser" >
         

             update tuser set id=#id# ,vname=#vname# where id=#id#
         
]]>  
     
update >
     
< delete  id ="deleteTuser"   >
         

             delete  from tuser where id=#id#
         
]]>
     
delete >
     
sqlMap >
再看下面这个较复杂点的SQL Map Statement
< sqlMap  id =”Product”> 
   =”productCache”  type =”LRU”> 
            =”24”/> 
           =”size”  value =”1000”  />  
cacheModel >  
< typeAlias  alias =”product”  type =”com.ibatis.example.Product”  />  
< parameterMap  id =”productParam”  class =”product”> 
          =”id”/> 
         >  
< resultMap  id =”productResult”  class =”product”> 
            =”id”  column =”PRD_ID”/> 
           =”description”  column =”PRD_DESCRIPTION”/> 
>  
< select  id =”getProduct”  parameterMap =”productParam”  resultMap =”productResu      t”  cacheModel =”product-cache”> 
          select * from PRODUCT where PRD_ID  = ? 
>  
sqlMap >
对比两个不同的定义文件,第二个的定义比较麻烦,但运行效率却比第一个要高。因为第一个定义文件使用了Ibatis框架的自动映射特性。

在一个Sql map XML映射击文件可以包含多个Mapped Statement ,Parameter Map和ResultMap,但它们的名称在该SQL Map XML文件中必须是唯一的
Mapped Statements

SQL Map的核心概念是Mapped Statement。Mapped Statement可以使用任意的SQL语句,并拥有parameter map(输入)和result map(输出)。如果是简单情况,Mapped Statement可以使用Java类来作为parameter和result。Mapped Statement也可以使用缓存模型,在内存中缓存常用的数据。Mapped Statement的结构如下所示:
       [parameterClass=”some.class.Name”] 
       [resultClass=”some.class.Name”]
       [parameterMap=”nameOfParameterMap”] 
       [resultMap=”nameOfResultMap”]
       [cacheModel=”nameOfCache”] >
       select * from PRODUCT where PRD_ID = [?|#propertyName#] order by    
             [$simpleDynamic$]

在上面的表达式中,括号[]里的部分时可选的属性,并且在某些情况下只有特定的组合才是合法的。因此下面这个简单的例子也是正确的:
   
        insert into PRODUCT (PRD_ID,    PRD_DESCRIPTION) values (1, “Shih Tzu”)

上面的例子不太可能出现,但如果只是简单地想用SQL Map架构来执行任意地的SQL语句,这种写法就派上用场了。但常见的用法还是通过Parameter Map和Result Map,来实现Java Bean映射的特性,这是SQL Map真正有价值的地方。
Statements类型
元素是个通用声明,可以用于任何类型的SQL语句。通常,使用具体的statement类型是个好主意。具体statement类型提供了更直观的XML DTD,并拥有某些
Statement 类型
属性
子元素
方法
 
id parameterClass resultClass parameterMap resultMap cacheModel xmlResultName
 
所有的动态元素
 
insert update delete 所有的查询方法
 
 
id parameterClass parameterMap
 
所有的动态元素
 
insert
update
 delete
 
 
id
parameterClass parameterMap
 
所有的动态元素
 
Insert
Update
delete
 
 
id parameterClass resultClass parameterMap resultMap cacheModel
 
所有的动态元素
 
所有的查询方法
 
id parameterClass resultClass parameterMap resultMap cacheModel
 
所有的动态元素
 
所有的查询方法
 
 
id parameterClass resultClass parameterMap resultMap xmlResultName
 
所有的动态元素
 
insert update delete 所有的查询方法
 


二、SQL语句  
         SQL语句在mapped statement 中最重要的部份,可以使用符合数据库或JDBC的任意SQL语句,对于语句有特殊途同归符号的,可以把SQL语句写在里面。如
< statement  id ="getPersonsByAge"  parameterClass =”int”  resultClass ="examples.domain.Person" >
 

   SELECT * FROM PERSON WHERE AGE > #value# 
 
]]>
statement >
自动生成的主键
很多数据库支持自动生成主键的数据类型。不过这通常(并不总是)是个私有的特性。SQL Map通过的子元素来支持自动生成的键值。它同时支持预生成(如Oracle)和后生成两种类型(如MS-SQL Server)。下面是两个例子:
< insert  id ="insertProduct-ORACLE"  parameterClass ="com.domain.Product" >  
< selectKey  resultClass ="int"  keyProperty ="id"   >  
SELECT STOCKIDSEQUENCE.NEXTVAL AS ID FROM DUAL 
selectKey >
     insert into PRODUCT (PRD_ID,PRD_DESCRIPTION) values (#id#,#description#) 
insert >  
— Microsoft SQL Server IDENTITY Column Example -- >
< insert  id ="insertProduct-MS-SQL"  parameterClass ="com.domain.Product" >  
    insert into PRODUCT (PRD_DESCRIPTION) values (#description#) 
    < selectKey  resultClass ="int"  keyProperty ="id"   >  
       SELECT @@IDENTITY AS ID 
    selectKey >
  insert >
存储过程
SQL Map通过元素支持存储过程。下面的例子说明如何使用具有输出参数的存储过程。
< parameterMap  id ="swapParameters"  class ="map"   >  
   
< parameter 
property ="email1"    jdbcType ="VARCHAR"  javaType ="java.lang.String"  mode ="INOUT" />
 
< parameter 
property ="email2"    jdbcType ="VARCHAR"   javaType ="java.lang.String"   mode ="INOUT" />  
parameterMap >  
< procedure  id ="swapEmailAddresses"  parameterMap ="swapParameters"   >
   {call swap_email_address (?, ?)} 
procedure >
支持标准的JDBC格式调用存储过程方法。如果存储过程回的是游标那又怎么定义的。
parameterClass

parameterClass属性的值是Java类的全限定名(即包括类的包名)。parameterClass属性是可选的,但强烈建议使用。它的目的是限制输入参数的类型为指定的Java类,并优化框架的性能。如果您使用parameterMap,则没有必要使用parameterClass属性。例如,如果要只允许Java类“examples.domain.Product”作为输入参数,可以这样作:
< statement  id =”statementName”  parameterClass =”  examples.domain.Product” >  insert into PRODUCT values (#id#, #description#, #price#)
 
statement >
parameterMap

属性parameterMap的值等于一个预先定义的元素的名称。parameterMap属性很少使用,更多的是使用上面的parameterClass和inline parameter(接下来会讨论)。 注意!动态mapped statement只支持inline parameter,不支持parameter map。 parameterMap的基本思想是定义一系列有次序的参数系列,用于匹配JDBC PreparedStatement的值符号。例如:
< parameterMap  id =”insert-product-param”  class =”com.domain.Product”>
  
=”id”/> 
  
=”description”/> 
>  
< statement  id =”insertProduct”  parameterMap =”insert-product-param”>  insert into PRODUCT (PRD_ID, PRD_DESCRIPTION) values (?,?); 
>

如上所述,parameterMap负责将Java Bean的属性映射成statement的参数。
虽然parameterMap的外部形式很少使用,理解它如何工作对于理解inline parameter还是很有帮助。本节以下部分将详细讨论inline parameter。


括号[]是可选的属性。parameterMap元素只要求属性id作为唯一标识。属性class是可选的但强烈推荐使用。和parameterClass类似,class属性可以框架检查输入参数的类型并优化性能。
一个的例子
< parameterMap  id =”insert-product-param”  class =”com.domain.Product”>
 
=”id”  jdbcType =”NUMERIC”  javaType =”int”  nullValue =”-9999999”/> 
=”description”  jdbcType =”VARCHAR”  nullValue =”NO_ENTRY”/> 
>  
< statement  id =”insertProduct”  parameterMap =”insert-product-param”> 
insert into PRODUCT (PRD_ID, PRD_DESCRIPTION) values (?,?); 
>
注意!
parameterMap并不自动地绑定到特定的Java类。因此在上面的例子中,任何拥有“id”和“description”属性的Java Bean对象,都可以作为parameterMap的输入。如果需要将输入绑定到特定的Java类,可以使用mapped-statement的resultClass属性。
 注意!
Parameter Map的名称(name)局部的,只在定义它的SQL Map XML文件中有效。不过,加上SQL Map的名称(即在根元素中的名称)作为前缀,您可以在另一个SQL Map XML文件中引用它。例如,要在另一个文件中引用以上的parameterMap,可以使用名称“Product.insert-product-param”。

Inline Parameter简介

parameterMap的语法虽然简单,但很繁琐。还有一种更受欢迎更灵活的方法,可以大大简化定义和减少代码量。这种方法把Java Bean的属性名称嵌在Mapped Statement的定义中(即直接写在SQL语句中)。缺省情况下,任何没有指定parameterMap的Mapped Statement都会被解析成inline parameter(内嵌参数)。用上面的例子(即Product)来说,就是:
< statement  id =”insertProduct”  parameterClass =”com.domain.Product”>
 
insert into PRODUCT (PRD_ID, PRD_DESCRIPTION) values (#id#, #description#);
  >
在内嵌参数中指定数据类型可以用下面的语法:
< statement  id =”insertProduct”  parameterClass =”com.domain.Product”> 
insert into PRODUCT (PRD_ID, PRD_DESCRIPTION) values (#id:NUMERIC#, #description:VARCHAR#); 
>
在内嵌参数中指定数据类型和NULL的替代值可以用这样的语法:

insert into PRODUCT (PRD_ID, PRD_DESCRIPTION) values (#id:NUMERIC:-999999#, #description:VARCHAR:NO_ENTRY#);
注意!在内嵌参数中,要指定NULL的替代值,必须要先指定数据类型。 注意!如需要在查询时也使用NULL替代值,必须同时在resultMap中定义(如下说明)。
 注意!如果您需要指定很多的数据类型和NULL替代值,可以使用外部的parameterMap


resultClass

resultClass属性的值是Java类的全限定名(即包括类的包名)。resultClass属性可以让您指定一个Java类,根据ResultSetMetaData将其自动映射到JDBC的ResultSet。只要是Java Bean的属性名称和ResultSet的列名匹配,属性自动赋值给列值。这使得查询mapped statement变得很短。例如:

< statement  id ="getPerson"  parameterClass =”int”  resultClass ="examples.domain.Person" >  SELECT PER_ID as id,
PER_FIRST_NAME as firstName,
PER_LAST_NAME as lastName,
PER_BIRTH_DATE as birthDate,
PER_WEIGHT_KG as weightInKilograms, PER_HEIGHT_M as heightInMeters FROM PERSON WHERE PER_ID = #value# 
statement >
resultMap
  resultMap是最常用和最重要的属性。ResultMap属性的值等于预先定义的resultMap元素的name属性值(参照下面的例子)。使用resultMap可以控制数据如何从结果集中取出,以及哪一个属性匹配哪一个字段。不象使用resultClass的自动映射方法,resultMap属性可以允许指定字段的数据类型,NULL的替代值复杂类型映射(包括其他Java Bean,集合类型和基本类型包装类)。
  
< resultMap  id =”get-product-result”  class =”com.ibatis.example.Product”>
 
=”id”  column =”PRD_ID”/>   
=”description”  column =”PRD_DESCRIPTION”/>
 
>
 
< statement  id =”getProduct”  resultMap =”get-product-result”> 
       select * from PRODUCT 
>
xmlResultName

当直接把查询结果映射成XML document时,属性xmlResultName的值等于XML document根元素的名称。例如:
< select  id ="getPerson"  parameterClass =”int”  resultClass ="xml"  xmlResultName =”person”> 
SELECT PER_ID as id, 
PER_FIRST_NAME as firstName, 
PER_LAST_NAME as lastName,
 PER_BIRTH_DATE as birthDate,
 PER_WEIGHT_KG as weightInKilograms,   PER_HEIGHT_M as heightInMeters
 FROM PERSON WHERE PER_ID 
= #value# 
>
上面的查询结果将产生一个XML document,结构如下:
< person >
    
< id > 1 id >
    
< firstName > Clinton firstName >
    
< lastName > Begin lastName >
    
< birthDate > 1900-01-01 birthDate >
    
< weightInKilograms > 89 weightInKilograms >
    
< heightInMeters > 1.77 heightInMeters >
person >
基本类型输入参数
很简单就是使用JAVA基础类型来做为参数了。
< statement  id =”insertProduct”  parameter =”java.lang.Integer”> 
select * from PRODUCT where PRD_ID  = #value#  >
Map类型输入参数
< statement  id =”insertProduct”  parameterClass =”java.util.Map”>
 
select * from PRODUCT where PRD_CAT_ID  = #catId#  and PRD_CODE  = #code# 
>
可以注意到mapped statement的形式完全没有区别!上面的例子中,如果把Map对象作为输入参数去调用mapped statement,Map对象必须包含键值“catId”和“code”。键值引用的对象必须是合适的类型,以上面的例子来说,必须是Integer和String。Result Map(参见以下章节)也支持使用Map类型作为结果参数。要获得更多信息,请参见“Result Map”和“使用SQL Map API编程”部分。 Map类型也可以使用别名。例如,可以用“map”来代替“java.util.Map”。这些别名参见下面的“支持Parameter Map和Result Map的数据类型”表格。


三、动态 MAP Statement
         
作用是动态构建SQL语句,根据不同的一元或二元运算条件构建复杂的SQL语句,这功能非常好,这样就可以把写的BO层的SQL语句构造移值到SQL MAP 文件里。这里例举一些例子:
< select  id ="dynamicGetAccountList"  cacheModel ="account-cache"  resultMap ="account-result"   >  
select * from ACCOUNT 
   
< isGreaterThan  prepend ="and"  property ="id"  compareValue ="0" >
     where ACC_ID = #id# 
isGreaterThan >  
order by ACC_LAST_NAME 

select >
上面语句中可以根据参数id的不同值能构造出两条SQL查询语句,下面是一个比较复杂的例子:
< statement  id ="dynamicGetAccountList"  resultMap ="account-result"   >  
         select * from ACCOUNT 
    
< dynamic  prepend ="WHERE" >
            
  < isNotNull  prepend ="AND"  property ="firstName" >  
                    (ACC_FIRST_NAME = #firstName# 
             
< isNotNull  prepend ="OR"  property ="lastName" >  
                        ACC_LAST_NAME = #lastName#   
              
isNotNull >  
                  ) 
          
isNotNull >
  
           < isNotNull  prepend ="AND"  property ="emailAddress" >  
                    ACC_EMAIL like #emailAddress# 
             isNotNull >
 
           < isGreaterThan  prepend ="AND"  property ="id"  compareValue ="0" >  
                     ACC_ID = #id# 
             
isGreaterThan >
 
  dynamic >
 order by ACC_LAST_NAME

上面的例子中,元素划分出SQL语句的动态部分。动态部分可以包含任意多的条件标签元素,条件标签决定是否在语句中包含其中的SQL代码。所有的条件标签元素将根据传给动态查询Statement的参数对象的情况来工作。元素和条件元素都有“prepend”属性,它是动态SQL代码的一部分,在必要情况下,可以被父元素的“prepend”属性覆盖。上面的例子中,prepend属性“where”将覆盖第一个为“真”的条件元素。这对于确保生成正确的SQL语句是有必要的。例如,在第一个为“真”的条件元素中,“AND”是不需要的,事实上,加上它肯定会出错。以下小节讨论不同的条件元素,包括二元条件元素,一元条件元素和其他动态元素。
二元条件元素
       二元条件元素将一个属性值和一个静态值或另一个属性值比较,如果条件为“真”,元素体的内容将被包括在查询SQL语句中。
 二元条件元素的属性: 
prepend - 可被覆盖的SQL语句组成部分,添加在语句的前面(可选)property - 被比较的属性(必选)
compareProperty - 另一个用于和前者比较的属性(必选或选择compareValue)
 compareValue - 用于比较的值(必选或选择compareProperty)

二元条件元系的属性
比较属性值和静态值或另一个属性值是否相等。
比较属性值和静态值或另一个属性值是否不相等。
比较属性值是否大于静态值或另一个属性值。
比较属性值是否大于等于静态值或另一个属性值。
比较属性值是否小于静态值或另一个属性值。
比较属性值是否小于等于静态值或另一个属性值。 例子: ADOLESCENT = ‘TRUE’
 

一元条件元素
一元条件元素检查属性的状态是否符合特定的条件。
一元条件元素的属性:
prepend - 可被覆盖的SQL语句组成部分,添加在语句的前面(可选)
property - 被比较的属性(必选)
检查是否存在该属性(存在 parameter bean 的属性)。
检查是否不存在该属性(不存在 parameter bean 的属性)。
检查属性是否为 null
检查属性是否不为 null
 
检查 Collection.size() 的值,属性的 String String.valueOf() , 是否为 null 或空(“”或 size() < 1 )。
 
 
检查 Collection.size() 的值,属性的 String String.valueOf() , 是否不为 null 或不为空(“”或 size() > 0 )。 例子:
  FIRST_NAME=#firstName#
 
还有两个其它的条件元素,就不说了,用到的时候可以再查。

简单的动态SQL元素

虽然动态Mapped Statement API功能强大,但有时仅需要一小部分的动态SQL即可。为此,SQL statement和statement都可以包含简单的动态SQL元素,以帮助实现动态的order by子句,动态的查询字段或SQL语句的其他动态部分。简单动态SQL元素的概念有点象inline parameter的映射,但使用了稍微不同的语法。考虑下面的例子:
 
       select * from PRODUCT order by $preferredOrder$

简单动态元素可以包含在中,当要修改SQL语句本身时它能派上用场。例如:

< statement  id =”getProduct”  resultMap =”get-product-result”> 
SELECT * FROM PRODUCT 
=”WHERE”>
 
=”description”>   
       
PRD_DESCRIPTION $operator$ #description#  >  
dynamic >  
statement >

三、使用SQL Map API编程

   那那10来个方法吧,有空看看