【mybatis】基础学习记录

代码地址,学习简化省略 service 层:https://github.com/rocyuan666/learn-mybatis

mapper 接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package top.rocyuan.mapper;

import org.apache.ibatis.annotations.*;
import top.rocyuan.entity.User;

import java.util.ArrayList;
import java.util.Map;

@Mapper
public interface UserMapper {

/**
* 查询所有列表,无查询条件
*/
ArrayList<User> selectAll();

/**
* 查询详情
*/
User selectById(int id);

/**
* 查询详情(注解方式)
* 注解方式不常用!!!
* 分为:
* @Select("sql")
* @Insert("sql")
* @Delete("sql")
* @Update("sql")
*
*/
@Select("select id, user_name as userName, password, nick_name as nickName, avatar, sex, age, add_time as addTime, update_time as updateTime from roc_user where id = #{id}")
User selectByIdAnnotation(int id);

/**
* 查询列表 多条件查询
* 1. 散装参数 @Param 方式
* 2. User 对象方式
* 3. Map 方式
*/
// 1. 散装参数 @Param(field) 方式; field 需要与 xml 中 #{field} field 相同
// ArrayList<User> selectByCondition(@Param("age") Integer age, @Param("sex") Integer sex, @Param("nickName") String nickName);
// 2. User 实体类方式; 实体类属性 需要与 xml 中 #{field} field 相同
// ArrayList<User> selectByCondition(User user);
// 3. Map 方式; Map 中 key 需要与 xml 中 #{field} field 相同
ArrayList<User> selectByCondition(Map<String, Object> map);

/**
* 查询列表 单条件查询
*/
ArrayList<User> selectByConditionSingle(User user);

/**
* 添加
*/
void add(User user);

/**
* 修改
*/
void update(User user);

/**
* 删除
*/
void deleteById(int id);

/**
* 批量删除
* 不加 @Param xml 内部 会默认为: array 属性
*/
void deleteByIds(@Param("ids") int[] ids);
}

mapper XML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="top.rocyuan.mapper.UserMapper">

<!-- 映射 -->
<resultMap id="userResultMap" type="User">
<id column="id" property="id"/>
<result column="user_name" property="userName"/>
<result column="nick_name" property="nickName"/>
<result column="add_time" property="addTime"/>
<result column="update_time" property="updateTime"/>
<!-- 字段 与 属性值 一样的可以不写 -->
<!-- <result column="sex" property="sex"/> -->
<!-- <result column="age" property="age"/> -->
<!-- <result column="password" property="password"/> -->
<!-- <result column="avatar" property="avatar"/> -->
</resultMap>

<!-- sql 片段 配合 include 使用 -->
<sql id="userColum">
id
, user_name, password, nick_name, sex, age, avatar, add_time, update_time
</sql>

<!--
======================== 查询所有数据 ============================
-->
<!-- 使用了 resultMap 不需要指定 resultType="User" -->
<select id="selectAll" resultMap="userResultMap">
select
<include refid="userColum"/>
from roc_user;
</select>

<!--
======================== 查询详情 ============================
-->
<!-- 查询详情(单条件查询) parameterType="int" 可省略 -->
<select id="selectById" resultMap="userResultMap">
select
<include refid="userColum"/>
from roc_user where id = #{id};
</select>

<!--
特殊字符处理:
1. 转义字符 如:&lt; == <
2. CDATA区
-->
<!-- <select id="selectById" resultMap="userResultMap"> -->
<!-- select -->
<!-- <include refid="userColum"/> -->
<!-- from roc_user where id -->
<!-- <![CDATA[ -->
<!-- < -->
<!-- ]]> -->
<!-- #{id}; -->
<!-- </select> -->

<!--
======================== 多条件查询(存在BUG:必须要传递指定的参数) ============================
Mapper 接口传参方式不同,分为:
1. 散装参数 @Param 方式
2. User 实体类方式
3. Map 方式
-->
<!-- <select id="selectByCondition" resultMap="userResultMap"> -->
<!-- select -->
<!-- <include refid="userColum"/> -->
<!-- from roc_user -->
<!-- where age > #{age} -->
<!-- and sex = #{sex} -->
<!-- and nick_name like #{nickName}; -->
<!-- </select> -->

<!--
======================== 多条件动态查询(解决上方BUG) ============================
动态 sql 文档:https://mybatis.org/mybatis-3/zh_CN/dynamic-sql.html
Mapper 接口传参方式使用:2、3
if 标签; where 标签 动态处理 sql where 关键字后 and/or 等语法问题
-->
<select id="selectByCondition" resultMap="userResultMap">
select
<include refid="userColum"/>
from roc_user
<where>
<if test="age != null">
and age > #{age}
</if>
<if test="sex != null">
and sex = #{sex}
</if>
<if test="nickName != null and nickName != ''">
and nick_name like #{nickName}
</if>
</where>
</select>

