4.MyBatis映射器语句

1.select元素

select – SELECT映射查询语句。

<select id="selectPerson" parameterType="int" resultType="hashmap">
  SELECT * FROM PERSON WHERE ID = #{id}
</select>
select元素的属性描述
id在命名空间中唯一的标识符,可以被用来引用这条语句。
parameterType将会传入这条语句的参数的Java类全限定名或别名。这个属性是可选的,因为 MyBatis 可以通过类型处理器(TypeHandler)推断出具体传入语句的参数,默认值为未设置(unset)。
resultType期望从这条语句中返回结果的Java类全限定名或别名。 注意,如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身的类型。 resultType 和 resultMap 之间只能同时使用一个。
resultMap对外部 resultMap 的命名引用。结果映射是 MyBatis 最强大的特性,如果你对其理解透彻,许多复杂的映射问题都能迎刃而解。 resultType 和 resultMap 之间只能同时使用一个。
flushCache将其设置为 true 后,只要语句被调用,都会导致本地缓存和二级缓存被清空,对于select元素来说,默认值为false。
useCache将其设置为 true 后,将会导致本条语句的结果被二级缓存缓存起来,对于select元素来说,默认值为true。
timeout这设置了驱动程序在抛出异常之前等待数据库从请求返回的秒数。默认值为未设置(unset)(取决于数据库驱动)。
fetchSize这是一个驱动程序提示,尝试让驱动程序每次批量返回的结果行数等于这个设置值。默认值为未设置(unset)(取决于数据库驱动)。
statementTypeSTATEMENT,PREPARED 或 CALLABLE中的任何一个,这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值为PREPARED。
resultSetTypeFORWARD_ONLY,SCROLL_SENSITIVE,SCROLL_INSENSITIVE 或 DEFAULT(等价于 unset) 中的一个,默认值为未设置(unset)(取决于数据库驱动)。
databaseId如果配置了数据库厂商标识(databaseIdProvider),MyBatis 会加载所有不带 databaseId 或匹配当前 databaseId 的语句;如果带和不带的语句都有,则不带的会被忽略。
resultOrdered这个设置仅针对嵌套结果 select 语句:如果为 true,则假定嵌套结果被包含或组合在一起,这样当返回新的主结果行时,将不再出现对先前结果行的引用。这允许填充嵌套结果对内存更加友好。默认值为false。
resultSets这个设置仅适用于多结果集(multiple resultsets)的情况。它将列出语句执行后返回的结果集并赋予每个结果集一个名称,多个名称之间以逗号分隔。

2.insert,update,delete元素

insert – INSERT映射插入语句。

update – UPDATE映射更新语句。

delete – DELETE映射删除语句。

<insert id="insertAuthor">
  insert into Author (id,username,password,email,bio)
  values (#{id},#{username},#{password},#{email},#{bio})
</insert>

<update id="updateAuthor">
  update Author set
    username = #{username},
    password = #{password},
    email = #{email},
    bio = #{bio}
  where id = #{id}
</update>

<delete id="deleteAuthor">
  delete from Author where id = #{id}
</delete>
insert, update, delete元素的属性描述
id在命名空间中唯一的标识符,可以被用来引用这条语句。
parameterType将会传入这条语句的参数的类全限定名或别名。这个属性是可选的,因为 MyBatis 可以通过类型处理器(TypeHandler)推断出具体传入语句的参数,默认值为未设置(unset)。
flushCache将其设置为 true 后,只要语句被调用,都会导致本地缓存和二级缓存被清空,对于insert,update,delete元素来说,默认值为true。
timeout这设置了驱动程序在抛出异常之前等待数据库从请求返回的最大秒数。
默认值为未设置(unset)(取决于数据库驱动)。
statementTypeSTATEMENT,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 的语句;如果带和不带的语句都有,则不带的会被忽略。

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

4.cache元素

4.1缓存

cache – 该命名空间的缓存配置。

默认情况下,只启用了本地的会话缓存,它仅仅对一个会话中的数据进行缓存。 要启用全局的二级缓存,只需要在你的 SQL 映射文件中添加一行:

<cache/>

这个简单语句的效果如下:

  • 映射语句文件中的所有 select 语句的结果将会被缓存。
  • 映射语句文件中的所有 insert、update 和 delete 语句会刷新缓存。
  • 缓存会使用最近最少使用算法(LRU, Least Recently Used)算法来清除不需要的缓存。
  • 缓存不会定时进行刷新(也就是说,没有刷新间隔)。
  • 缓存会保存列表或对象(无论查询方法返回哪种)的 1024 个引用。
  • 缓存会被视为读/写缓存,这意味着获取到的对象并不是共享的,可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。

缓存只作用于 <cache> 标签所在的映射语句文件中的语句。如果你混合使用 Java API 和 XML 映射文件,在共用接口中的语句将不会被默认缓存。你需要使用 @CacheNamespaceRef 注解指定缓存作用域。

<cache
  eviction="FIFO"
  flushInterval="60000"
  size="512"
  readOnly="true"/>
cache元素的属性描述
eviction默认的清除策略是 LRU
flushInterval可以被设置为任意的正整数,设置的值应该是一个以毫秒为单位的合理时间量。 默认情况是不设置,也就是没有刷新间隔,缓存仅仅会在调用语句时刷新。
size属性可以被设置为任意正整数,要注意欲缓存对象的大小和运行环境中可用的内存资源。默认值是 1024。
readOnly可以被设置为 true 或 false。只读的缓存会给所有调用者返回缓存对象的相同实例。 因此这些对象不能被修改。这就提供了可观的性能提升。而可读写的缓存会(通过序列化)返回缓存对象的拷贝。 速度上会慢一些,但是更安全,因此默认值是 false。
cache元素的eviction属性描述
LRU最近最少使用:移除最长时间不被使用的对象。
FIFO先进先出:按对象进入缓存的顺序来移除它们。
SOFT软引用:基于垃圾回收器状态和软引用规则移除对象。
WEAK弱引用:更积极地基于垃圾收集器状态和弱引用规则移除对象。

二级缓存是事务性的。这意味着,当 SqlSession 提交完成时,或是 回滚完成时但没有执行 flushCache=trueinsert/delete/update 语句时,缓存会获得更新。

4.2自定义缓存

除了上述自定义缓存的方式,你也可以通过实现你自己的缓存,或为其他第三方缓存方案创建适配器,来完全覆盖缓存行为。

<cache type="com.domain.something.MyCustomCache"/>

type 属性指定的类必须实现 org.apache.ibatis.cache.Cache 接口,且提供一个接受 String id 作为参数的构造器。 

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();
}

