外观
MySQL 学习笔记
面向复习整理的 MySQL 学习笔记,覆盖 SQL 基础语法、常用写法与易错点,以及 MyBatis 动态 SQL 的常用拼接写法。
1. SQL 基础
【重点要点】
- 核心 CRUD:INSERT / UPDATE / DELETE / SELECT;UPDATE、DELETE 漏写 WHERE 会作用全表,执行前先 SELECT 确认影响范围。
- 执行顺序:FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT;WHERE 中不能使用聚合函数,聚合结果过滤要用 HAVING。
- GROUP BY 后 SELECT 的非聚合列需用聚合函数包裹,MySQL 5.7+ 默认开启 only_full_group_by,直接选普通列会报错。
- JOIN:LEFT JOIN 的右表过滤条件放 WHERE 会把左连接退化成内连接,应写在 ON 里;ON 管连接匹配,WHERE 管结果过滤。
- NULL 陷阱:
= NULL永不成立,判断用 IS NULL / IS NOT NULL;COUNT(列) 不计 NULL 行,COUNT(*) 计所有行。 - 分页与去重:LIMIT offset, count(偏移量在前);去重用 DISTINCT,去重计数用 COUNT(DISTINCT 列)。
sql
-- 增删改查(UPDATE / DELETE 务必带 WHERE,否则全表生效)
INSERT INTO user (name, age) VALUES ('张三', 18);
UPDATE user SET age = 19 WHERE id = 1;
DELETE FROM user WHERE id = 2;
SELECT * FROM user WHERE age BETWEEN 18 AND 25 ORDER BY age DESC;sql
-- JOIN + 分组聚合 + HAVING + 排序分页:各课程平均分 Top 10
SELECT c.name AS course, AVG(sc.score) AS avg_score
FROM score sc
JOIN course c ON sc.course_id = c.id
GROUP BY c.id
HAVING avg_score >= 60
ORDER BY avg_score DESC
LIMIT 0, 10;2. 动态SQL
【重点要点】
<if>:test 条件成立才拼接片段;非空判断写法param != null and param != '',字符串字面量用单引号。<where>:自动剔除子元素开头多余的 AND/OR,避免拼出 WHERE AND ... 的语法错误;子条件全不满足时不生成 WHERE。<foreach>:遍历集合拼接 SQL,常用于 IN 查询与批量插入;collection 指定参数名(单个 List 用 list 或 @Param 别名),item 为元素别名,separator 为分隔符,open/close 指定左右包裹符。- 补充:
<set>用于动态 UPDATE,自动去掉末尾逗号;<choose>/<when>/<otherwise>实现多选一分支,类似 switch-case。 - 易错点:XML 中
<必须转义为<;拼接出的首部多余 AND/OR 统一交给<where>处理。
xml
<!-- 多条件查询:<where> 自动去掉首个多余的 AND -->
<select id="listUsers" resultType="User">
SELECT * FROM user
<where>
<if test="name != null and name != ''">
AND name LIKE CONCAT('%', #{name}, '%')
</if>
<if test="age != null">
AND age >= #{age}
</if>
</where>
ORDER BY id DESC
</select>xml
<!-- IN 查询:collection 用 @Param("ids") 别名;批量插入:collection 对应 List<User> -->
<select id="selectByIds" resultType="User">
SELECT * FROM user WHERE id IN
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
<insert id="batchInsert">
INSERT INTO user (name, age) VALUES
<foreach collection="list" item="u" separator=",">
(#{u.name}, #{u.age})
</foreach>
</insert>xml
<!-- 动态 UPDATE:<set> 自动去除末尾逗号 -->
<update id="updateUser">
UPDATE user
<set>
<if test="name != null">name = #{name},</if>
<if test="age != null">age = #{age},</if>
</set>
WHERE id = #{id}
</update>