mybatis使用(超详细)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战(已更新的所有项目都能学习) / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新开坑项目:《Spring AI 项目实战》 正在持续爆肝中,基于 Spring AI + Spring Boot 3.x + JDK 21..., 点击查看 ;
  • 《从零手撸:仿小红书(微服务架构)》 已完结,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...,点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;

截止目前, 星球 内专栏累计输出 100w+ 字,讲解图 4013+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3700+ 小伙伴加入学习 ,欢迎点击围观

在 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 的核心优势

  1. 灵活的手动 SQL 编写:开发者完全掌控 SQL 语句,无需依赖框架生成不可控的 SQL。
  2. 高效的性能:避免了 Hibernate 等框架因全自动化带来的性能损耗。
  3. 易学易用:基于 SQL 的天然逻辑,学习曲线平缓。
  4. 支持动态 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 不仅能提升开发效率,更能加深对数据库操作底层逻辑的理解,为构建高性能应用打下坚实基础。

最新发布