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
实现批量查询。
常见错误与解决方案
- Mapper接口未被扫描:检查
mybatis-config.xml
中的<mappers>
配置<mappers> <mapper resource="com/example/mapper/UserMapper.xml"/> </mappers>
- 参数绑定失败:确保传入参数名称与
#{}
占位符一致,或使用@Param
注解:@Select("SELECT * FROM users WHERE name = #{username}") User findByName(@Param("username") String name);
结论
MyBatis框架通过灵活的SQL映射机制,为Java开发者提供了高效且可控的数据访问方案。无论是编程初学者需要理解ORM基础,还是中级开发者寻求优化方案,MyBatis都能通过其丰富的扩展性和清晰的配置逻辑,成为构建企业级应用的可靠选择。建议读者通过实际项目实践上述案例,逐步掌握动态SQL、缓存配置等高级特性,从而在实际开发中发挥MyBatis的最大价值。