本站不再更新,欢迎光临 java开发技术网
随笔-230  评论-230  文章-8  trackbacks-0

< 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" >  
           
<![CDATA[
             select id,vname from tuser where id=#value#
            
]]>
     
</ select >  

     
< insert  id ="insrtTuser"  parameterClass ="tuser" >
         
<![CDATA[
             insert into tuser values(#id#,#vname#)
         
]]>
     
</ insert >
     
< update  id ="updateTuser"  parameterClass ="tuser" >
         
<![CDATA[
             update tuser set id=#id# ,vname=#vname# where id=#id#
         
]]>  
     
</ update >
     
< delete  id ="deleteTuser"   >
         
<![CDATA[
             delete  from tuser where id=#id#
         
]]>
     
</ delete >
     
</ sqlMap >

再看下面这个较复杂点的SQL Map Statement

< sqlMap  id =”Product”> 
  <cacheModel id =”productCache”  type =”LRU”> 
            <flushInterval hours =”24”/> 
           <property name =”size”  value =”1000”  />  
</ cacheModel >  
< typeAlias  alias =”product”  type =”com.ibatis.example.Product”  />  
< parameterMap  id =”productParam”  class =”product”> 
          <parameter property =”id”/> 
         </parameterMap >  
< resultMap  id =”productResult”  class =”product”> 
           <result property =”id”  column =”PRD_ID”/> 
           <result property
=”description”  column =”PRD_DESCRIPTION”/> 
</resultMap >  
< select  id =”getProduct”  parameterMap =”productParam”  resultMap =”productResu      t”  cacheModel =”product-cache”> 
          select * from PRODUCT where PRD_ID  = ? 
</select >  
</ 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的结构如下所示:
<statement id=”statementName”
       [parameterClass=”some.class.Name”] 
       [resultClass=”some.class.Name”]
       [parameterMap=”nameOfParameterMap”] 
       [resultMap=”nameOfResultMap”]
       [cacheModel=”nameOfCache”] >
       select * from PRODUCT where PRD_ID = [?|#propertyName#] order by    
             [$simpleDynamic$]
</statement>
在上面的表达式中,括号[]里的部分时可选的属性,并且在某些情况下只有特定的组合才是合法的。因此下面这个简单的例子也是正确的:
    <statement id=”insertTestProduct” >
        insert into PRODUCT (PRD_ID,    PRD_DESCRIPTION) values (1, “Shih Tzu”)
</statement>
上面的例子不太可能出现,但如果只是简单地想用SQL Map架构来执行任意地的SQL语句,这种写法就派上用场了。但常见的用法还是通过Parameter Map和Result Map,来实现Java Bean映射的特性,这是SQL Map真正有价值的地方。
Statements类型
<statement>元素是个通用声明,可以用于任何类型的SQL语句。通常,使用具体的statement类型是个好主意。具体statement类型提供了更直观的XML DTD,并拥有某些

Statement 类型

属性

子元素

方法

<statement>

 

id parameterClass resultClass parameterMap resultMap cacheModel xmlResultName

 

所有的动态元素

 

insert update delete 所有的查询方法

 

<insert>

 

id parameterClass parameterMap

 

所有的动态元素 <selectKey>

 

insert

update

 delete

 

<update>

 

id

parameterClass parameterMap

 

所有的动态元素

 

Insert

Update

delete

 

<delete>

 

id parameterClass resultClass parameterMap resultMap cacheModel

 

所有的动态元素

 

所有的查询方法

 

<select>

 

id parameterClass resultClass parameterMap resultMap cacheModel

 

所有的动态元素

 

所有的查询方法

 

<procedure>

 

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" >
 
<![CDATA[
   SELECT * FROM PERSON WHERE AGE > #value# 
 
]]>
</ statement >

自动生成的主键
很多数据库支持自动生成主键的数据类型。不过这通常(并不总是)是个私有的特性。SQL Map通过<insert>的子元素<selectKey>来支持自动生成的键值。它同时支持预生成(如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通过<procedure>元素支持存储过程。下面的例子说明如何使用具有输出参数的存储过程。

< 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>元素的名称。parameterMap属性很少使用,更多的是使用上面的parameterClass和inline parameter(接下来会讨论)。 注意!动态mapped statement只支持inline parameter,不支持parameter map。 parameterMap的基本思想是定义一系列有次序的参数系列,用于匹配JDBC PreparedStatement的值符号。例如:

< parameterMap  id =”insert-product-param”  class =”com.domain.Product”>
  
<parameter property =”id”/> 
  
<parameter property =”description”/> 
</parameterMap >  
< statement  id =”insertProduct”  parameterMap =”insert-product-param”>  insert into PRODUCT (PRD_ID, PRD_DESCRIPTION) values (?,?); 
</statement
>

如上所述,parameterMap负责将Java Bean的属性映射成statement的参数。
虽然parameterMap的外部形式很少使用,理解它如何工作对于理解inline parameter还是很有帮助。本节以下部分将详细讨论inline parameter。 <parameterMap id=”parameterMapName” [class=”com.domain.Product”]> <parameter property =”propertyName” [jdbcType=”VARCHAR”] [javaType=”string”] [nullValue=”NUMERIC”] [null=”-9999999”]/> <parameter …… />
<parameter …… />
</parameterMap>
括号[]是可选的属性。parameterMap元素只要求属性id作为唯一标识。属性class是可选的但强烈推荐使用。和parameterClass类似,class属性可以框架检查输入参数的类型并优化性能。
一个<parameterMap>的例子

< parameterMap  id =”insert-product-param”  class =”com.domain.Product”>
 
<parameter property =”id”  jdbcType =”NUMERIC”  javaType =”int”  nullValue =”-9999999”/> 
<parameter property =”description”  jdbcType =”VARCHAR”  nullValue =”NO_ENTRY”/> 
</parameterMap >  
< statement  id =”insertProduct”  parameterMap =”insert-product-param”> 
insert into PRODUCT (PRD_ID, PRD_DESCRIPTION) values (?,?); 
</statement
>

注意!
parameterMap并不自动地绑定到特定的Java类。因此在上面的例子中,任何拥有“id”和“description”属性的Java Bean对象,都可以作为parameterMap的输入。如果需要将输入绑定到特定的Java类,可以使用mapped-statement的resultClass属性。
 注意!
Parameter Map的名称(name)局部的,只在定义它的SQL Map XML文件中有效。不过,加上SQL Map的名称(即在<sqlMap>根元素中的名称)作为前缀,您可以在另一个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
>

在内嵌参数中指定数据类型可以用下面的语法:

< statement  id =”insertProduct”  parameterClass =”com.domain.Product”> 
insert into PRODUCT (PRD_ID, PRD_DESCRIPTION) values (#id:NUMERIC#, #description:VARCHAR#); 
</statement
>

在内嵌参数中指定数据类型和NULL的替代值可以用这样的语法:

<statement id=”insertProduct” parameterClass=”com.domain.Product”>
insert into PRODUCT (PRD_ID, PRD_DESCRIPTION) values (#id:NUMERIC:-999999#, #description:VARCHAR:NO_ENTRY#);
</statement>

注意!在内嵌参数中,要指定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”>
 
<result property =”id”  column =”PRD_ID”/>   
<result property =”description”  column =”PRD_DESCRIPTION”/>
 
</resultMap >
 
< statement  id =”getProduct”  resultMap =”get-product-result”> 
       select * from PRODUCT 
</statement
>

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# 
</select >

上面的查询结果将产生一个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#  </statement >

Map类型输入参数

< statement  id =”insertProduct”  parameterClass =”java.util.Map”>
 
select * from PRODUCT where PRD_CAT_ID  = #catId#  and PRD_CODE  = #code# 
</statement >

可以注意到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
</statement>

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

二元条件元系的属性

<isEqual>

比较属性值和静态值或另一个属性值是否相等。

<isNotEqual>

比较属性值和静态值或另一个属性值是否不相等。

<isGreaterThan>

比较属性值是否大于静态值或另一个属性值。

<isGreaterEqual>

比较属性值是否大于等于静态值或另一个属性值。

<isLessThan>

比较属性值是否小于静态值或另一个属性值。

<isLessEqual>

比较属性值是否小于等于静态值或另一个属性值。 例子: <isLessEqual prepend=”AND” property=”age” compareValue=”18”> ADOLESCENT = ‘TRUE’ </isLessEqual>

 


一元条件元素
一元条件元素检查属性的状态是否符合特定的条件。
一元条件元素的属性:
prepend - 可被覆盖的SQL语句组成部分,添加在语句的前面(可选)
property - 被比较的属性(必选)

<isPropertyAvailable>

检查是否存在该属性(存在parameter bean的属性)。

<isNotPropertyAvailable>

检查是否不存在该属性(不存在parameter bean的属性)。

<isNull>

检查属性是否为null

<isNotNull>

检查属性是否不为null

<isEmpty>

 

检查Collection.size()的值,属性的StringString.valueOf(),是否为null或空(“”或size() < 1)。

 

<isNotEmpty>

 

检查Collection.size()的值,属性的StringString.valueOf(),是否不为null或不为空(“”或size() > 0)。 例子:

 <isNotEmpty prepend=”AND” property=”firstName” > FIRST_NAME=#firstName# </isNotEmpty>

 

还有两个其它的条件元素,<isParameterPresent>,<iterate>就不说了,用到的时候可以再查。

简单的动态SQL元素

虽然动态Mapped Statement API功能强大,但有时仅需要一小部分的动态SQL即可。为此,SQL statement和statement都可以包含简单的动态SQL元素,以帮助实现动态的order by子句,动态的查询字段或SQL语句的其他动态部分。简单动态SQL元素的概念有点象inline parameter的映射,但使用了稍微不同的语法。考虑下面的例子:
 <statement id=”getProduct” resultMap=”get-product-result”>
       select * from PRODUCT order by $preferredOrder$
</statement>
简单动态元素可以包含在<dynamic-mapped-statement>中,当要修改SQL语句本身时它能派上用场。例如:

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

三、使用SQL Map API编程

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



posted on 2007-01-04 21:31 有猫相伴的日子 阅读(11819) 评论(5)  编辑  收藏 所属分类: ibatis/hibernate/持久层技术

评论:
# re: Ibatis学习随笔 2008-03-11 15:42 | wangpan
请教:
如何调用一个带多个条件的查询语句?  回复  更多评论
  
# re: Ibatis学习随笔 2008-03-11 15:43 | wangpan
请教:
如何调用一个带多个条件的查询语句?

如这个
<select id="selectVenues" parameterClass ="int" resutlMap="account-result">
select
id,
serviceitem,
trade,
pro,
city,
vcname,
vename,
caddress,
eaddress,
gamecname,
gameename,
collecter,
batch
from o_venues

<dynamic prepend="where">
<isNotEmpty prepend="and" property="city">
(city = #city#)
</isNotEmpty>
<isNotEmpty prepend="and" property="vcname">
(vcname = #vcname#)
</isNotEmpty>
</dynamic>
</select>  回复  更多评论
  
# re: Ibatis学习随笔 2008-05-06 11:44 | 请教问题
我用ibatis读tomcat下的数据库连接池,报这个错是什么原因Cause: com.ibatis.sqlmap.engine.transaction.TransactionException: JdbcTransaction initialization failed. DataSource was null.
有人能帮解决下吗?我的qq327362894
  回复  更多评论
  
# re: Ibatis学习随笔 2009-04-30 16:15 | 56
体育  回复  更多评论
  
# re: Ibatis学习随笔 2009-12-17 21:39 | 团派家园
ibaits会如何呢?  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航:
 
本站不再更新,欢迎光临 java开发技术网