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+ 小伙伴加入学习 ,欢迎点击围观

MyBatis框架的核心概念

在Java开发的世界中,MyBatis框架如同一位精通多国语言的翻译官,它能够将Java对象(如POJO)与数据库的SQL语句无缝衔接。对于编程初学者而言,理解其核心机制是掌握这一工具的关键。

翻译官比喻:核心组件解析

MyBatis的三大核心组件可以形象地比喻为:

  • SqlSessionFactory:如同翻译官的“工作台”,负责创建数据库会话(SqlSession)
  • SqlSession:如同翻译官的“工作手册”,提供执行SQL、提交事务等操作
  • Mapper接口与XML/注解:如同翻译官的“语言词典”,定义具体的翻译规则

核心组件对比表

组件名称作用描述对应比喻
SqlSessionFactory创建数据库会话的工厂翻译官的工作台
SqlSession执行SQL、管理事务的上下文翻译官的工作手册
Mapper定义SQL映射关系翻译官的语言词典

配置文件:MyBatis的“导航地图”

MyBatis通过mybatis-config.xml配置全局参数,如数据库连接信息、类型别名等。例如:

<?xml version="1.0" encoding="UTF-8"?>  
<!DOCTYPE configuration  
  PUBLIC "-//mybatis.org//DTD CONFIG 3.5//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/test?useSSL=false"/>  
        <property name="username" value="root"/>  
        <property name="password" value="123456"/>  
      </dataSource>  
    </environment>  
  </environments>  
</configuration>  

此配置文件如同导航地图,指引MyBatis找到数据库的位置并建立连接。


快速入门:Hello World示例

通过一个简单案例,演示如何用MyBatis实现数据库查询。

1. Maven依赖配置

pom.xml中添加MyBatis和MySQL驱动依赖:

<dependencies>  
  <dependency>  
    <groupId>org.mybatis</groupId>  
    <artifactId>mybatis</artifactId>  
    <version>3.5.10</version>  
  </dependency>  
  <dependency>  
    <groupId>mysql</groupId>  
    <artifactId>mysql-connector-java</artifactId>  
    <version>8.0.29</version>  
  </dependency>  
</dependencies>  

2. 实体类与映射文件

创建User实体类:

public class User {  
  private Integer id;  
  private String name;  
  // 省略getter/setter  
}  

编写UserMapper.xml映射文件:

<mapper namespace="com.example.mapper.UserMapper">  
  <select id="selectUserById" resultType="User">  
    SELECT * FROM users WHERE id = #{id}  
  </select>  
</mapper>  

3. 核心代码实现

通过SqlSessionFactory创建会话并执行查询:

SqlSessionFactory factory = new SqlSessionFactoryBuilder()  
  .build(Resources.getResourceAsStream("mybatis-config.xml"));  
try (SqlSession session = factory.openSession()) {  
  UserMapper mapper = session.getMapper(UserMapper.class);  
  User user = mapper.selectUserById(1);  
  System.out.println(user.getName());  
}  

动态SQL的魔法:条件语句与循环

动态SQL是MyBatis区别于JDBC的核心优势之一,它允许根据条件动态拼接SQL语句。

if标签:智能条件判断

<select id="findActiveUsers" 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>  

此例中,<if>标签根据传入参数动态添加查询条件,避免了手动拼接SQL字符串的风险。

foreach标签:循环生成IN子句

<select id="findUsersByIds" resultType="User">  
  SELECT * FROM users  
  WHERE id IN  
  <foreach item="id" collection="ids" open="(" separator="," close=")">  
    #{id}  
  </foreach>  
</select>  

当传入List<Integer> ids时,会自动生成类似IN (1,2,3)的查询语句。


缓存机制:提升性能的“记忆库”

MyBatis提供了两级缓存机制,帮助开发者优化数据库访问效率。

一级缓存:SqlSession的本地缓存

默认开启,作用域为单个SqlSession。例如:

try (SqlSession session = factory.openSession()) {  
  User user1 = session.selectOne("selectUserById", 1);  
  User user2 = session.selectOne("selectUserById", 1);  
  System.out.println(user1 == user2); // 输出:true  
}  

两次查询返回同一对象,避免了重复查询数据库。

二级缓存:跨SqlSession的共享缓存

需在mybatis-config.xml中开启全局配置,并在Mapper中设置<cache>

<configuration>  
  <settings>  
    <setting name="cacheEnabled" value="true"/>  
  </settings>  
</configuration>  
<mapper namespace="com.example.mapper.UserMapper">  
  <cache/>  
  <!-- 其他SQL语句 -->  
</mapper>  

此时,不同SqlSession间的数据查询结果会被共享,但需注意数据一致性问题。


插件扩展:自定义功能的“系统接口”

MyBatis插件机制允许开发者通过拦截器(Interceptor)扩展核心功能。

拦截器原理:拦截SQL执行链

@Intercepts({@Signature(  
  type = Executor.class,  
  method = "query",  
  args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})})  
public class LoggingInterceptor implements Interceptor {  
  @Override  
  public Object intercept(Invocation invocation) throws Throwable {  
    System.out.println("执行SQL前的日志");  
    Object result = invocation.proceed(); // 继续执行原方法  
    System.out.println("执行SQL后的日志");  
    return result;  
  }  
}  

通过@Intercepts注解指定拦截的目标方法,实现日志记录或性能监控功能。


最佳实践与常见问题

配置优化技巧

  • 使用注解驱动:减少XML配置量,例如:
    @Select("SELECT * FROM users WHERE id = #{id}")  
    User selectUserById(Integer id);  
    
  • 避免N+1查询:通过<select>标签的fetchType="eager"@SelectProvider实现批量查询。

常见错误与解决方案

  1. Mapper接口未被扫描:检查mybatis-config.xml中的<mappers>配置
    <mappers>  
      <mapper resource="com/example/mapper/UserMapper.xml"/>  
    </mappers>  
    
  2. 参数绑定失败:确保传入参数名称与#{}占位符一致,或使用@Param注解:
    @Select("SELECT * FROM users WHERE name = #{username}")  
    User findByName(@Param("username") String name);  
    

结论

MyBatis框架通过灵活的SQL映射机制,为Java开发者提供了高效且可控的数据访问方案。无论是编程初学者需要理解ORM基础,还是中级开发者寻求优化方案,MyBatis都能通过其丰富的扩展性和清晰的配置逻辑,成为构建企业级应用的可靠选择。建议读者通过实际项目实践上述案例,逐步掌握动态SQL、缓存配置等高级特性,从而在实际开发中发挥MyBatis的最大价值。

最新发布