4, mybatis-XML映射器

MyBatis 的真正强大在于它的语句映射,这是它的魔力所在。由于它的异常强大,映射器的 XML 文件就显得相对简单。如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% 的代码。MyBatis 致力于减少使用成本,让用户能更专注于 SQL 代码。

SQL 映射文件只有很少的几个顶级元素(按照应被定义的顺序列出):

  • cache – 该命名空间的缓存配置。
  • cache-ref – 引用其它命名空间的缓存配置。
  • resultMap – 描述如何从数据库结果集中加载对象,是最复杂也是最强大的元素。
    - parameterMap – 老式风格的参数映射。此元素已被废弃,并可能在将来被移除!请使用行内参数映射。文档中不会介绍此元素。
  • sql – 可被其它语句引用的可重用语句块。
  • insert – 映射插入语句。
  • update – 映射更新语句。
  • delete – 映射删除语句。
  • select – 映射查询语句。

select

一个简单查询的 select 元素是非常简单的

<select id="selectPerson" parameterType="int" resultType="User">
  SELECT * FROM PERSON WHERE ID = #{id}
</select>

select的常用属性

属性 描述
id 在命名空间中唯一的标识符,可以被用来引用这条语句
parameterType 传入这条语句的参数的类全限定名或别名
resultType 期望从这条语句中返回结果的类全限定名或别名。resultType 和 resultMap 之间只能同时使用一个。
resultMap 对外部 resultMap 的命名引用。 resultType 和 resultMap 之间只能同时使用一个。

insert, update 和 delete

数据变更语句 insert,update 和 delete 的实现非常接近:

<insert
  id="insertAuthor"
  parameterType="domain.blog.Author">

<update
  id="updateAuthor"
  parameterType="domain.blog.Author"
  timeout="20">

<delete
  id="deleteAuthor"
  parameterType="domain.blog.Author"
  timeout="20">

多行插入

# UserMapper8.xml
<insert id="insertUsers" useGeneratedKeys="true" keyProperty="id" parameterType="list">
  		 insert into User (name, age, sex) values
		<foreach item="user" collection="list" separator=",">
    		(#{user.name}, #{user.age}, #{user.sex})
		</foreach>
	</insert>

sql片段

# UserMapper8.xml
<sql id="userColumns"> id, name, age,  sex </sql>
	

<select id="selectById" parameterType="java.lang.Integer" resultMap="user">
  select 
  <include refid="userColumns"/>
  from User where id = #{id, jdbcType=INTEGER} 
</select>	

结果映射

resultMap 和resultType

resultType

mybatis会将结果自动映射到类上, 无需太多的配置, 并且可以使用类型别名

# mybatis-config-08.xml
<typeAliases>
	<typeAlias type="top.itkaoti.example08.demo.User" alias="User"/>	
</typeAliases>

# UserMapper8.xml
<select id="selectById01" parameterType="java.lang.Integer" resultType="user">
	select 
	<include refid="userColumns"/>
  	from User where id = #{id, jdbcType=INTEGER} 
</select>

resultMap

使用resultMap可以解决数据库字段和javaBean属性不一致的问题,

<resultMap id="user" type="top.itkaoti.example08.demo.User">
	<id column="id" jdbcType="INTEGER" property="id" />
	<result column="name" jdbcType="VARCHAR" property="name" />
	<result column="age" jdbcType="INTEGER" property="age" />
	<result column="sex" jdbcType="INTEGER" property="sex" />
</resultMap>

  	
<select id="selectById" parameterType="java.lang.Integer" resultMap="user">
  	select 
	<include refid="userColumns"/>
  	from User where id = #{id, jdbcType=INTEGER} 
</select>

cache缓存

开启二级缓存

mybatis默认开启了一级缓存(即session级别的缓存), 要启用全局的二级缓存,只需要配置一下 SQL 映设文件

<cache
  eviction="FIFO"
  flushInterval="60000"
  size="512"
  readOnly="true"/>
参数 含义
eviction 清除策略, LRU , FIFO , SOFT , WEAK
flushInterval 缓存刷新时间,以毫秒为单位, 默认是不刷新
size 缓存最大数

使用自定义缓存

  1. 编写一个类, 实现org.apache.ibatis.cache.Cache接口, 且提供一个接受 String 参数作为 id 的构造器
public class MyCache implements Cache {

	private String id;
	private HashMap<Object, Object> cache = new HashMap<>();

	public MyCache(String id) {
		super();
		this.id = id;
	}

	@Override
	public String getId() {
		return this.id;
	}

	@Override
	public void putObject(Object key, Object value) {
		System.out.println("put cache");
		cache.put(key, value);
	}

	@Override
	public Object getObject(Object key) {
		System.out.println("get from cache");
		return cache.get(key);
	}

	@Override
	public Object removeObject(Object key) {
		return cache.remove(key);
	}

	@Override
	public void clear() {
		cache.clear();
	}

	@Override
	public int getSize() {
		return cache.size();
	}

}
  1. 映射xml文件中配置
<cache type="top.itkaoti.example08.demo.MyCache"></cache>

项目地址

mybatis官方文档