一、区分ParameterMap和ParameterClass
parameterMap
属性parameterMap的值等于一个预先定义的<parameterMap>元素的名称。parameterMap属性很少使用,更多的是使用上面的parameterClass和inline parameter
注意!动态mapped statement只支持inline parameter(内联参数),不支持parameter map。
在使用Parameter Map的时候是不能用#property#的形式显示地指定要使用的属性参数,只能通过“?”,顺序替代每一个parameter元素
缺省情况下,任何没有指定parameterMap的Mapped Statement都会被解析成inline parameter(内嵌参数)
parameterMap的基本思想是定义一系列有次序的参数系列,用于匹配JDBC PreparedStatement的值符号。例如:
<parameterMap class="com.ibatis.dataobject.Product" id="insert-product-param" >
<parameter property="id"/>
<parameter property="description"/>
<parameter property="price"/>
</parameterMap>
<statement id="insertProduct-useParaMap" parameterMap="insert-product-param">
<![CDATA[insert into t_product(prd_id,prd_description,prd_price) values(?,?,?)]]>
</statement>
上面的例子中,parameter map的两个参数按次序匹配SQL语句中的值符号(?)。因此,第一个“?”号将被“id”属性的值替换,而第二个“?”号将被“description”属性的值替换。
具体的parameterMap:
<parameterMap id=”parameterMapName” [class=”com.domain.Product”]>
<parameter property =”propertyName”
[jdbcType=”VARCHAR”]
[javaType=”string”]
[nullValue=”NUMERIC”]
[null=”-9999999”]
/>
<parameter…… />
<parameter …… />
</parameterMap>
<parameter>元素:
1.property
property是传给statement的参数对象的Java Bean属性名称。该名称根据需要,可以在statement中多次出现(即在SQL语句SET子句中被更新的属性,也可以作为条件出现在WHERE子句中)。
2.jdbcType
属性jdbcType用于显式地指定给本属性(property)赋值的数据库字段的数据类型。
注意! 大多数JDBC Driver只有在字段可以为NULL时需要指定jdbcType属性。因此,对于这些Driver,只是在字段可以为NULL时才需要指定type属性。
注意! 当使用Oracle Driver时,如果没有给可以为NULL的字段指定jdbcType属性,当试图给这些字段赋值NULL时,会出现“Invalid column type”错误。
3.javaType
属性javaType用于显式地指定被赋值参数Java属性的类名。
4.nullValue (要特别关注)
属性nullValue的值可以是对于property类型来说任意的合法值,用于指定NULL的替换值。就是说,当Java Bean的属性值等于指定值时,相应的字段将赋值NULL。这个特性允许在应用中给不支持null的数据类型(即int,double,float等)赋值null。当这些数据类型的属性值匹配null值(即匹配-9999)时,NULL将代替null值写入数据库。
</parameter>元素
parameterClass
parameterClass属性值是JAVA类的全限定名,目的是限制输入参数的类型为指定的JAVA类,如果不指定,任何带有合适属性(get/set方法)的JAVA BEAN都可以作为输入参数。
parameterClass是你要传进来的参数的类型(通常可以是Map对象,也可以是基础数据类型)
二、区分resultMap和resultClass
resultMap:可以预先定义resultMap元素,可以控制数据如何从结果集中取出,以及哪个属性匹配哪个字段。
resultMap也是你要返回的值类型(一般是对象,参考例子),从命名上就可以发现传进来的是一个Map对象,如果要用的话,要先定义。
<resultMap id="xxxxx" class="POJO(比如com.test.A)">
<result column="ID" property="Id" jdbcType="DECIMAL" />
<result column="Name" property="Name" jdbcType="varchar" />
</resultMap>
注意:前面的column出现的字段,sql语句中要出现,并且这些字段对应的类属性必须一致。
之所以采用这个,是因为,很多连表查询,查询出来的结果不一定是一条或者一个已存在的pojo,这个时候就要重新定义一个来接收。
resultMap结果映射, 需结合 resultMap 节点对映射关系加以定义。一般而言,对于insert、update、delete、select 语句,优先采用 parameterClass和 resultClass。parameterMap 使用较少,
resultMap 则大多用于嵌套查询以及存储过程的处理,之所以这样,原因是由于存储过程相对而言比较封闭(很多情况下需要调用现有的存储过程,其参数命名和返回的数据字段命名往往不符合 Java 编程中的命名习惯,并且由于我们难以通过 Select SQL 的 as 子句进行字段名转义,无法使其自动与 POJO中的属性名相匹配)。此时,使用 resultMap 建立字段名和 POJO 属性名之间的映射关系就显得非常有效。例如字段USER_ID对应的属性为userId
另一方面,由于通过 resultMap 指定了字段名和字段类型,ibatis 无需再通过 JDBC ResultSetMetaData 来动态获取字段信息,在一定程度上也提升了性能表现。
resultClass:可以把结果自动映射到相应的JAVA类中,但无法指定输出字段的类型,会对性能产生轻微的影响。
resultClass的定义格式如下:
<typeAlias alias ="PersonFactDo" type="com.xxx.PersonFactDo"/>
三、总结
parameterMap与parameterClass没有什么本质的区别,都是为了传递参数,parameterMap只是以key,value的形式传递,底层通过Map.get(key)的方式获取你的参数值,parameterClass是以属性名,属性值的方式传递,底层通过属性对应的get方法获取属性值,从这一点来讲其实Map和一个Pojo对象有一定的相似之处,仔细体会.
至于resultMap与resultClass要稍微复杂一点,resultClass很简单,直接将数据库字段映射到对象属性上。resultMap稍微有点复杂,它能支持复杂的关联查询。
由于insert,update,delete的返回结果为int,通常select语句较复杂些。复杂体现在:
1)输出参数:resultClass或resultMap; resultClass利用<typeAlias alias="" type=“”/>来定义;resultMap利用<resultMap id="" class=""><result column="" property="" jdbcType=""/> </resultMap>来定义。
2)在实际应用中,通常查询条件被封装成一个query类,而且查询条件是动态变化的,因此要利用ibatis提供的<dynamic>机制;
3) 当查询记录很多条时,利用分页查询完成