一、什么是 MyBatis?
MyBatis 是 Java 中用于操作数据库的持久层框架,核心思想是 "用 SQL 语句精准控制数据库",提供灵活的 SQL 定制能力。通过 XML 或注解配置 SQL,自动将 Java 对象映射到 SQL 参数和结果集。
二、动态SQL ------ MyBatis 的杀手锏
动态 SQL 是 MyBatis 最强大的特性,能根据不同条件拼接 SQL 语句。举个栗子:用户注册时,非必填字段(如性别)可能为空,此时 SQL 需要灵活处理。
1. <if>
标签:条件判断
作用:如果字段存在则拼接 SQL,否则跳过。
sql
<!-- 根据性别动态插入(未填性别时不插入) -->
<insert id="insertUserByCondition">
INSERT INTO userinfo (
username,
password, --
<if test="gender != null">gender,</if>
phone
)
VALUES (
#{username},
#{password},
<if test="gender != null">#{gender},</if>
#{phone}
);
</insert>
重点 :test="gender != null"
中的 gender
是 Java 对象的属性名,不是数据库字段名!
2. <trim>
标签:去除多余符号
当多个动态字段存在时,可能因逗号导致语法错误。<trim>
自动处理头和尾的符号。
sql
<!-- 动态处理用户名、密码等字段,去掉末尾逗号 -->
<insert id="insertUserByCondition">
INSERT INTO userinfo
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="username != null">username,</if>
<if test="password != null">password,</if>
</trim>
VALUES
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="username != null">#{username},</if>
<if test="password != null">#{password},</if>
</trim>
</insert>
- prefix :开头添加
(
- suffix :结尾添加
)
- suffixOverrides:去掉最后一个逗号
3. <where>
和 <set>
标签
-
<where>
:自动去除条件前的AND
或OR
,避免WHERE
后空条件。sql<select id="queryByCondition" resultType="UserInfo"> SELECT * FROM userinfo <where> <if test="age !=null">AND age = #{age}</if> <if test="gender !=null">AND gender = #{gender}</if> </where> </select>
-
<set>
:自动去除UPDATE
语句中的多余逗号。
sql
<update id="updateUserByCondition">
UPDATE userinfo
<set>
<if test="username != null">username = #{username},</if>
<if test="password != null">password = #{password},</if>
</set>
WHERE id = #{id}
</update>
4. <foreach>
标签:批量操作
批量删除书籍(比如选中多个图书 ID 调用后端接口):
*
sql
<delete id="deleteByIds">
DELETE FROM book_info
WHERE id IN
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
collection="ids"
:传入的集合参数(如List<Integer>
)open
,close
:包裹成(id1, id2, id3)
separator
:分隔符设为逗号
三、实战案例 ------ 图书管理系统
1. 用户登录(Session管理)
sql
@PostMapping("/login")
public boolean login(String name, String password, HttpSession session) {
UserInfo user = userService.getUserByName(name);
if (user != null && password.equals(user.getPassword())) {
session.setAttribute("SESSION_USER_KEY", user); // 存储登录状态
return true;
}
return false;
}
2. 分页查询(LIMIT + 前端显示)
sql
// BookController
@GetMapping("/getListByPage")
public PageResult<BookInfo> getListByPage(@RequestParam int currentPage,
@RequestParam int pageSize) {
int offset = (currentPage - 1) * pageSize;
int total = bookService.countBooks();
List<BookInfo> books = bookService.getBooksByPage(offset, pageSize);
return new PageResult<>(total, books);
}
XML分页查询:
sql
<select id="getBooksByPage" resultType="BookInfo">
SELECT * FROM book_info
ORDER BY id DESC
LIMIT #{offset}, #{pageSize}
</select>
3. 强制登录(拦截器示例)
sql
@Component
public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
HttpSession session = request.getSession();
if (session.getAttribute("SESSION_USER_KEY") == null) {
response.sendRedirect("/login.html"); // 未登录跳转
return false;
}
return true;
}
}
四、核心技巧总结
-
动态SQL标签
<if>
:按条件拼接 SQL。<trim>
:去除多余符号的黑科技。<where>
+<set>
:智能处理条件。<foreach>
:批量操作神器。
-
项目实践常见问题
-
参数传递 :确保 XML 中
#{}
引用的属性名是 Java 对象的字段! -
逻辑删除 :通过
UPDATE
标记status=0
,而非物理删除。 -
分页计算 :
sqloffset = (currentPage - 1) * pageSize; totalPages = (total + pageSize - 1) / pageSize;
五、MyBatis Generator 代码生成工具
简化 CRUD 操作,快速生成 Model、Mapper 文件。
配置
generatorConfig.xml
sql<context id="demo" targetRuntime="MyBatis3Simple"> <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/book_test" userId="root" password="root"/> <javaModelGenerator targetPackage="com.example.model" targetProject="src/main/java"/> <sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources"/> <!-- 生成 DAO --> <javaClientGenerator type="XMLMAPPER" targetPackage="com.example.mapper" targetProject="src/main/java"/> <table tableName="book_info" domainObjectName="BookInfo"/> </context>
运行插件生成代码,无需手动写增删改查!
-