所谓的映射器可以理解为前面配置的mapper.xml文件,在这个文件中我们通过namespace将配置和指定的Dao层接口关联起来,准确的来说是为每个Dao层接口中的方法配置具体的sql语句;另外mapper文件中还可以为查询语句灵活的配置返回结果对象(javaBean),根据需要构建动态sql等功能。在映射器中可以定义的元素有select insert delete update等代表具体sql操作类型的元素,另外还有sql(预定义好的一部分sql语句,可以在其它地方引用),resultMap(用来实现从数据库查询结果集到Java对象的映射,是最复杂和强大的元素),cache(给定命名空间的缓存配置),cache-ref(其它命名空间缓存配置)。下面来看下这些元素的具体配置。
1.select元素
select元素可以说是最强大也是最常用的sql元素,基本的过程是在执行查询之前需要指定参数的类型,这个类型可以是简单的int float,也可以是复杂的JavaBean,Map等元素
在执行查询之后,可以通过ResultMap将查询结果映射为指定的Java Bean。具体的可配置参数如下,
元素 | 说明 | 备注 |
---|---|---|
id | 和mapper元素的namespace组合起来唯一对应到一个方法,提供给mybatis调用 | 如通过命名空间和id组合起来不唯一,MyBatis将抛出异常 |
parameterType | 指定传入参数的类型,多用于单参数情况,可以是基本类型,也可以是JavaBean全名或别名 | 可以选择JavaBean或Map等复杂的参数类型传递给SQL |
resultType | 配置返回值类型,可以是int、double等基本类型,也可以配置JavaBean(全路径或别名),如果JavaBean的字段名和数据库返回字段名一致,可以实现自动映射。不能和resltMap同用 | 最常用的元素之一,比如我们统计总条数就将其置为int |
resultMap | 结果映射Map,可以在其中自定义映射规则 | 它是MyBatis最复杂的元素,可以配置映射规则、级联、typeHandler等 |
flushCache | 它的作用是在调用SQL后是否要求Mybatis清空之前查询的本地缓存和二级缓存 | 取值为布尔类型,默认为false |
useCache | 启动二级缓存的开关,是否要求MyBatis将此次结果缓存 | 取值为布尔型,默认为true |
timeout | 设置超时参数,等超时的时候将抛出异常,单位为秒 | 默认是底层JDBC驱动设置的秒数 |
fetchSize | 获取记录的总条数设定 | 默认是JDBC所设置的条数 |
statementType | 设置Mybatis使用的Statement,可以选择的有STATEMENT(statement)、PREPARED(PreparedStatement)、CallableStatement | 默认使用的是PREPARED |
parameterType:用于指定从接口传入参数的类型,参数可能是基本类型也有可能是Java Bean或其它集合类型.对于单个参数,可以直接用参数名引用,对于多个参数(无论是多个java Bean还是多个普通类型的参数,其实都是以Map形式传入的,如果使用了@param注解,那么Map的key就是注解中的参数名,如果只有一个参数,则可以直接通过名字引用否则就只能通过下标形式进行引用),传入Collections集合的处理(比如传入一个基本类型的list,或传入一个Java Bean类型的list)。
一个简单例子:统计名称中包含指定关键词的商品数目。
<select id="countProductByName" parameterType="string" resultType="int">
select count(1) as total from product where product_name like concat('%',#{productName},'%')
</select>
这里通过id来标识这条sql对应的方法,parameterType定义参数类型,resultType定义返回值类型。
自动映射:如果只要返回的数据库字段和javaBean的属性一致,Mybatis就会帮助我们回填这些字段,而无需额外的配置。autoMappingBehavior属性可以用来指定是否需要开启这种自动映射,有三个可选项:NONE(取消自动映射) PARTIAL(只会自动映射,没有定义嵌套结果集映射的结果集) FULL(会自动映射任意复杂的结果集,包括嵌套结果集情况)。默认的是PARTIAL,只会映射当前对象,使用FULL嵌套映射,性能可能会下降。如果数据库是下划线命名方式而JavaBean是驼峰式,那么可以在setting中配置mapUndersorceToCamelCase为true,实现下划线转驼峰.自动映射的JavaBean是通过resultType属性指定的。
多参数传递:少量参数使用@Param方式注解,在mapper.xml文件中可以直接通过@Param指定的名字进行引用;大量参数可以封装成JavaBean传入,通过ParameterType指定参数类型之后,在mapper.xml文件中,可以通过JavaBean的属性名称进行引用。对于单个参数,可以直接传递,直接通过名字引用。当参数数目比较少的时候,可以通过@Param方式传入,如果参数
数目过多,可以封装成Java Bean的形式传入,如果传入的参数中既有基本类型又有JavaBean类型,则还是需要通过@Param参数进行区分。
2.insert元素
insert元素比select元素简单很多,mybatis会在插入之后返回一个整数,表示插入的条数;对于insert元素来说,和select一样,首先都需要关注参数的
传递.可以配置的属性一些和select元素是相同的,另外一些是特有的,主要看下特有的属性。
参数 | 说明 |
---|---|
flushCache | 作用是执行sql之后是否需要情况mybatis的本地查询缓存和二级缓存,默认是false |
keyProperty | 表示以哪个列作为属性的主键,不能与keyColumn同时使用.如果是联合主键,以逗号分隔开 |
keyColumn | 指定第几列是主键,只接受整型参数,不能与keyProperty同时使用,如果是联合主键,以逗号隔开 |
useGeneralKeys | 会让mybatis使用jdbc的getGeneralKeys方法来取出数据库内部生成的主键,比如mysql的自动递增id,必须和keyProperty或keyColumn配合使用,默认为false。使用这个属性可以实现主键值的回填,注意,这个属性设置为true的时候,返回结果映射的POJO对象中必须有一个字段和主键值完全同名,否则在回填结果的时候会报错 |
insert中的主键回填:
如果在数据库中定义了自增主键,那么在有些情况下在插入数据之后希望能获得生成的主键以便进行另外的操作。在mybatis中设置了keyProperty和keyColumn之后,再把useGeneralKeys设为true,则可以实现主键的回填。
使用SelectKey实现自定义主键:
如果数据库不支持自动生成主键或者数据库默认生成主键的规则不能满足我们的要求,那么可以通过这个元素来进行主键的生成,可以配置的属性:
keyProperty:需要被selectKey语句设置的目标属性列名
resultType:结果类型,一般mybatis可以默认计算出
order:可以被设置为 BEFORE 或 AFTER。如果设置为 BEFORE,那么它会首先选择主键,设置 keyProperty 然后执行插入语句。如果设置为 AFTER,那么先执行插入语句,然后是 selectKey 元素 - 这和像 Oracle 的数据库相似,在插入语句内部可能有嵌入索引调用。
其实在selectKey中只是给propertyKey指定的属性赋了一个值,这个值甚至可以是完全随机的,也可以是根据mybatis现有主键值进行生成的。
3.update和delete元素
这两个元素和insert元素类似,都是返回操作影响的行数,主要需要关注的是参数的传递。总的来说,映射文件中配置的select insert update和delete几个sql元素,对应的就是sql中的几个语句.对于这些元素来说,都需要关心的是参数的传递,sql语句的组织(动态sql),另外对于select元素来说还需要关心查询结果的映射。对于参数的传递,可以配置的属性是parameterType 对于结果集的映射主要通过resultMap元素来进行配置。这两个属性在上面都已经涉及到,至于动态sql的拼装,会在后面进行学习。
4.sql元素
sql元素的作用在于预先定义好一个sql的片段,然后在其它地方就可以直接引用。最简单的示例如下:
<sql id="columns">
branch_id,name,city,state,zip
</sql>
<select id="test" resultType="branch">
select
<include refid="columns"/>
from branch where branch_id=#{branchId}
</select>
更复杂一点,还可以往sql中传入动态的属性,注意这里的变量不能用#定义而要用$定义,如下:
<sql id="columns">
${prefix}.branch_id,${prefix}.name,${prefix}.city,${prefix}.state,${prefix}.zip
</sql>
<select id="test" resultType="branch">
select
<include refid="columns">
<property name="prefix" value="branch"/>
</include>
from branch where branch_id=#{branchId}
</select>
5.resultMap属性
前面在select元素已经提到了resultMap元素,这里进行更详细的了解。目前来说,resultMap的主要作用是实现结果集的映射以及配置类型转换器。
首先来看下resultMap元素的构成,前面用到的主要是id和result两个元素,但是除此之外还有很多其它元素,所有可配置的属性如下:
<resultMap>
<constructor>
<idArg/>
<arg/>
</constructor>
<id/>
<result/>
<association/>
<collection/>
<discriminator>
<case/>
</discriminator>
</resultMap>
constructor元素用来配置构造器,适用于有些JavaBean没有提供无参构造器的情况,比如Branch对象只有一个 public Branch(int branch_id, String name)形式的构造器,那么就需要配置如下的constructor元素,这样mybatis才知道需要那个构造器来构造POJO对象。
<constructor>
<idArg column="branch_id" javaType="int"/>
<arg column="name" javaType="string"/>
</constructor>
这里的int 和string都是mybatis默认定义的系统别名,分别对应Integer和String类型。
id元素用来指明那个列是表的主键,如果有是联合主键,则可以配置多个id元素,result用来定义数据库列名到POJO属性的映射。
id和result元素都有以下属性可以进行配置:
property //POJO中属性名
columns //数据库中列名
javaType //属性的Java类型
jdbcType //列对应的数据库类型
typeHandler //数据库类型向Java类型转换的转换器
此外的association collection discriminator都是和级联相关的几个字段,暂时不做介绍。