为了对你的缓存进行配置,只需要简单地在你的缓存实现中添加公有的 JavaBean 属性,然后通过 cache 元素传递属性值。

<cache type="com.domain.something.MyCustomCache">
  <property name="cacheFile" value="/tmp/my-custom-cache.tmp"/>
</cache>

4.3cache-ref

cache-ref – 引用其它命名空间的缓存配置。

<cache-ref namespace="com.someone.application.data.SomeMapper"/>

5.参数

5.1参数语法

默认情况下,使用 #{} 参数语法时,MyBatis 会创建 PreparedStatement 参数占位符,并通过占位符安全地设置参数(就像使用 ? 一样)。

不过有时你就是想直接在 SQL 语句中直接插入一个未修改的字符串。比如,ORDER BY 子句,这时候你可以:

ORDER BY ${columnName}

5.2参数类型

当参数是原始或简单数据类型时,比如 IntegerString没有相关属性,因此将完全替换参数的完整值。

<select id="selectUsers" resultType="User">
  select id, username, password
  from users
  where id = #{id}
</select>

当参数是一个复杂的对象时,比如 User 有相关属性,会查找 idusernamepassword 属性,然后将它们的值传入预处理语句的参数中。

<insert id="insertUser" parameterType="User">
  insert into users (id, username, password)
  values (#{id}, #{username}, #{password})
</insert>

参数也可以指定一个特殊的数据类型。

#{age,javaType=int,jdbcType=NUMERIC,typeHandler=MyTypeHandler}
#{height,javaType=double,jdbcType=NUMERIC,numericScale=2}

javaType:几乎总是可以根据参数对象的类型使用类型处理器(TypeHandler)确定 javaType。除非该对象是一个 HashMap,这个时候,你需要显式指定 javaType 来确保正确的类型处理器(TypeHandler)被使用。

jdbcType:如果null作为值传递给nullable的列时,这个时候,必须使用jdbcType

要更进一步地自定义类型处理方式,可以指定一个特殊的类型处理器类(或别名),比如:

#{age,javaType=int,jdbcType=NUMERIC,typeHandler=MyTypeHandler}

5.3IN,OUT,INOUT参数

mode 属性允许你指定 INOUT 或 INOUT 参数。

#{department, mode=OUT, jdbcType=CURSOR, javaType=ResultSet, resultMap=departmentResultMap}

如果 mode 为 OUT(或 INOUT),而且 jdbcType 为 CURSOR(也就是 Oracle 的 REFCURSOR),你必须指定一个 resultMap 引用来将结果集 ResultSet 映射到参数的类型上。要注意这里的 javaType 属性是可选的,如果留空并且 jdbcType 是 CURSOR,它会被自动地设置为 ResultSet

#{department, mode=OUT, jdbcType=CURSOR, javaType=ResultSet, resultMap=departmentResultMap}

原创文章,作者:huoxiaoqiang,如若转载,请注明出处:https://www.huoxiaoqiang.com/java/mybatis/17111.html

(0)
上一篇 2022年9月4日 20:39
下一篇 2022年9月5日 15:17

相关推荐

  • 5.MyBatis映射器结果映射

    1.映射工作原理 上述语句只是简单地将所有的列映射到 HashMap 的键上,但是 HashMap 并不是一个很好的领域模型。 而我们的程序更可能会使用 JavaBean 或 POJO(Plain Old Java Objects,普通老式 Java 对象)作为领域模型。MyBatis 对两者都提供了支持。无论是自动映…

    MyBatis教程 2022年9月5日
    0180
  • 3.MyBatis-Spring配置

    1.MySQL数据库配置 需提前手动创建好数据库。 2.MyBatis配置 MyBatis 配置参数存储在Spring Boot应用的application.properties文件中。 配置 描述 mybatis.config-location MyBatis xml 配置文件的位置。 mybatis.check-c…

    MyBatis教程 2022年9月3日
    0470
  • 2.MyBatis配置

    1.configuration(配置)结构 configuration(配置) properties(属性) settings(设置) typeAliases(类型别名) typeHandlers(类型处理器) objectFactory(对象工厂) plugins(插件) environments(环境配置) env…

    MyBatis教程 2022年9月2日
    0390

发表回复

登录后才能评论