1、sqlmap摘自IBatis官网java版中文开发文档,动态SQL,优雅的条件组合:直接使用JDBC一个非常普遍的问题是动态SQL。使用参数值、参数本身和数据列都是动态的SQL,通常非常困难。典型的解决方法是,使用一系列if-else条件语句和一连串讨厌的字符串连接。对于这个问题,SQLMapAPI使用和mappedstatement非常相似的结构,提供了较为优雅的方法。这里是一个简单的例子:程序代码:select*fromACCOUNTwhereACC_ID=#id#orderbyACC_LAST_NAME上面的例子中,根据参数bean“id”属性的不同情况,可创建两个可能的语句。如果参数“
2、id”大于0,将创建下面的语句:程序代码:select*fromACCOUNTwhereACC_ID=?或者,如果“id”参数小于等于0,将创建下面的语句:程序代码:select*fromACCOUNT在更复杂的例子中,动态MappedStatement的用处更明显。如下面比较复杂的例子:程序代码:select*fromACCOUNT(ACC_FIRST_NAME=#firstName#ACC_LAST_NAME=#lastName#)ACC_EMAILlike#emailAddress#ACC_ID=#id#orderbyACC_LAST_NAMEClintonBegin著刘涛(toleu)
3、译开发指南iBATISSQLMapsPage42of62根据不同的条件,上面动态的语句可以产生16条不同的查询语句。使用if-else结构和字符串,会产生上百行很乱的代码。而使用动态Statement,和在SQL的动态部位周围插入条件标签一样容易。例如:程序代码:select*fromACCOUNTACC_ID=#id#ACC_LAST_NAME=#lastName#orderbyACC_LAST_NAME上面的例子中,元素划分出SQL语句的动态部分。动态部分可以包含任意多的条件标签元素,条件标签决定是否在语句中包含其中的SQL代码。所有的条件标签元素将根据传给动态查询Statement的参数
4、对象的情况来工作。元素和条件元素都有“prepend”属性,它是动态SQL代码的一部分,在必要情况下,可以被父元素的“prepend”属性覆盖。上面的例子中,prepend属性“where”将覆盖第一个为“真”的条件元素。这对于确保生成正确的SQL语句是有必要的。例如,在第一个为“真”的条件元素中,“AND”是不需要的,事实上,加上它肯定会出错(ibatis还是挺周到的,-_-,得试验下如果为“假”的情况,这个WHERE”还在不在了)。以下小节讨论不同的条件元素,包括二元条件元素,一元条件元素和其他动态元素。/=摘自javaeye在复杂查询过程中,我们常常需要根据用户的选择决定查询条件,这里发
5、生变化的并不只是SQL中的参数,包括Select语句中所包括的字段和限定条件,都可能发生变化。典型情况,如在一个复杂的组合查询页面,我们必须根据用户的选择和输入决定查询的条件组合。一个典型的页面如下:对于这个组合查询页面,根据用户选择填写的内容,我们应为其生成不同的查询语句。如用户没有填写任何信息即提交查询请求,我们应该返回所有记录:Select*fromt_user;如用户只在页面上填写了姓名“Erica”,我们应该生成类似:Select*fromt_userwherenamelike%Erica%;的SQL查询语句。如用户只在页面上填写了地址“Beijing”,我们应该生成类似:Selec
6、t*fromt_userwhereaddresslike%Beijing%”;的SQL。而如果用户同时填写了姓名和地址(”Erica”&Beijing),则我们应生成类似:Select*fromt_userwherenamelike%Erica%andaddresslike%Beijing%”的SQL查询语句。对于ibatis这样需要预先指定SQL语句的ORM实现而言,传统的做法无非通过if-else语句对输入参数加以判定,然后针对用户选择调用不同的statement定义。对于上面这种简单的情况(两种查询条件的排列组合,共4种情况)而言,statement的重复定义工作已经让人不厌其烦,而对于
7、动辄拥有七八个查询条件,乃至十几个查询条件的排列组合而言,琐碎反复的statement定义实在让人不堪承受。考虑到这个问题,ibatis引入了动态映射机制,即在statement定义中,根据不同的查询参数,设定对应的SQL语句。还是以上面的示例为例:selectid,name,sexfromt_user(namelike#name#)(addresslike#address#)通过dynamic节点,我们定义了一个动态的WHERE子句。此WHERE子句中将可能包含两个针对name和address字段的判断条件。而这两个字段是否加入检索取决于用户所提供的查询条件(字段是否为空isNotEmpty
8、)。对于一个典型的Web程序而言,我们通过HttpServletRequest获得表单中的字段名并将其设入查询参数,如:user.setName(request.getParameter(name);user.setAddress(request.getParameter(address);sqlMap.queryForList(User.getUsers,user);在执行queryForList(User.getUsers,user)时,ibatis即根据配置文件中设定的SQL动态生成规则,创建相应的SQL语句。上面的示例中,我们通过判定节点isNotEmpty,指定了关于name和add
9、ress属性的动态规则:(namelike#name#)这个节点对应的语义是,如果参数类的name属性非空(isNotEmpty,即非空字符串”),则在生成的SQLWhere字句中包括判定条件(namelike#name#),其中#name#将以参数类的name属性值填充。Address属性的判定生成与name属性完全相同,这里就不再赘述。这样,我们通过在statement定义中引入dynamic节点,很简单的实现了SQL判定子句的动态生成,对于复杂的组合查询而言,这将带来极大的便利。判定节点的定义可以非常灵活,我们甚至可以使用嵌套的判定节点来实现复杂的动态映射,如:(name=#name#a
10、ddress=#address#)这段定义规定,只有用户提供了姓名信息时,才能结合地址数据进行查询(如果只提供地址数据,而将姓名信息忽略,将依然被视为全检索)。Dynamic节点和判定节点中的prepend属性,指明了本节点中定义的SQL子句在主体SQL中出现时的前缀。如:(namelike#name#)(addresslike#address#)假设name属性的值为“Erica”,address属性的值为“Beijing”,则会生成类似下面的SQL子句(实际运行期将生成带占位符的PreparedStatement,之后再为其填充数据):WHERE(namelikeBeijing)AND(a
11、ddresslikeBeijing)其中WHERE之后的语句是在dynamic节点中所定义,因此以dynamic节点的prepend设置(WHERE)作为前缀,而其中的”AND”,实际上是address属性所对应的isNotEmpty节点的prepend设定,它引领了对应节点中定义的SQL子句。至于name属性对应的isNotEmpty节点,由于ibatis会自动判定是否需要追加prepend前缀,这里(namelike#name#)是WHERE子句中的第一个条件子句,无需AND前缀,所以自动省略。判定节点并非仅限于isNotEmpty,ibatis中提供了丰富的判定定义功能。判定节点分两类:
12、一元判定一元判定是针对属性值本身的判定,如属性是否为NULL,是否为空值等。上面示例中isNotEmpty就是典型的一元判定。一元判定节点有:节点名描述参数类中是否提供了此属性与相反属性值是否为NULL与相反如果属性为Collection或者String,其size是否1,如果非以上两种类型,则通过String.valueOf(属性值)获得其String类型的值后,判断其size是否1与相反。二元判定二元判定有两个判定参数,一是属性名,而是判定值,如(age=#age#)其中,property=age指定了属性名”age”,compareValue=”18”指明了判定值为”18”。上面判定节点
13、isGreaterThan对应的语义是:如果age属性大于18(compareValue),则在SQL中加入(age=#age#)条件。二元判定节点有:节点名属性值与compareValues的关系相等。不等。大于大于等于小于小于等于ibatis动态mapped Statement 配置详解分类:Database2007-08-23 11:102862人阅读评论(1)收藏举报动态 Mapped Statement直接使用 JDBC 一个非常普遍的问题是动态 SQL。使用参数值、参数本身和数据列都是动态的 SQL,通常非常困难。典型的解决方法是,使用一系列 if-else 条件语句和一连串讨厌的
14、字符串连接。对于这个问题,SQL Map API使用和 mapped statement非常相似的结构,提供了较为优雅的方法。这里是一个简单的例子:select * from ACCOUNTwhere ACC_ID = #id#order by ACC_LAST_NAME上面的例子中,根据参数 bean“id”属性的不同情况,可创建两个可能的语句。如果参数“id”大于 0,将创建下面的语句:select * from ACCOUNT where ACC_ID = ?或者,如果“id”参数小于等于 0,将创建下面的语句:select * from ACCOUNT在更复杂的例子中,动态 Mappe
15、d Statement 的用处更明显。如下面比较复杂的例子:select * from ACCOUNT(ACC_FIRST_NAME = #firstName#ACC_LAST_NAME = #lastName#)ACC_EMAIL like #emailAddress#ACC_ID = #id#order by ACC_LAST_NAME根据不同的条件,上面动态的语句可以产生 16 条不同的查询语句。使用 if-else 结构和字符串,会产生上百行很乱的代码。而使用动态 Statement,和在 SQL 的动态部位周围插入条件标签一样容易。例如:select * from ACCOUNTAC
16、C_ID = #id#ACC_LAST_NAME = #lastName#order by ACC_LAST_NAME上面的例子中,元素划分出SQL 语句的动态部分。动态部分可以包含任意多的条件标签元素,条件标签决定是否在语句中包含其中的 SQL 代码。所有的条件标签元素将根据传给动态查询 Statement 的参数对象的情况来工作。元素和条件元素都有“prepend”属性,它是动态 SQL 代码的一部分,在必要情况下,可以被父元素的“prepend”属性覆盖。上面的例子中,prepend属性“where”将覆盖第一个为“真”的条件元素。这对于确保生成正确的 SQL 语句是有必要的。例如,在第
17、一个为“真”的条件元素中,“AND”是不需要的,事实上,加上它肯定会出错。以下小节讨论不同的条件元素,包括二元条件元素,一元条件元素和其他动态元素。二元条件元素二元条件元素将一个属性值和一个静态值或另一个属性值比较,如果条件为“真”,元素体的内容将被包括在查询 SQL 语句中。 二元条件元素的属性:prepend 可被覆盖的 SQL 语句组成部分,添加在语句的前面(可选)property 被比较的属性(必选)compareProperty 另一个用于和前者比较的属性(必选或选择 compareValue)compareValue 用于比较的值(必选或选择 compareProperty)比较属
18、性值和静态值或另一个属性值是否相等。比较属性值和静态值或另一个属性值是否不相等。比较属性值是否大于静态值或另一个属性值。比较属性值是否大于等于静态值或另一个属性值。比较属性值是否小于静态值或另一个属性值。比较属性值是否小于等于静态值或另一个属性值。例子:ADOLESCENT = TRUE一元条件元素一元条件元素检查属性的状态是否符合特定的条件。 一元条件元素的属性:prepend 可被覆盖的 SQL 语句组成部分,添加在语句的前面(可选)property 被比较的属性(必选)检查是否存在该属性(存在 parameter bean 的属性)。检查是否不存在该属性(不存在 parameter be
19、an 的属性)。检查属性是否为 null。检查属性是否不为 null。检查 Collection.size()的值,属性的 String 或 String.valueOf()值,是否为 null或空(“”或size() 1)。检查 Collection.size()的值,属性的 String 或 String.valueOf()值,是否不为 null 或不为空(“”或 size() 0)。例子:FIRST_NAME=#firstName#其他元素 Parameter Present:这些元素检查参数对象是否存在。Parameter Present的属性:prepend 可被覆盖的 SQL 语句
20、组成部分,添加在语句的前面(可选)检查是否存在参数对象(不为 null)。检查是否不存在参数对象(参数对象为 null)。例子:EMPLOYEE_TYPE = DEFAULT Iterate:这属性遍历整个集合,并为 List 集合中的元素重复元素体的内容。Iterate 的属性:prepend 可被覆盖的 SQL 语句组成部分,添加在语句的前面(可选)property 类型为 java.util.List 的用于遍历的元素(必选)open 整个遍历内容体开始的字符串,用于定义括号(可选)close 整个遍历内容体结束的字符串,用于定义括号(可选)conjunction 每次遍历内容之间的字符串,用于定义 AND 或 OR(可选)遍历类型为 java.util.List的元素。例子:iterate prepend=”AND” pro
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1