MyBatis中XML映射⽂件中常见的标签说明
SQL 映射⽂件只有很少的⼏个顶级元素(按照应被定义的顺序列出):
cache – 对给定命名空间的缓存配置。
cache-ref – 对其他命名空间缓存配置的引⽤。
resultMap – 是最复杂也是最强⼤的元素,⽤来描述如何从数据库结果集中来加载对象。
parameterMap – 已被废弃!⽼式风格的参数映射。更好的办法是使⽤内联参数,此元素可能在将来被移除。
sql – 可被其他语句引⽤的可重⽤语句块。
insert – 映射插⼊语句
update – 映射更新语句
delete – 映射删除语句
select – 映射查询语句
select
<select id="selectPerson" parameterType="int" resultType="hashmap">
SELECT * FROM PERSON WHERE ID = #{id}
</select>
这个语句被称作 selectPerson,接受⼀个 int(或 Integer)类型的参数,并返回⼀个 HashMap 类型的对象,其中的键是列名,值便是结果⾏中的对应值。
注意参数符号:#{id}
这就告诉 MyBatis 创建⼀个预处理语句(PreparedStatement)参数,在 JDBC 中,这样的⼀个参数在 SQL 中会由⼀个“?”来标识,并被传递到⼀个新的预处理语句中,就像这样:
// 近似的 JDBC 代码,⾮ MyBatis 代码...
String selectPerson = "SELECT * FROM PERSON WHERE ID=?";
PreparedStatement ps = conn.prepareStatement(selectPerson);
ps.setInt(1,id);
<select
id="selectPerson"
parameterType="int"
parameterMap="deprecated"
resultType="hashmap"
resultMap="personResultMap"
flushCache="false"
useCache="true"
timeout="10"
fetchSize="256"
statementType="PREPARED"
resultSetType="FORWARD_ONLY">
属性描述
id在命名空间中唯⼀的标识符,可以被⽤来引⽤这条语句。
parameterType将会传⼊这条语句的参数类的完全限定名或别名。这个属性是可选的,因为 MyBatis 可以通过类型处理器(TypeHandler)推断出具体传⼊语句的参数,默认值为未设置(unset)。
parameterMap这是引⽤外部 parameterMap 的已经被废弃的⽅法。请使⽤内联参数映射和 parameterType 属性。
resultType从这条语句中返回的期望类型的类的完全限定名或别名。注意如果返回的是集合,那应该设置为集合包含的类型,⽽不是集合本⾝。可以使⽤ resultType 或 resultMap,但不能同时使⽤。
resultMap外部 resultMap 的命名引⽤。结果集的映射是 MyBatis 最强⼤的特性,如果你对其理解透彻,许多复杂映射的情形都能迎刃⽽解。可以使⽤ resultMap 或 resultType,但不能同时使⽤。
flushCache将其设置为 true 后,只要语句被调⽤,都会导致本地缓存和⼆级缓存被清空,默认值:false。useCache将其设置为 true 后,将会导致本条语句的结果被⼆级缓存缓存起来,默认值:对 select 元素为 true。
timeout这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为未设置(unset)(依赖驱动)。
fetchSize这是⼀个给驱动的提⽰,尝试让驱动程序每次批量返回的结果⾏数和这个设置值相等。默认值为未设置(unset)(依赖驱动)。
statementType STATEMENT,PREPARED 或 CALLABLE 中的⼀个。这会让 MyBatis 分别使⽤
Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED。
FORWARD_ONLY,SCROLL_SENSITIVE, SCROLL_INSENSITIVE 或 DEFAULT(等价于 unset)中的
resultSetType⼀个,默认值为 unset (依赖驱动)。
databaseId如果配置了数据库⼚商标识(databaseIdProvider),MyBatis 会加载所有的不带 databaseId 或匹配当前databaseId 的语句;如果带或者不带的语句都有,则不带的会被忽略。
resultOrdered 这个设置仅针对嵌套结果 select 语句适⽤:如果为 true,就是假设包含了嵌套结果集或是分组,这样的话当返回⼀个主结果⾏的时候,就不会发⽣有对前⾯结果集的引⽤的情况。这就使得在获取嵌套的结果集的时候不⾄于导致内存不够⽤。默认值:false。
resultSets这个设置仅对多结果集的情况适⽤。它将列出语句执⾏后返回的结果集并给每个结果集⼀个名称,名称是逗号分隔的。
属性描述
insert, update 和 delete
数据变更语句 insert,update 和 delete 的实现⾮常接近:
<insert
id="insertAuthor"
parameterType="domain.blog.Author"
flushCache="true"
statementType="PREPARED"
keyProperty=""
keyColumn=""
useGeneratedKeys=""
timeout="20">
<update
id="updateAuthor"
parameterType="domain.blog.Author"
flushCache="true"
statementType="PREPARED"
timeout="20">
<delete
id="deleteAuthor"
parameterType="domain.blog.Author"
flushCache="true"
statementType="PREPARED"
timeout="20">
属性描述
id命名空间中的唯⼀标识符,可被⽤来代表这条语句。
parameterType将要传⼊语句的参数的完全限定类名或别名。这个属性是可选的,因为 MyBatis 可以通过类型处理器推断出具体传⼊语句的参数,默认值为未设置(unset)。
parameterMap这是引⽤外部 parameterMap 的已经被废弃的⽅法。请使⽤内联参数映射和 parameterType 属性。
flushCache将其设置为 true 后,只要语句被调⽤,都会导致本地缓存和⼆级缓存被清空,默认值:true(对于insert、update 和 delete 语句)。
timeout这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为未设置(unset)(依赖驱动)。
statementType STATEMENT,PREPARED 或 CALLABLE 的⼀个。这会让 MyBatis 分别使⽤Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED。
useGeneratedKeys (仅对 insert 和 update 有⽤)这会令 MyBatis 使⽤ JDBC 的 getGeneratedKeys ⽅法来取出由数据库内部⽣成的主键(⽐如:像 MySQL 和 SQL Server 这样的关系数据库管理系统的⾃动递增字段),默认值:false。
keyProperty (仅对 insert 和 update 有⽤)唯⼀标记⼀个属性,MyBatis 会通过 getGeneratedKeys 的返回值或者通过 insert 语句的 selectKey ⼦元素设置它的键值,默认值:未设置(unset)。如果希望得到多个⽣成的列,也可以是逗号分隔的属性名称列表。
keyColumn (仅对 insert 和 update 有⽤)通过⽣成的键值设置表中的列名,这个设置仅在某些数据库(像PostgreSQL)是必须的,当主键列不是表中的第⼀列的时候需要设置。如果希望使⽤多个⽣成的列,也可以设置为逗号分隔的属性名称列表。
databaseId如果配置了数据库⼚商标识(databaseIdProvider),MyBatis 会加载所有的不带 databaseId 或匹配当前 databaseId 的语句;如果带或者不带的语句都有,则不带的会被忽略。
⽣成主键
<selectKey
keyProperty="id"
resultType="int"
order="BEFORE"
statementType="PREPARED">
属性描述
keyProperty selectKey 语句结果应该被设置的⽬标属性。如果希望得到多个⽣成的列,也可以是逗号分隔的属性名称列表。
keyColumn匹配属性的返回结果集中的列名称。如果希望得到多个⽣成的列,也可以是逗号分隔的属
性名称列表。
resultType 结果的类型。MyBatis 通常可以推断出来,但是为了更加精确,写上也不会有什么问题。MyBatis 允许将任何简单类型⽤作主键的类型,包括字符串。如果希望作⽤于多个⽣成的列,则可以使⽤⼀个包含期望属性的Object 或⼀个 Map。
order 这可以被设置为 BEFORE 或 AFTER。如果设置为 BEFORE,那么它会⾸先⽣成主键,设置 keyProperty 然后执⾏插⼊语句。如果设置为 AFTER,那么先执⾏插⼊语句,然后是 selectKey 中的语句 - 这和 Oracle 数据库的⾏为相似,在插⼊语句内部可能有嵌⼊索引调⽤。
statementType与前⾯相同,MyBatis ⽀持 STATEMENT,PREPARED 和 CALLABLE 语句的映射类型,分别代表PreparedStatement 和 CallableStatement 类型。
<selectKey resultType="java.lang.Long" order="AFTER" keyProperty="id">
SELECT LAST_INSERT_ID() AS id
</selectKey>
sql
这个元素可以被⽤来定义可重⽤的 SQL 代码段,这些 SQL 代码可以被包含在其他语句中。它可以(在加载的时候)被静态地设置参数。在不同的包含语句中可以设置不同的值到参数占位符上。⽐如:
<sql id="userColumns"> ${alias}.id,${alias}.username,${alias}.password </sql>
<select id="selectUsers" resultType="map">
select
<include refid="userColumns"><property name="alias" value="t1"/></include>,
<include refid="userColumns"><property name="alias" value="t2"/></include>
from some_table t1
cross join some_table t2
</select>
结果映射
resultMap 元素是 MyBatis 中最重要最强⼤的元素,在⼀些情形下允许你进⾏⼀些 JDBC 不⽀持的操作。实际上,在为⼀些⽐如连接的复杂语句编写映射代码的时候,⼀份 resultMap 能够代替实现同等功能的长达数千⾏的代码。ResultMap 的设计思想是,对于简单的语句根本不需要配置显式的结果映射,⽽对于复杂⼀点的语句只需要描述它们的关系就⾏了。
在JavaBean中定义⼀个有 3 个属性:id,username 和 hashedPassword的类,然后在l中,这些属性会对应到select 语句中的列名,这样的⼀个 JavaBean 可以被映射到 ResultSet,就像映射到 HashMap ⼀样简单。
<select id="selectUsers" resultType="del.User">
select id, username, hashedPassword
from some_table
where id = #{id}
</select>
像第三中的第三个例⼦,也可以定义外部resultMap,这也是解决列名不匹配的另外⼀种⽅式。
<resultMap id="userResultMap" type="User">
<id property="id" column="user_id" />
<result property="username" column="user_name"/>
<result property="password" column="hashed_password"/>
</resultMap>
<select id="selectUsers" resultMap="userResultMap">
select user_id, user_name, hashed_password
from some_table
where id = #{id}
</select>
结果映射(resultMap)
constructor-⽤于在实例化类时,注⼊结果到构造⽅法中
idArg - ID 参数;标记出作为 ID 的结果可以帮助提⾼整体性能
arg - 将被注⼊到构造⽅法的⼀个普通结果
id – ⼀个 ID 结果;标记出作为 ID 的结果可以帮助提⾼整体性能
result – 注⼊到字段或 JavaBean 属性的普通结果
association– ⼀个复杂类型的关联;许多结果将包装成这种类型
嵌套结果映射 – 关联本⾝可以是⼀个 resultMap 元素,或者从别处引⽤⼀个
collection– ⼀个复杂类型的集合
嵌套结果映射 – 集合本⾝可以是⼀个 resultMap 元素,或者从别处引⽤⼀个
discriminator– 使⽤结果值来决定使⽤哪个resultMap
case– 基于某些值的结果映射
嵌套结果映射 – case 本⾝可以是⼀个 resultMap 元素,因此可以具有相同的结构和元素,或者从别处引⽤⼀个。
属性描述
id当前命名空间中的⼀个唯⼀标识,⽤于标识⼀个结果映射。
type类的完全限定名, 或者⼀个类型别名(关于内置的类型别名,可以参考上⾯的表格)。
autoMapping如果设置这个属性,MyBatis将会为本结果映射开启或者关闭⾃动映射。这个属性会覆盖全局的属性autoMappingBehavior。默认值:未设置(unset)。
id & result
<id property="id" column="post_id"/>
<result property="subject" column="post_subject"/>
这些是结果映射最基本的内容。id 和 result 元素都将⼀个列的值映射到⼀个简单数据类型(String, int, double, Date 等)的属性或字段。
这两者之间的唯⼀不同是,id 元素表⽰的结果将是对象的标识属性,这会在⽐较对象实例时⽤到。这样可以提⾼整体的性能,尤其是进⾏缓存和嵌套结果映射(也就是连接映射)的时候。
属性描述
xml标签大全property 映射到列结果的字段或属性。如果⽤来匹配的 JavaBean 存在给定名字的属性,那么它将会被使⽤。否则MyBatis 将会寻给定名称的字段。⽆论是哪⼀种情形,你都可以使⽤通常的点式分隔形式进⾏复杂属性导航。⽐如,你可以这样映射⼀些简单的东西:“username”,或者映射到⼀些复杂的东西
上:“address.street.number”。
column数据库中的列名,或者是列的别名。⼀般情况下,这和传递给 String(columnName) ⽅法的参数⼀样。
javaType ⼀个 Java 类的完全限定名,或⼀个类型别名(关于内置的类型别名,可以参考上⾯的表格)。如果你映射到⼀个 JavaBean,MyBatis 通常可以推断类型。然⽽,如果你映射到的是 HashMap,那么你应该明确地指定javaType 来保证⾏为与期望的相⼀致。
jdbcType JDBC 类型,所⽀持的 JDBC 类型参见这个表格之后的“⽀持的 JDBC 类型”。只需要在可能
执⾏插⼊、更新和删除的且允许空值的列上指定 JDBC 类型。这是 JDBC 的要求⽽⾮ MyBatis 的要求。如果你直接⾯向 JDBC 编程,你需要对可能存在空值的列指定这个类型。
typeHandler我们在前⾯讨论过默认的类型处理器。使⽤这个属性,你可以覆盖默认的类型处理器。这个属性值是⼀个类型处理器实现类的完全限定名,或者是类型别名。
缓存
默认情况下,只启⽤了本地的会话缓存,它仅仅对⼀个会话中的数据进⾏缓存。要启⽤全局的⼆级缓存,只需要在你的 SQL 映射⽂件中添加⼀⾏:<cache/>
基本上就是这样。这个简单语句的效果如下:
映射语句⽂件中的所有 select 语句的结果将会被缓存。
映射语句⽂件中的所有 insert、update 和 delete 语句会刷新缓存。
缓存会使⽤最近最少使⽤算法(LRU, Least Recently Used)算法来清除不需要的缓存。
缓存不会定时进⾏刷新(也就是说,没有刷新间隔)。
缓存会保存列表或对象(⽆论查询⽅法返回哪种)的 1024 个引⽤。
缓存会被视为读/写缓存,这意味着获取到的对象并不是共享的,可以安全地被调⽤者修改,⽽不⼲扰其他调⽤者或线程所做的潜在修改。
提⽰缓存只作⽤于 cache 标签所在的映射⽂件中的语句。如果你混合使⽤ Java API 和 XML 映射⽂件,在共⽤接⼝中的语句将不会被默认缓存。你需要使⽤ @CacheNamespaceRef 注解指定缓存作⽤域。
这些属性可以通过 cache 元素的属性来修改。⽐如:
<cache
eviction="FIFO"
flushInterval="60000"
size="512"
readOnly="true"/>
这个更⾼级的配置创建了⼀个 FIFO 缓存,每隔 60 秒刷新,最多可以存储结果对象或列表的 512 个引⽤,⽽且返回的对象被认为是只读的,因此对它们进⾏修改可能会在不同线程中的调⽤者产⽣冲突。
可⽤的清除策略有:
LRU – 最近最少使⽤:移除最长时间不被使⽤的对象。
FIFO – 先进先出:按对象进⼊缓存的顺序来移除它们。
SOFT – 软引⽤:基于垃圾回收器状态和软引⽤规则移除对象。
WEAK – 弱引⽤:更积极地基于垃圾收集器状态和弱引⽤规则移除对象。
默认的清除策略是 LRU。
flushInterval(刷新间隔)属性可以被设置为任意的正整数,设置的值应该是⼀个以毫秒为单位的合理时间量。默认情况是不设置,也就是没有刷新间隔,缓存仅仅会在调⽤语句时刷新。
size(引⽤数⽬)属性可以被设置为任意正整数,要注意欲缓存对象的⼤⼩和运⾏环境中可⽤的内存
资源。默认值是 1024。readOnly(只读)属性可以被设置为 true 或 false。只读的缓存会给所有调⽤者返回缓存对象的相同实例。因此这些对象不能被修改。这就提供了可观的性能提升。⽽可读写的缓存会(通过序列化)返回缓存对象的拷贝。速度上会慢⼀些,但是更安全,因此默认值是 false。
提⽰⼆级缓存是事务性的。这意味着,当 SqlSession 完成并提交时,或是完成并回滚,但没有执⾏ flushCache=true 的insert/delete/update 语句时,缓存会获得更新。
使⽤⾃定义缓存
除了上述⾃定义缓存的⽅式,你也可以通过实现你⾃⼰的缓存,或为其他第三⽅缓存⽅案创建适配器,来完全覆盖缓存⾏为。
<cache type="com.domain.something.MyCustomCache"/>
例⼦:
type 属性指定的类必须实现 batis.cache.Cache 接⼝,且提供⼀个接受 String 参数作为 id 的构造器。这个接⼝是MyBatis 框架中许多复杂的接⼝之⼀,但是⾏为却⾮常简单。
public interface Cache {
String getId();
int getSize();
void putObject(Object key, Object value);
Object getObject(Object key);
boolean hasKey(Object key);
Object removeObject(Object key);
void clear();
}
动态SQL
Mybatis 动态 SQL ,可以让我们在 XML 映射⽂件内,以 XML 标签的形式编写动态 SQL ,完成逻辑判断和动态拼接SQL 的功能。
Mybatis 提供了 9 种动态 SQL 标签:<if />、<choose />、<when />、<otherwise />、<trim />、<where />、<set />、<foreach />、<bind /> 。
其执⾏原理为,使⽤ OGNL 的表达式,从 SQL 参数对象中计算表达式的值,根据表达式的值动态拼接 SQL ,以此来完成动态 SQL 的功能。
if
动态 SQL 通常要做的事情是根据条件包含 where ⼦句的⼀部分。⽐如:
<select id="findActiveBlogWithTitleLike"
resultType="Blog">
SELECT * FROM BLOG
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论