<!--
======================== 单条件动态查询(指定字段的内容查询) ============================
动态 sql 文档:https://mybatis.org/mybatis-3/zh_CN/dynamic-sql.html
choose、when, otherwise 标签; where 标签 动态处理 sql where 关键字后 and/or 等语法问题
类似
switch、case、default 语句
-->
<select id="selectByConditionSingle" resultMap="userResultMap">
select
<include refid="userColum"/>
from roc_user
<where>
<choose>
<when test="age != null">
age > #{age}
</when>
<when test="sex != null">
sex = #{sex}
</when>
<when test="nickName != null and nickName != ''">
nick_name like #{nickName}
</when>
</choose>
</where>
</select>


<!--
======================== 添加 ============================
添加完返回该条数据的 id useGeneratedKeys="true" keyProperty="id"
-->
<insert id="add" useGeneratedKeys="true" keyProperty="id">
insert into roc_user (user_name, password, nick_name, sex, age, avatar, add_time, update_time)
values (#{userName}, #{password}, #{nickName}, #{sex}, #{age}, #{avatar}, #{addTime}, #{updateTime});
</insert>

<!--
======================== 修改(存在BUG:没有传某个字段时,该字段会被修改为null) ============================
-->
<!-- <update id="update"> -->
<!-- update roc_user -->
<!-- set user_name = #{userName}, -->
<!-- password = #{password}, -->
<!-- nick_name = #{nickName}, -->
<!-- sex = #{sex}, -->
<!-- age = #{age}, -->
<!-- avatar = #{avatar}, -->
<!-- add_time = #{addTime}, -->
<!-- update_time = #{updateTime} -->
<!-- where id = ${id} -->
<!-- </update> -->

<!--
======================== 修改(解决上方BUG,动态修改字段) ============================
-->
<update id="update">
update roc_user
<set>
<if test="userName != null and userName != ''">
user_name = #{userName},
</if>
<if test="password != null and password != ''">
password = #{password},
</if>
<if test="nickName != null and nickName != ''">
nick_name = #{nickName},
</if>
<if test="sex != null">
sex = #{sex},
</if>
<if test="age != null">
age = #{age},
</if>
<if test="avatar != null and avatar != ''">
avatar = #{avatar},
</if>
<if test="addTime != null and addTime != ''">
add_time = #{addTime},
</if>
<if test="updateTime != null and updateTime != ''">
update_time = #{updateTime},
</if>
</set>
where id = #{id};
</update>

<!--
======================== 删除 ============================
-->
<delete id="deleteById">
delete
from roc_user
where id = #{id}
</delete>

<!--
======================== 批量删除 ============================
foreach 标签
collection: 默认 array, 在 Mapper 接口中使用注解 @Param("ids") 指定
item: 每一项的变量
separator: 使用什么分割
open: 使用 foreach 标签 开始拼接的字符串
close: 使用 foreach 标签 结束拼接的字符串
-->
<delete id="deleteByIds">
delete
from roc_user
where id in
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</delete>
<!-- 未使用 open close 效果 -->
<!-- <delete id="deleteByIds"> -->
<!-- delete -->
<!-- from roc_user -->
<!-- where id in( -->
<!-- <foreach collection="ids" item="id" separator=","> -->
<!-- #{id} -->
<!-- </foreach> -->
<!-- ) -->
<!-- </delete> -->
</mapper>

参数传递补充

MyBatis 参数传递,建议使用 @Param 修改 Map 集合中默认的键名!!!

MyBatis 参数封装:

  • 单个参数:
    • POJO 类型:直接使用,属性名 和 参数占位符名称 一致
    • Map 集合:直接使用,键名 和 参数占位符名称 一致
    • Collection:封装为 Map 集合,可以使用 @Param 注解,替换 Map 集合中默认的 arg 键名
      • 默认键名如下:
      • map.put(“arg0”,collection 集合);
      • map.put(“collection”,collection 集合);
    • List:封装为 Map 集合,可以使用 @Param 注解,替换 Map 集合中默认的 arg 键名
      • 默认键名如下:
      • map.put(“arg0”,list 集合);
      • map.put(“collection”,list 集合);
      • map.put(“list”,list 集合);
    • Array:封装为 Map 集合,可以使用 @Param 注解,替换 Map 集合中默认的 arg 键名(如批量删除地方就是用的 ids 替换了 array)
      • 默认键名如下:
      • map.put(“arg0”,数组);
      • map.put(“array”,数组);
    • 其他类型:直接使用
  • 多个参数:
    • 封装为 Map 集合,可以使用 @Param 注解,替换 Map 集合中默认的 arg 键名
    • 默认键名如下:
    • map.put(“arg0”,参数值 1)
    • map.put(“param1”,参数值 1)
    • map.put(“param2”,参数值 2)
    • map.put(“agr1”,参数值 2)
    • ——– 使用了 @Param(“username”) 默认的将被修改为如下: ——–
    • map.put(“username”,参数值 1)
    • map.put(“param1”,参数值 1)
    • map.put(“param2”,参数值 2)
    • map.put(“agr1”,参数值 2)