新增、更新数据不刷新缓存
缓存在新增、更新数据时会自动失效,对于部分影响不大的操作可以设置不刷新缓存,方法是在语句xml中设置flushCache=false。
1
| <update id="demo" flushCache="flase"></update>
|
模糊查询
MySQL模糊查询一把条件是使用like条件,经常使用传入的变量作为like条件。在MyBatis里面,like使用变量需要用到${}或者concat。建议使用concat,#{}可以防止SQL注入。
1
2
| like '%${value}%'
like concat('%',#{value},'%')
|
使用缓存
使用缓存能够极大提升应用的性能。二级缓存的开启方式是
1
| <cache flushInterval="60000"></cache>
|
自动创建表
不建议在MyBatis里面建表,原则上数据表要由数据库管理员创建。但是对于一些小应用,可能开发者集多个角色于一身,自动创建表反而利大于弊。如下的语句在<select>标签内使用了CREATE TABLE IF NOT EXISTS语法,可以在无表时自动创建表,有表时会跳过执行。
1
2
3
4
5
6
| <select id="createTable">
CREATE TABLE IF NOT EXISTS `demo` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`path` varchar(128) NOT NULL COMMENT '路径',
) ENGINE=MyISM DEFAULT CHARSET=utf8;
</select>
|
设置SQL超时时间
通过timeout属性可以设置超时时间,也就是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数
1
| <update id="demo" timeout="100"></update>
|
获取生成的自增长id
使用自增id有很多好处,可以通过配置selectKey实现insert执行后返回生成的自增id,以用于后续流程
1
2
3
4
5
6
| <insert id="insert" parameterType="demo">
<selectKey keyProperty="id" order"AFTER" resultType="Java.lang.Long">
SELECT LAST_INSERT_ID()
</selectKey>
insert into `demo`(demo) values(#{demo})
</insert>
|
匹配多个值
使用forEach构建查询条件集合,where语句使用in即可实现匹配做个值。
1
2
3
4
5
6
7
| <select id="querybyId" resultType="BaseResultMap">
select * from entity
where id in
<forEach collection="userids" item="userid" index="index" open="(" seperator="," close=")">
#{userid}
</forEach>
</select>
|
只更新部分字段
使用<if><set>标签配合,可以实现只更新部分数据。一般是传入null不更新,非null则更新。
<if>标签支持test配置一个表达式,表达式返回true时<if>内部的SQL片段会生效,否则不会生效。<set>标签能够自动生成set片段,并处理去除首尾多余的字符。
1
2
3
4
5
6
7
8
9
10
11
12
| <update id="updateById" parameterType="UserDO">
update `user`
<set>
<if test="nick != null">
nick = #{nick},
</if>
<if test="avatar != null">
avatar = #{avatar},
</if>
</set>
where userId = #{userId}
</update>
|
动态查询条件
使用<if><where>标签配合,可以实现动态查询条件。<if>标签能够实现条件判断。<where>标签能够自动组装where片段,去除首尾的非法字符。
1
2
3
4
5
6
7
8
9
10
11
| <select id="select" resultType="resultMap">
SELECT * FROM demo
<where>
<if test="userId != null">
userId = #{userId}
</if>
<if test="nick != null">
and nick= #{nick}
</if>
</where>
</select>
|
批量插入数据
批量插入数据能够极大提升性能,曾经测试过多条数据插入时间从分钟级降到秒级完成。批量插入主要用到forEach标签,把批量数据转换成values语句。
forEach标签的属性主要有item,index,collection,open,separator,close。
item:集合中元素迭代时的别名;
index:集合中元素迭代时的索引;
open:常用于where语句中,表示以什么开始,比如以’(‘开始;
close:常用于where语句中,表示以什么结束;
collection:集合值;
1
2
3
4
5
6
7
| <insert id="batchInsert" parameterType="java.util.List">
insert into `demo`(userId, `url`)
values
<foreach collection="list" item="item" separator=",">
(#{item.userId}, #{item.url})
</foreach>
</insert>
|
条件语句
java可以很方便地使用if或switch实现分支功能。MyBatis的choose标签可以实现条件分支。如下的配置中,传入id时使用id,不传则使用其它条件。
choose标签是按顺序判断其内部when标签中的test条件是否成立,如果有一个成立,则choose结束。当choose中所有when的条件都不满足,则执行otherwise中的sql。类似Java的switch语句,choose为switch,when为case,otherwise则为default。
1
2
3
4
5
6
7
8
9
10
11
12
13
| <update id="update" parameterType="Config">
update `config` set `content` = #{content}
<where>
<choose>
<when test="id != null">
id = #{id}
</when>
<otherwise>
appName = #{appName} and t = #{t} and x = #{x}
</otherwise>
</choose>
</where>
</update>
|
复用SQL片段
用sql标签可以定义SQL片段,用于SQL语句复用。
1
2
3
4
5
6
7
8
9
| <sql id="Base_Column_List">
userid, email
</sql>
<select id="selectById" parameter="java.lang.Long" resultMap="ResultMap">
select
<include refid="Base_Column_List" />
from `user`
where userId = #{userId}
</select>
|