`
pf_miles
  • 浏览: 134645 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

iBatis学习笔记(映射文件小结)

阅读更多

映射文件总体形式:

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE sqlMap

PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"

"http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap namespace=”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=”productResult” cacheModel=”product-cache”>

select * from PRODUCT where PRD_ID = ?

</select>

</sqlMap>

映射的查询语句形式:

<statement id=”statementName”

[parameterClass=”some.class.Name”]

[resultClass=”some.class.Name”]

[parameterMap=”nameOfParameterMap”]

[resultMap=”nameOfResultMap”]

[cacheModel=”nameOfCache”]

[timeout=“5”]>

select * from PRODUCT where PRD_ID = [?|#propertyName#]

order by [$simpleDynamic$]

</statement>

<insert id=”insertTestProduct” >

insert into PRODUCT (PRD_ID, PRD_DESCRIPTION) values (1, “Shih Tzu”)

</insert>

<select id="getPersonsByAge" parameterClass=”int” resultClass="examples.domain.Person">

SELECT *

FROM PERSON

WHERE AGE <![CDATA[ > ]]> #value#

</select>

下面的表格说明了所有支持的查询语句形式及其属性:

 

可定义SQL Fragments对部分SQL语句进行复用:

<sql id="selectItem_fragment">

FROM items

WHERE parentid = 6

</sql>

<select id="selectItemCount" resultClass="int">

SELECT COUNT(*) AS total

<include refid="selectItem_fragment"/>

</select>

<select id="selectItems" resultClass="Item">

SELECT id, name

<include refid="selectItem_fragment"/>

</select>

 

对某些数据库的自动增长键有支持,但不同的支持策略,例:

 

<!—Oracle SEQUENCE Example -->

<insert id="insertProduct-ORACLE" parameterClass="com.domain.Product">

<selectKey resultClass="int" >

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" >

SELECT @@IDENTITY AS ID

</selectKey>

</insert>

更具体内容参见帮助文档。

 

存储过程:

<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>

 

存储过程影响数据库表,同时也影响参数对象,mode若是INOUT或OUT,参数对象会被改变,否则不改变。

 

对于映射查询,iBatis建议:参数使用inline-parameter,也就是parameterClass(不是parameterMap),而结果使用resultMap(不是resultClass)。

 

parameterMap格式:

<parameterMap id=”parameterMapName” [class=”com.domain.Product”]>

<parameter property =”propertyName” [jdbcType=”VARCHAR”] [javaType=”string”]

[nullValue=“-9999”]

[typeName=”{REF or user-defined type}”]

[resultMap=someResultMap]

[mode=IN|OUT|INOUT]

[typeHandler=someTypeHandler]

[numericScale=2]/>

<parameter …… />

<parameter …… />

</parameterMap>

 

resultMap格式:

<resultMap id=”resultMapName” class=”some.domain.Class”

[extends=”parent-resultMap”]

[groupBy=“some property list”]>

<result property=”propertyName” column=”COLUMN_NAME”

[columnIndex=”1”] [javaType=”int”] [jdbcType=”NUMERIC”]

[nullValue=”-999999”] [select=”someOtherStatement”]

[resultMap=“someOtherResultMap”]

[typeHandler=“com.mydomain.MyTypehandler”]

/>

<result ……/>

<result ……/>

<result ……/>

</resultMap>

 

java.util.Map接口的实现类也可作为parameterMap或resultMap的class。

 

复杂查询:

N+1查询(结合cache的话会比连接查询好,没有cache很糟):

<resultMap id=”get-product-result” class=”com.ibatis.example.Product”>

<result property=”id” column=”PRD_ID”/>

<result property=”description” column=”PRD_DESCRIPTION”/>

<result property=”category” column=”PRD_CAT_ID ” select=”getCategory”/>

</resultMap>

<resultMap id=”get-category-result” class=”com.ibatis.example.Category”>

<result property=”id” column=”CAT_ID”/>

<result property=”description” column=”CAT_DESCRIPTION”/>

</resultMap>

<select id=”getProduct” parameterClass=”int” resultMap=”get-product-result”>

select * from PRODUCT where PRD_ID = #value#

</select>

<select id=”getCategory” parameterClass=”int” resultMap=”get-category-result”>

select * from CATEGORY where CAT_ID = #value#

</select>

 

连接查询(iBatis解决复杂查询的通常方式,但有cache时候可能不如N+1查询):

<resultMap id=”get-product-result” class=”com.ibatis.example.Product”>

<result property=”id” column=”PRD_ID”/>

<result property=”description” column=”PRD_DESCRIPTION”/>

<result property=”category.id” column=”CAT_ID ” />

<result property=”category.description” column=”CAT_DESCRIPTION ” />

</resultMap>

<select id=”getProduct” parameterClass=”int” resultMap=”get-product-result”>

select *

from PRODUCT, CATEGORY

where PRD_CAT_ID=CAT_ID

and PRD_ID = #value#

</select>

或者:

<resultMap id=”get-product-result” class=”com.ibatis.example.Product”>

<result property=”id” column=”PRD_ID”/>

<result property=”description” column=”PRD_DESCRIPTION”/>

<result property=”category” resultMap=“get-category-result” />

</resultMap>

<resultMap id=”get-category-result” class=”com.ibatis.example.Category”>

<result property=”id” column=”CAT_ID ” />

<result property=”description” column=”CAT_DESCRIPTION ” />

</resultMap>

<select id=”getProduct” parameterClass=”int” resultMap=”get-product-result”>

select *

from PRODUCT, CATEGORY

where PRD_CAT_ID=CAT_ID

and PRD_ID = #value#

</select>

复杂集合查询:

N+1法:

<resultMap id=”get-category-result” class=”com.ibatis.example.Category”>

<result property=”id” column=”CAT_ID”/>

<result property=”description” column=”CAT_DESCRIPTION”/>

<result property=”productList” column=”CAT_ID ” select=” getProductsByCatId”/>

</resultMap>

<resultMap id=”get-product-result” class=”com.ibatis.example.Product”>

<result property=”id” column=”PRD_ID”/>

<result property=”description” column=”PRD_DESCRIPTION”/>

</resultMap>

<select id=”getCategory” parameterClass=”int” resultMap=”get-category-result”>

select * from CATEGORY where CAT_ID = #value#

</select>

<select id=”getProductsByCatId” parameterClass=”int” resultMap=”get-product-result”>

select * from PRODUCT where PRD_CAT_ID = #value#

</select>

groupBy法:

<sqlMap namespace="ProductCategory">

<resultMap id=”categoryResult” class=”com.ibatis.example.Category” groupBy=”id”>

<result property=”id” column=”CAT_ID”/>

<result property=”description” column=”CAT_DESCRIPTION”/>

<result property=”productList” resultMap=”ProductCategory.productResult”/>

</resultMap>

<resultMap id=”productResult” class=”com.ibatis.example.Product”>

<result property=”id” column=”PRD_ID”/>

<result property=”description” column=”PRD_DESCRIPTION”/>

</resultMap>

<select id=”getCategory” parameterClass=”int” resultMap=”categoryResult”>

select C.CAT_ID, C.CAT_DESCRIPTION, P.PRD_ID, P.PRD_DESCRIPTION

from CATEGORY C

left outer join PRODUCT P

on C.CAT_ID = P.PRD_CAT_ID

where CAT_ID = #value#

</select>

</sqlMap>

注:groupBy属性不能和queryForPaginatedList()调用同时使用。

N+1查询中的符合查询:

<resultMap id=”get-order-result” class=”com.ibatis.example.Order”>

<result property=”id” column=”ORD_ID”/>

<result property=”customerId” column=”ORD_CST_ID”/>

<result property=”payments” column=”{itemId=ORD_ID, custId=ORD_CST_ID}

select=”getOrderPayments”/>

</resultMap>

<select id=”getOrderPayments” resultMap=”get-payment-result”>

select * from PAYMENT

where PAY_ORD_ID = #itemId#

and PAY_CST_ID = #custId#

</select>

数据类型表:

 

自定义TypeHandler:

public class YesNoBoolTypeHandlerCallback implements TypeHandlerCallback {

private static final String YES = "Y";

private static final String NO = "N";

public Object getResult(ResultGetter getter)

throws SQLException {

String s = getter.getString();

if (YES.equalsIgnoreCase(s)) {

return new Boolean (true);

} else if (NO.equalsIgnoreCase(s)) {

return new Boolean (false);

} else {

throw new SQLException (

"Unexpected value " + s + " found where " + YES + " or " + NO + " was expected.");

}

}

public void setParameter(ParameterSetter setter, Object parameter)

throws SQLException {

boolean b = ((Boolean)parameter).booleanValue();

if (b) {

setter.setString(YES);

} else {

setter.setString(NO);

}

}

public Object valueOf(String s) {

if (YES.equalsIgnoreCase(s)) {

return new Boolean (true);

} else {

return new Boolean (false);

}

}

然后在sqlMapConfig文件里加上如下配置:

<typeHandler

javaType="boolean"

jdbcType=”VARCHAR”

callback="org.apache.ibatis.sqlmap.extensions.YesNoBoolTypeHandlerCallback"/>

缓存设置:

<cacheModel id="product-cache" type ="LRU" readOnly=”true” serialize=”false”>

<flushInterval hours="24"/>

<flushOnExecute statement="insertProduct"/>

<flushOnExecute statement="updateProduct"/>

<flushOnExecute statement="deleteProduct"/>

<property name=”cache-size” value=”1000” />

</cacheModel>

<select id=”getProductList” cacheModel=”product-cache”>

select * from PRODUCT where PRD_CAT_ID = #value#

</select>

Readonly属性默认为true,但若想要在返回的对象上做更改的话,设为false。

Serialize属性设置为false后,该cache为全局共享cache,这种cache不能是readOnly的(因为没意义)。

Cache的种类:

MEMORY——java特殊引用类实现的cache

<cacheModel id="product-cache" type="MEMORY">

<flushInterval hours="24"/>

<flushOnExecute statement="insertProduct"/>

<flushOnExecute statement="updateProduct"/>

<flushOnExecute statement="deleteProduct"/>

<property name=”reference-type” value=”WEAK” />

</cacheModel>

所有的referencetype:

 

LRU——最少使用算法的cache:

<cacheModel id="product-cache" type="LRU">

<flushInterval hours="24"/>

<flushOnExecute statement="insertProduct"/>

<flushOnExecute statement="updateProduct"/>

<flushOnExecute statement="deleteProduct"/>

<property name=”size” value=”1000” />

</cacheModel>

FIFO——先进先出算法的cache:

<cacheModel id="product-cache" type="FIFO">

<flushInterval hours="24"/>

<flushOnExecute statement="insertProduct"/>

<flushOnExecute statement="updateProduct"/>

<flushOnExecute statement="deleteProduct"/>

<property name=”size” value=”1000” />

</cacheModel>

OSCACHE——插件cache,opensymphony的cache实现,参见:http://www.opensymphony.com/oscache/

<cacheModel id="product-cache" type="OSCACHE">

<flushInterval hours="24"/>

<flushOnExecute statement="insertProduct"/>

<flushOnExecute statement="updateProduct"/>

<flushOnExecute statement="deleteProduct"/>

</cacheModel>

构造动态SQL语句:

<dynamic>元素: 总的包含元素,并提供最外层的开头预设字、开始字符串和结束字符串。

prepend – 加在本体前面的预设字符 (可选)

open – 标识本体开始的开始字符串(可选)

close – 标识本题结束的结束字符串 (可选)

dynamic元素的removeFirstPrepend属性是强制的,所以它的第一个子元素的prepend字符串在生成语句的时候总是会被取消掉。

 

二元操作标记:

<isEqual> 检查一个属性和一个给定值或另一个属性是否相等。

<isNotEqual>检查一个属性和一个给定值或另一个属性是否不相等。

<isGreaterThan> 检查一个属性是否大于一个给定值或另一个属性。

<isGreaterEqual> 检查一个属性是否大于或等于一个给定值或另一个属性。

<isLessThan> 检查一个属性是否小于一个给定值或另一个属性。

<isLessEqual> 检查一个属性是否小于或等于一个给定值或另一个属性。

属性:

prepend – the overridable SQL part that will be prepended to the statement (optional)

property – the property to be compared (required)

compareProperty – the other property to be compared (required or compareValue)

compareValue – the value to be compared (required or compareProperty)

removeFirstPrepend – removes the prepend of the first nested content producing tag (true|false, optional)

open – the string with which to open the entire resulting body content (optional)

close – the string with which to close the entire resulting body content (optional)

 

举例:

<isLessEqual prepend=”AND” property=”age” compareValue=”18”>

ADOLESCENT = ‘TRUE’

</isLessEqual>

 

一元判断标记:

<isPropertyAvailable> Checks if a property is available (i.e is a property of the parameter bean)

<isNotPropertyAvailable> Checks if a property is unavailable (i.e not a property of the parameter bean)

<isNull> Checks if a property is null.

<isNotNull> Checks if a property is not null.

<isEmpty> Checks to see if the value of a Collection, String or String.valueOf() property

is null or empty (“” or size() < 1).

<isNotEmpty> Checks to see if the value of a Collection, String or String.valueOf() property

is not null and not empty (“” or size() < 1).

属性:

prepend – the overridable SQL part that will be prepended to the statement (optional)

property – the property to be checked (required)

removeFirstPrepend – removes the prepend of the first nested content producing tag (true|false, optional)

open – the string with which to open the entire resulting body content (optional)

close – the string with which to close the entire resulting body content (optional)

举例:

<isNotEmpty prepend=”AND” property=”firstName” >

FIRST_NAME=#firstName#

</isNotEmpty>

其它标记:

<isParameterPresent> Checks to see if the parameter object is present (not null).

<isNotParameterPresent> Checks to see if the parameter object is not present (null).

属性:

prepend – the overridable SQL part that will be prepended to the statement (optional)

removeFirstPrepend – removes the prepend of the first nested content producing tag (true|false, optional)

open – the string with which to open the entire resulting body content (optional)

close – the string with which to close the entire resulting body content (optional)

举例:

<isNotParameterPresent prepend=”AND”>

EMPLOYEE_TYPE = ‘DEFAULT’

</isNotParameterPresent>

 

<iterate> Iterates over a property that is an implementation java.util.Collection, or

java.util.Iterator, or is an array.

例:

<iterate prepend=”AND” property=”userNameList”

open=”(” close=”)” conjunction=”OR”>

username=#userNameList[]#

</iterate>

当集合类单独被当作参数传进此查询时,也可以这么写:

<iterate prepend=”AND” open=”(” close=”)” conjunction=”OR”>

username=#[]#

</iterate>

也可以像这样选择集合中对象的属性:

<iterate prepend=”AND” property=”userList”

open=”(” close=”)” conjunction=”OR”>

firstname=#userList[].firstName# and

lastname=#userList[].lastName#

</iterate>

该标签还可以自己嵌套:

<dynamic prepend="where">

<iterate property="orConditions" conjunction="or">

(

<iterate property="orConditions[].conditions"

conjunction="and">

$orConditions[].conditions[].condition$

#orConditions[].conditions[].value#

</iterate>

)

</iterate>

</dynamic>

若只是想生成一些简单的动态sql语句,这样写就可以:

<select id=”getProduct” resultMap=”get-product-result”>

select * from PRODUCT order by $preferredOrder$

</select>

注意“$”,不是“#”,这是和为preparedStatement赋值的普通属性的取得的不同之处。

分享到:
评论
1 楼 hesy_007 2008-09-17  
真是天下文章一大抄,你抄我来我抄他。

相关推荐

    iBATIS-SqlMaps,ibatis映射文件

    iBATIS的核心概念是SqlMapConfig.xml配置文件和一系列的SqlMap.xml映射文件,这两个文件是理解iBATIS工作原理的关键。 SqlMapConfig.xml是整个iBATIS框架的全局配置文件,它包含了数据源、事务管理器等核心组件的...

    iBatis2学习笔记

    3.iBatis2学习笔记:单表映射 .doc 4.iBatis2学习笔记:SqlMap的配置总结(18条).doc 5.iBatis2学习笔记:入参和返回值的问题.doc 6.iBatis2学习笔记:一对多映射(双向).doc 7.iBatis2学习笔记:多对多映射(双向)...

    IBatis学习笔记以及使用心得

    IBatis学习笔记以及使用心得IBatis学习笔记以及使用心得IBatis学习笔记以及使用心得IBatis学习笔记以及使用心得IBatis学习笔记以及使用心得IBatis学习笔记以及使用心得

    ibatis配置文件、映射文件详解

    ### ibatis配置文件、映射文件详解 #### 1. SQL Map Config 文件详解 在ibatis框架中,`sqlMapConfig.xml`是一个非常重要的配置文件,它主要用于设置ibatis的全局配置信息,包括数据库连接信息、环境配置以及其它...

    ibatis 的关系映射

    iBATIS通过配置XML映射文件或注解来定义这种映射关系。映射文件通常包含SQL语句和结果映射,其中结果映射定义了数据库查询结果如何转换为Java对象。 例如,在一对多关系中,一个实体(如用户)可以有多个关联的实体...

    ibatis学习笔记

    ibatis学习笔记 ibatis学习笔记 ibatis学习笔记 ibatis学习笔记 ibatis学习笔记 ibatis学习笔记 ibatis学习笔记

    ibatis映射文件信息,接口对应

    标题和描述中提到的“ibatis映射文件信息,接口对应”是指Ibatis如何通过映射文件与Java接口进行关联,实现数据操作的封装和调用。 首先,我们需要了解Ibatis的核心组成部分:SqlMapConfig.xml配置文件、Mapper接口...

    ibatis学习笔记.txt

    ### iBatis 学习笔记知识点总结 #### 一、iBatis 概念与特点 **1.1 iBatis 定义** - **iBatis** 是一个基于 Java 的开源持久层框架,它专注于 SQL 映射,提供了一种将对象与数据库交互过程中的 SQL 语句进行分离的...

    ibatis配置、映射文件详解.doc

    《iBatis配置与映射文件详解》 iBatis,作为一个轻量级的持久层框架,以其灵活的SQL映射和良好的数据库交互性深受开发者喜爱。本文将深入解析iBatis的核心配置文件`sqlMapConfig.xml`,以及映射文件的使用方法,...

    ibatis 学习小结笔记

    ### ibatis 学习小结笔记 #### 一、ibatis 概述 ibatis 是一个基于 Java 的持久层框架,它提供了一种简便的方式来处理关系型数据库与 Java 对象之间的映射(O/R Mapping)。ibatis 在设计上强调的是 SQL 语句的...

    ibatis学习笔记(一)

    这篇“ibatis学习笔记(一)”可能是博主对Ibatis基础概念、安装配置以及基本使用的介绍,让我们通过标签“源码”和“工具”来深入探讨Ibatis的相关知识。 首先,Ibatis是一个轻量级的Java ORM(对象关系映射)框架...

    ibatis 学习笔记

    **SQL Maps** 是iBATIS的核心,它通过XML文件将JavaBean、Map实现甚至是基本类型包装类(如String、Integer等)映射到JDBC PreparedStatement。SQL Maps简化了数据库操作,减少了大量手写SQL的代码。使用过程包括三...

    持久层框架ibatis学习笔记

    通过本文的学习笔记,我们可以了解到 iBatis 在简化数据库访问的同时提供了足够的灵活性。尽管 iBatis 相比 Hibernate 在自动化程度上略显不足,但对于需要高度定制 SQL 查询的场景来说,iBatis 的优势十分明显。...

    \ibatis配置文件、映射文件详解

    本文将深入探讨iBATIS的核心配置文件——`sqlMapConfig.xml`,以及映射文件的详细内容。 `sqlMapConfig.xml`是iBATIS的全局配置文件,它包含了所有iBATIS运行时的设置,如数据源、事务管理器、缓存配置等。让我们...

    IBATIS学习笔记

    ### IBATIS学习笔记知识点详解 #### 一、IBATIS简介 iBatis是一个用于Java的数据持久化框架,类似于Hibernate、JDO和EJB等技术。它的主要特点是将对象映射为SQL语句,这使得开发人员可以更加灵活地控制SQL的执行,...

    ibatis SQL映射文件、DAO、model自动生成工具源码

    Ibatis 是一款轻量级的Java持久层框架,它提供了SQL映射文件和基于XML或注解的SQL语句配置,使得开发者可以更加灵活地控制SQL的编写,从而避免了传统的JDBC代码中的大量模板式代码。这个"ibatis SQL映射文件、DAO、...

    Ibatis学习笔记,文档,资源6合1

    这个压缩包集合了Ibatis的学习笔记、文档和相关资源,为想要深入理解和掌握Ibatis的人提供了一站式的自学材料。 Ibatis的核心概念是SQL Mapping,它允许开发者将SQL语句直接写在XML配置文件中,或者使用注解方式,...

Global site tag (gtag.js) - Google Analytics