select属性:
<select
id=”selectPerson”
parameterType=”int”
parameterMap=”deprecated”
resultType=”hashmap”
resultMap=”personResultMap”
flushCache=”false”
useCache=”true”
timeout=”10000”
fetchSize=”256”
statementType=”PREPARED”
resultSetType=”FORWARD_ONLY”
>
属性描述:
id在命名空间中唯一的标识符,可以被用来引用这条语句。
parameterType将会传入这条语句的参数类的完全限定名或别名。
parameterMap这是引用外部parameterMap的已经被废弃的方法。使用内联参数
映射和parameterType属性。
resultType从这条语句中返回的期望类型的类的完全限定名或别名。注意集
合情形,那应该是集合可以包含的类型,而不能是集合本身。使
用resultType或resultMap,但不能同时使用。
resultMap命名引用外部的resultMap。返回map是MyBatis最具力量的特性,
对其有一个很好的理解的话,许多复杂映射的情形就能被解决了。
使用resultMap或resultType,但不能同时使用。
flushCache将其设置为true,不论语句什么时候被带哦用,都会导致缓存被
清空。默认值:false。
useCache将其设置为true,将会导致本条语句的结果被缓存。默认值:true。
timeout这个设置驱动程序等待数据库返回请求结果,并抛出异常时间的
最大等待值。默认不设置(驱动自行处理)。
fetchSize这是暗示驱动程序每次批量返回的结果行数。默认不设置(驱动
自行处理)。
statementType STATEMENT,PREPARED或CALLABLE的一种。这会让MyBatis
使用选择使用Statement,PreparedStatement或CallableStatement。
默认值:PREPARED。
resultSetType FORWARD_ONLY|SCROLL_SENSITIVE|SCROLL_INSENSITIVE
中的一种。默认是不设置(驱动自行处理)。
insert属性:
<insert
id="insertAuthor"
parameterType="domain.blog.Author"
flushCache="true"
statementType="PREPARED"
keyProperty=""
useGeneratedKeys=""
timeout="20000">
update属性:
<update
id="insertAuthor"
parameterType="domain.blog.Author"
flushCache="true"
statementType="PREPARED"
timeout="20000">
delete属性:
<delete
id="insertAuthor"
parameterType="domain.blog.Author"
flushCache="true"
statementType="PREPARED"
timeout="20000">
属性描述:
id在命名空间中唯一的标识符,可以被用来引用这条语句。
parameterType将会传入这条语句的参数类的完全限定名或别名。
parameterMap这是引用外部parameterMap的已经被废弃的方法。使用内联参数
映射和parameterType属性。
flushCache将其设置为true,不论语句什么时候被带哦用,都会导致缓存被清
空。默认值:false。
timeout这个设置驱动程序等待数据库返回请求结果,并抛出异常时间的最
大等待值。默认不设置(驱动自行处理)。
statementType STATEMENT,PREPARED或CALLABLE的一种。这会让MyBatis
使用选择使用Statement,PreparedStatement或CallableStatement。
默认值:PREPARED。
useGeneratedKeys(仅对insert有用)这会告诉MyBatis使用JDBC的
getGeneratedKeys方法来取出由数据(比如:像MySQL和SQL
Server这样的数据库管理系统的自动递增字段)内部生成的主键。
默认值:false。
keyProperty(仅对insert有用)标记一个属性,MyBatis会通过getGeneratedKeys
或者通过insert语句的selectKey子元素设置它的值。默认:不设置。
<insertid="insertAuthor"parameterType="domain.blog.Author">
insert into Author(id,username,password,email,bio)
values(#{id},#{username},#{password},#{email},#{bio})
</insert>
<updateid="updateAuthor"parameterType="domain.blog.Author">
update Author set
username=#{username},
password=#{password},
email=#{email},
bio=#{bio}
where id=#{id}
</update>
<deleteid="deleteAuthor”parameterType="int">
delete from Author where id=#{id}
</delete>
首先,如果你的数据库支持自动生成主键的字段(比如MySQL和SQLServer),那么
你可以设置useGeneratedKeys=”true”,而且设置keyProperty到你已经做好的目标属性上。
例如,如果上面的Author表已经对id使用了自动生成的列类型,那么语句可以修改为:
<insertid="insertAuthor"parameterType="domain.blog.Author"
useGeneratedKeys=”true”keyProperty=”id”>
insert into Author(username,password,email,bio)
values(#{username},#{password},#{email},#{bio})
</insert>
MyBatis有另外一种方法来处理数据库不支持自动生成类型,或者可能JDBC驱动不支
持自动生成主键时的主键生成问题。
这里有一个简单(甚至很傻)的示例,它可以生成一个随机ID(可能你不会这么做,
但是这展示了MyBatis处理问题的灵活性,因为它并不真的关心ID的生成):
<insert id="insertAuthor" parameterType="domain.blog.Author">
<selectKey keyProperty="id" resultType="int"order="BEFORE">
select CAST(RANDOM()*1000000 as INTEGER)a from SYSIBM.SYSDUMMY1
</selectKey>
insert into Author
(id,username,password,email,bio,favourite_section)
values
(#{id},#{username},#{password},#{email},#{bio},
#{favouriteSection,jdbcType=VARCHAR}
)
</insert>
在上面的示例中,selectKey元素将会首先运行,Author的id会被设置,然后插入语句
会被调用。这给你了一个简单的行为在你的数据库中来处理自动生成的主键,而不需要使你
的Java代码变得复杂。
selectKey元素:
<selectKey
keyProperty="id"
resultType="int"
order="BEFORE"
statementType="PREPARED"
>
属性描述:
keyProperty selectKey语句结果应该被设置的目标属性。
resultType结果的类型。MyBatis通常可以算出来,但是写上也没有问题。
MyBatis允许任何简单类型用作主键的类型,包括字符串。
order这可以被设置为BEFORE或AFTER。如果设置为BEFORE,那
么它会首先选择主键,设置keyProperty然后执行插入语句。如果
设置为AFTER,那么先执行插入语句,然后是selectKey元素-
这和如Oracle数据库相似,可以在插入语句中嵌入序列调用。
statementType和前面的相同,MyBatis支持STATEMENT,PREPARED和
CALLABLE语句的映射类型,分别代表PreparedStatement和CallableStatement类型。
sql:
这个元素可以被用来定义可重用的SQL代码段,可以包含在其他语句中。比如:
<sql id=”userColumns”>id,username,password</sql>
这个SQL片段可以被包含在其他语句中,例如:
<select id=”selectUsers” parameterType=”int” resultType=”hashmap”>
select<include refid=”userColumns”/>
from some_table
where id=#{id}
</select>
Parameters:
用来指定一个确定的数据类型,如:
#{property,javaType=int,jdbcType=NUMERIC}
例子:
#{department,
mode=OUT,
jdbcType=CURSOR,
javaType=ResultSet,
resultMap=departmentResultMap}
mode属性允许你指定IN,OUT或INOUT参数。如果参数为OUT或INOUT,参数对象属性的真实值将会被改变,就像你期望你需要你个输出参数。如果mode为OUT(或INOUT),而且jdbcType为CURSOR(也就是Oracle的REFCURSOR),你必须指定一个resultMap来映射结果集到参数类型。要注意这里的javaType属性是可选的,如果左边的空白是jdbcType的CURSOR类型,它会自动地被设置为结果集。
resultMap:
<!--column不做限制,可以为任意表的字段,而property须为type 定义的pojo属性-->
<resultMap id="唯一的标识" type="映射的pojo对象">
<id column="表的主键字段,或者可以为查询语句中的别名字段" jdbcType="字段类型" property="映射pojo对象的主键属性" />
<result column="表的一个字段(可以为任意表的一个字段)" jdbcType="字段类型" property="映射到pojo对象的一个属性(须为type定义的pojo对象中的一个属性)"/>
<association property="pojo的一个对象属性" javaType="pojo关联的pojo对象">
<id column="关联pojo对象对应表的主键字段" jdbcType="字段类型" property="关联pojo对象的主席属性"/>
<result column="任意表的字段" jdbcType="字段类型" property="关联pojo对象的属性"/>
</association>
<!-- 集合中的property须为oftype定义的pojo对象的属性-->
<collection property="pojo的集合属性" ofType="集合中的pojo对象">
<id column="集合中pojo对象对应的表的主键字段" jdbcType="字段类型" property="集合中pojo对象的主键属性" />
<result column="可以为任意表的字段" jdbcType="字段类型" property="集合中的pojo对象的属性" />
</collection>
</resultMap>
如果collection标签是使用嵌套查询,格式如下:
<collection column="传递给嵌套查询语句的字段参数" property="pojo对象中集合属性" ofType="集合属性中的pojo对象" select="嵌套的查询语句" >
</collection>
一个商品的结果映射;
public class TShopSku {
/**
* 主键ID
*/
private Long id;
/**
* 商品名
*/
private String skuName;
/**
* 分类ID
*/
private Long categoryId;
/**
* 主键ID
* @return ID
*/
public Long getId() {
return id;
}
/**
* 主键ID,
* @param id
*/
public void setId(Long id) {
this.id = id;
}
/**
* 商品名
* @return SKU_NAME 商品名
*/
public String getSkuName() {
return skuName;
}
/**
* 商品名
* @param skuName 商品名
*/
public void setSkuName(String skuName) {
this.skuName = skuName == null ? null : skuName.trim();
}
/**
* 分类ID
* @return CATEGORY_ID 分类ID
*/
public Long getCategoryId() {
return categoryId;
}
/**
* 分类ID
* @param categoryId 分类ID
*/
public void setCategoryId(Long categoryId) {
this.categoryId = categoryId;
}
对应的resultMap:
<resultMap id="BaseResultMap" type="com.meikai.shop.entity.TShopSku">
<id column="ID" jdbcType="BIGINT" property="id" />
<result column="SKU_NAME" jdbcType="VARCHAR" property="skuName" />
<result column="CATEGORY_ID" jdbcType="BIGINT" property="categoryId" />
</resultMap>
商品pojo类添加属性集合:
/**
* 属性集合
*/
private List<TShopAttribute> attributes;
/**
* 获得属性集合
*/
public List<TShopAttribute> getAttributes() {
return attributes;
}
/**
* 设置属性集合
* @param attributes
*/
public void setAttributes(List<TShopAttribute> attributes) {
this.attributes = attributes;
}
将Collection标签添加到resultMap中,这里有两种方式:
1、嵌套结果:
对应的resultMap:
<resultMap id="BasePlusResultMap" type="com.meikai.shop.entity.TShopSku">
<id column="ID" jdbcType="BIGINT" property="id" />
<result column="SKU_NAME" jdbcType="VARCHAR" property="skuName" />
<result column="CATEGORY_ID" jdbcType="BIGINT" property="categoryId" />
<collection property="attributes" ofType="com.meikai.shop.entity.TShopAttribute" >
<id column="AttributeID" jdbcType="BIGINT" property="id" />
<result column="attribute_NAME" jdbcType="VARCHAR" property="attributeName" />
</collection>
</resultMap>
查询语句:
<select id="getById" resultMap="basePlusResultMap">
select s.ID,s.SKU_NAME,s.CATEGORY_ID,a.ID,a.ATTRIBUTE_NAME
from t_shop_sku s,t_shop_attribute a
where s.ID =a.SKU_ID and s.ID = #{id,jdbcType =BIGINT};
</select>
2、关联的嵌套查询(在collection中添加select属性):
商品结果集映射resultMap:
<resultMap id="BasePlusResultMap" type="com.meikai.shop.entity.TShopSku">
<id column="ID" jdbcType="BIGINT" property="id" />
<result column="SKU_NAME" jdbcType="VARCHAR" property="skuName" />
<result column="CATEGORY_ID" jdbcType="BIGINT" property="categoryId" />
<collection column="{skuId=ID}" property="attributes" ofType="com.meikai.shop.entity.TShopAttribute" select="getAttribute" >
</collection>
</resultMap>
collection的select会执行下面的查询属性语句:
<select id="getAttribute" resultMap="AttributeResultMap">
select a.ID,s.ATTRIBUTE_NAME
from t_shop_attribute a
where a.ID = #{skuId,jdbcType =BIGINT};
</select>
属性结果集映射:
<resultMap id="AttributeResultMap" type="com.meikai.shop.entity.TShopAttribute">
<id column="ID" jdbcType="BIGINT" property="id" />
<result column="ATTRIBUTE_NAME" jdbcType="VARCHAR" property="attributeName" />
</resultMap>
BasePlusResultMap包含了属性查询语句的Collection
所以通过下面的查询商品语句就可获得商品以及其包含的属性集合:
<select id="getById" resultMap="BasePlusResultMap">
select s.ID,s.SKU_NAME,s.CATEGORY_ID
from t_shop_sku s
where s.ID = #{id,jdbcType =BIGINT};
</select>
鉴别器:
<discriminator javaType="int" column="draft">
<case value="1" resultType="DraftPost"/>
</discriminator>
有时一个单独的数据库查询也许返回很多不同(但是希望有些关联)数据类型的结果集。
鉴别器元素就是被设计来处理这个情况的,还有包括类的继承层次结构。鉴别器非常容易理
解,因为它的表现很像Java语言中的switch语句。
<resultMap id="vehicleResult" type="Vehicle">
<id property=”id” column="id"/>
<result property="vin" column="vin"/>
<result property="year" column="year"/>
<result property="make" column="make"/>
<result property="model" column="model"/>
<result property="color" column="color"/>
<discriminator javaType="int" column="vehicle_type">
<case value="1" resultMap="carResult"/>
<case value="2" resultMap="truckResult"/>
<case value="3" resultMap="vanResult"/>
<case value="4" resultMap="suvResult"/>
</discriminator>
</resultMap>
在这个示例中,MyBatis会从结果集中得到每条记录,然后比较它的vehicle类型的值。
如果它匹配任何一个鉴别器的实例,那么就使用这个实例指定的结果映射。换句话说,这样
做完全是剩余的结果映射被忽略(除非它被扩展,这在第二个示例中讨论)。如果没有任何
一个实例相匹配,那么MyBatis仅仅使用鉴别器块外定义的结果映射。所以,如果carResult
按如下声明:
<resultMap id="carResult" type="Car">
<result property=”doorCount” column="door_count"/>
</resultMap>
那么只有doorCount属性会被加载。这步完成后完整地允许鉴别器实例的独立组,尽管
和父结果映射可能没有什么关系。这种情况下,我们当然知道cars和vehicles之间有关系,
如Car是一个Vehicle实例。因此,我们想要剩余的属性也被加载。我们设置的结果映射的
简单改变如下。
<resultMap id="carResult" type="Car" extends=”vehicleResult”>
<result property=”doorCount” column="door_count"/>
</resultMap>
现在vehicleResult和carResult的属性都会被加载了。
还有另外一种语法来做简洁的映射风格。比如:
<resultMap id="vehicleResult" type="Vehicle">
<id property=”id” column="id"/>
<result property="vin" column="vin"/>
<result property="year" column="year"/>
<result property="make" column="make"/>
<result property="model" column="model"/>
<result property="color" column="color"/>
<discriminator javaType="int" column="vehicle_type">
<case value="1" resultType="carResult">
<result property=”doorCount” column="door_count"/>
</case>
<case value="2" resultType="truckResult">
<result property=”boxSize” column="box_size"/>
<result property=”extendedCab” column="extended_cab"/>
</case>
<case value="3" resultType="vanResult">
<result property=”powerSlidingDoor”
column="power_sliding_door"/>
</case>
<case value="4" resultType="suvResult">
<result property=”allWheelDrive” column="all_wheel_drive"/>
</case>
</discriminator>
</resultMap>
缓存:
MyBatis包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制。MyBatis3
中的缓存实现的很多改进都已经实现了,使得它更加强大而且易于配置。
默认情况下是没有开启缓存的,除了局部的session缓存,可以增强变现而且处理循环
依赖也是必须的。要开启二级缓存,你需要在你的SQL映射文件中添加一行:
<cache/>