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 | 缓存最大数 |
使用自定义缓存
- 编写一个类, 实现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();
}
}
- 映射xml文件中配置
<cache type="top.itkaoti.example08.demo.MyCache"></cache>