mybatis使用(超详细)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2900+ 小伙伴加入学习 ,欢迎点击围观
在 Java 后端开发中,数据库操作是核心任务之一。MyBatis 作为一款广泛使用的 ORM(对象关系映射)框架,凭借其灵活性和高效性,成为开发者实现数据持久层的首选工具。本文将从零开始,以循序渐进的方式讲解 MyBatis 使用 的核心知识,通过实际案例和代码示例,帮助读者掌握 MyBatis 的基础操作、配置方法以及高级特性。无论是编程新手还是有一定经验的开发者,都能在本文中找到适合自己的学习路径。
一、MyBatis 的核心概念与优势
1.1 什么是 MyBatis?
MyBatis 是一个基于 Java 的持久层框架,它简化了数据库与 Java 对象之间的映射关系。与 Hibernate 等全自动化 ORM 框架不同,MyBatis 采用 半自动化 的方式,允许开发者通过 XML 或注解直接编写 SQL 语句。这种设计使得 MyBatis 在性能和灵活性上具有显著优势,尤其适合需要精细控制 SQL 逻辑的场景。
形象比喻:
可以将 MyBatis 想象为一座桥梁,它连接了 Java 代码与数据库。开发者只需通过这座桥梁传递 SQL 请求,MyBatis 会自动处理底层的数据库连接、结果集映射等复杂操作。
1.2 MyBatis 的核心优势
- 灵活的手动 SQL 编写:开发者完全掌控 SQL 语句,无需依赖框架生成不可控的 SQL。
- 高效的性能:避免了 Hibernate 等框架因全自动化带来的性能损耗。
- 易学易用:基于 SQL 的天然逻辑,学习曲线平缓。
- 支持动态 SQL:通过条件判断和循环语句,动态生成复杂 SQL。
二、环境搭建与基础配置
2.1 引入 MyBatis 依赖
在 Maven 项目中,需在 pom.xml
文件中添加 MyBatis 依赖:
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.13</version>
</dependency>
2.2 配置 MyBatis 核心文件 mybatis-config.xml
此文件是 MyBatis 的全局配置中心,定义数据源、映射文件路径等关键信息。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD CONFIGURATION 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
</configuration>
关键点解析:
<environments>
定义数据库连接环境,transactionManager
和dataSource
分别控制事务和数据源。<mappers>
指定 SQL 映射文件的路径。
三、CRUD 操作详解
3.1 创建操作(Create)
3.1.1 通过 XML 配置插入数据
在映射文件 UserMapper.xml
中定义插入语句:
<insert id="insertUser" parameterType="User">
INSERT INTO users (name, email, age)
VALUES (#{name}, #{email}, #{age})
<selectKey keyProperty="id" resultType="int" order="AFTER">
SELECT LAST_INSERT_ID()
</selectKey>
</insert>
3.1.2 通过注解简化代码
在接口类中使用 @Insert
注解:
@Insert("INSERT INTO users (name, email, age) VALUES (#{name}, #{email}, #{age})")
void insertUser(User user);
3.2 查询操作(Read)
3.2.1 单条查询
通过 #{}
占位符实现参数化查询:
<select id="selectUserById" resultType="User">
SELECT * FROM users WHERE id = #{id}
</select>
3.2.2 分页查询
结合 LIMIT
关键字实现分页逻辑:
<select id="selectUsersByPage" resultType="User">
SELECT * FROM users
LIMIT #{offset}, #{pageSize}
</select>
3.3 更新操作(Update)
<update id="updateUser" parameterType="User">
UPDATE users
SET name = #{name}, email = #{email}
WHERE id = #{id}
</update>
3.4 删除操作(Delete)
<delete id="deleteUserById">
DELETE FROM users WHERE id = #{id}
</delete>
四、动态 SQL 的高级用法
4.1 条件判断(if 标签)
根据参数是否存在动态生成 SQL:
<select id="selectUsersByCondition" resultType="User">
SELECT * FROM users
WHERE 1=1
<if test="name != null">
AND name LIKE CONCAT('%', #{name}, '%')
</if>
<if test="age != null">
AND age >= #{age}
</if>
</select>
4.2 循环遍历(foreach 标签)
批量插入或 IN 条件查询:
<insert id="insertBatch">
INSERT INTO users (name, email)
VALUES
<foreach item="user" collection="list" separator=",">
(#{user.name}, #{user.email})
</foreach>
</insert>
4.3 逻辑分组(choose 标签)
类似 Java 的 switch-case
逻辑:
<choose>
<when test="priority == 'high'">
ORDER BY created_at DESC
</when>
<when test="priority == 'low'">
ORDER BY created_at ASC
</when>
<otherwise>
ORDER BY id ASC
</otherwise>
</choose>
五、缓存机制与性能优化
5.1 一级缓存(Local Cache)
MyBatis 默认启用一级缓存,作用域为 SqlSession 级别。在同一个会话中,相同 SQL 语句只会执行一次,结果会被缓存。
示例:
SqlSession session = sqlSessionFactory.openSession();
try {
User user1 = session.selectOne("selectUserById", 1);
User user2 = session.selectOne("selectUserById", 1);
System.out.println(user1 == user2); // 输出 true,证明是缓存对象
} finally {
session.close();
}
5.2 二级缓存(Second Level Cache)
通过配置 <cache>
标签,可启用跨会话的全局缓存:
<mapper namespace="com.example.mapper.UserMapper">
<cache/>
<!-- 其他 SQL 语句 -->
</mapper>
六、常见问题与解决方案
6.1 SQL 注入攻击的防范
MyBatis 的 #{}
占位符会自动进行参数转义,有效防止 SQL 注入。避免直接拼接字符串:
// 错误写法:直接拼接 SQL
String unsafeSql = "SELECT * FROM users WHERE name = '" + userInput + "'";
// 正确写法:使用 #{parameter}
String safeSql = "SELECT * FROM users WHERE name = #{name}";
6.2 多对多关系的映射
通过 <resultMap>
实现复杂关系映射:
<resultMap id="userWithRoles" type="User">
<id property="id" column="user_id"/>
<collection property="roles" ofType="Role">
<id property="roleId" column="role_id"/>
</collection>
</resultMap>
七、最佳实践与进阶技巧
7.1 使用 MyBatis-Plus 简化开发
MyBatis-Plus 是 MyBatis 的增强工具,提供代码生成、通用 CRUD 等功能:
// 自动实现基本增删改查
public interface UserMapper extends BaseMapper<User> {
// 自定义 SQL
}
7.2 日志输出与调试
在 mybatis-config.xml
中启用日志:
<settings>
<setting name="logImpl" value="SLF4J"/>
</settings>
结论
通过本文的讲解,读者应能掌握 MyBatis 使用 的核心方法与技巧。从基础配置到动态 SQL,从缓存优化到多表关联,MyBatis 的灵活性和高效性使其成为 Java 后端开发的必备工具。建议读者通过实际项目实践,逐步探索更多高级功能,如分页插件、自定义拦截器等。掌握 MyBatis 不仅能提升开发效率,更能加深对数据库操作底层逻辑的理解,为构建高性能应用打下坚实基础。