Loading... ### MyBatis 入门教程及配置详解 MyBatis 是一款优秀的 **持久层框架**,通过简化 JDBC 操作实现 SQL 与 Java 代码的解耦。本文基于 **MyBatis 3.5.10** 最新版本,结合企业级实践详解核心配置与使用流程。 --- #### 一、MyBatis 核心架构 ```mermaid graph TB A[应用程序] --> B[SqlSessionFactory] B --> C[SqlSession] C --> D[Executor] D --> E[[MappedStatement]] E --> F[SQL 映射文件] E --> G[注解 SQL] F --> H[数据库驱动] G --> H ``` **组件作用**: * `SqlSessionFactory`:全局单例,构建 SqlSession 的工厂 * `SqlSession`:线程级数据库操作入口 * `Executor`:SQL 执行器(分 Simple/Reuse/Batch 三种模式) * `MappedStatement`:存储 SQL 映射信息 --- #### 二、环境搭建(Maven 项目) ##### 1. 添加依赖 ```xml <dependencies> <!-- MyBatis 核心 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.10</version> </dependency> <!-- MySQL 驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> </dependency> </dependencies> ``` ##### 2. 核心配置文件 `mybatis-config.xml` ```xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 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/test?useSSL=false"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> <!-- 映射文件扫描 --> <mappers> <mapper resource="mapper/UserMapper.xml"/> </mappers> </configuration> ``` **关键配置说明**: | **标签** | **作用** | **推荐值** | | ------------------------- | -------------- | -------------------------------------------- | | `<transactionManager>` | 事务管理方式 | `JDBC`(标准事务) | | `<dataSource type>` | 连接池类型 | `POOLED`(内置连接池) | | `<property name="url">` | 数据库 URL | 需指定时区:`serverTimezone=Asia/Shanghai` | --- #### 三、SQL 映射文件开发 ##### 1. 创建 `UserMapper.xml` ```xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.example.dao.UserMapper"> <!-- 结果映射 --> <resultMap id="userMap" type="User"> <id property="id" column="id"/> <result property="name" column="user_name"/> <result property="email" column="email"/> </resultMap> <!-- 查询用户 --> <select id="selectUserById" resultMap="userMap"> SELECT id, user_name, email FROM users WHERE id = #{id} </select> <!-- 插入用户 --> <insert id="insertUser" useGeneratedKeys="true" keyProperty="id"> INSERT INTO users(user_name, email) VALUES(#{name}, #{email}) </insert> </mapper> ``` **标签详解**: * `namespace`:绑定对应的 Java 接口 * `resultMap`:解决数据库字段与 Java 属性名不一致问题 * `#{ }`:参数占位符(防 SQL 注入) ##### 2. 创建 Java 接口 ```java public interface UserMapper { User selectUserById(int id); int insertUser(User user); } ``` --- #### 四、动态 SQL 实战 ```xml <select id="findUsers" resultMap="userMap"> SELECT * FROM users <where> <if test="name != null"> AND user_name LIKE CONCAT('%', #{name}, '%') </if> <if test="email != null"> AND email = #{email} </if> <choose> <when test="role == 'admin'"> AND is_admin = 1 </when> <otherwise> AND is_active = 1 </otherwise> </choose> </where> </select> ``` **动态标签能力**: * `<where>`:智能去除前缀 AND * `<if>`:条件判断 * `<choose>/<when>/<otherwise>`:多分支选择 --- #### 五、Java 代码调用流程 ```java // 1. 加载配置文件 InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml"); // 2. 构建 SqlSessionFactory SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 3. 执行操作(try-with-resources 自动关闭) try (SqlSession session = sqlSessionFactory.openSession()) { // 方式一:直接调用 Mapper 文件 User user = session.selectOne("com.example.dao.UserMapper.selectUserById", 1); // 方式二:获取 Mapper 接口代理 UserMapper mapper = session.getMapper(UserMapper.class); User user2 = mapper.selectUserById(2); // 提交事务 session.commit(); } ``` --- #### 六、高级配置项解析 ##### 1. 类型处理器(TypeHandler) ```java // 自定义枚举处理器 public class StatusTypeHandler extends BaseTypeHandler<UserStatus> { @Override public void setNonNullParameter(PreparedStatement ps, int i, UserStatus status, JdbcType jdbcType) { ps.setInt(i, status.getCode()); // 将枚举转码存储 } @Override public UserStatus getNullableResult(ResultSet rs, String col) throws SQLException { return UserStatus.fromCode(rs.getInt(col)); // 从数据库解码 } } ``` **配置文件注册**: ```xml <typeHandlers> <typeHandler handler="com.example.handler.StatusTypeHandler" javaType="com.example.enums.UserStatus"/> </typeHandlers> ``` ##### 2. 插件开发(Interceptor) ```java @Intercepts({ @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}) }) public class SqlCostPlugin implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { long start = System.currentTimeMillis(); Object result = invocation.proceed(); System.out.println("SQL执行耗时:" + (System.currentTimeMillis()-start) + "ms"); return result; } } ``` **配置文件注册**: ```xml <plugins> <plugin interceptor="com.example.plugin.SqlCostPlugin"/> </plugins> ``` --- #### 七、最佳实践与避坑指南 | **场景** | **推荐方案** | **风险规避** | | -------------- | ------------------------------ | ------------------ | | SQL 注入防护 | 严格使用 `#{ }`代替 `${ }` | 禁止拼接不可信参数 | | 大数据量查询 | 配置 `fetchSize`分批获取 | 避免 OOM | | 多数据源操作 | 使用 `@Transactional`注解 | 确保事务边界清晰 | | 二级缓存启用 | 实体类实现 `Serializable` | 防止序列化异常 | > 🔥 **性能优化技巧**: > > * 批处理操作:`SqlSession#commit()` 前调用 `ExecutorType.BATCH` > * 延迟加载:`<association fetchType="lazy">` 避免 N+1 查询 > * 本地缓存:`<setting name="localCacheScope" value="STATEMENT"/>` 防止脏读 --- ### 总结 MyBatis 的核心价值在于 **灵活控制 SQL** 与 **对象映射解耦**: 1. **配置核心**:`mybatis-config.xml` 定义全局策略,映射文件编写 SQL 2. **动态 SQL**:`<if>/<choose>` 实现复杂条件查询 3. **扩展机制**:TypeHandler 解决类型转换,Interceptor 实现功能增强 4. **事务控制**:通过 `SqlSession#commit()` 或 Spring 声明式事务管理 > 🚀 **企业级建议**: > > * 生产环境使用 **Druid 连接池** 替代内置 POOLED > * 搭配 **PageHelper 分页插件** 实现物理分页 > * 启用 **MyBatis-Plus** 获得 Lambda 表达式支持 *验证环境:MyBatis 3.5.10 + MySQL 8.0 + JDK 17* 最后修改:2025 年 08 月 16 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