深入浅出 MyBatis:从入门到实战的 Java 持久层框架应
引言:
在 Java 企业级开发领域,MyBatis 作为一款半自动化的 ORM(对象关系映射)框架,凭借其灵活的 SQL 映射机制和简洁的配置方式,成为了持久层开发的首选方案之一。本文将从 MyBatis 的核心概念出发,逐步带领读者掌握其基本使用方法,通过完整的实战案例演示从环境搭建到复杂查询的全流程操作,帮助开发者快速入门这一强大的持久层框架。
一、MyBatis 框架概述与核心优势
MyBatis(前身是 iBatis)诞生于 2001 年,由 Clinton Begin 创建,2010 年正式更名为 MyBatis 并捐赠给 Apache 基金会。与 Hibernate 等全自动 ORM 框架不同,MyBatis 采用 "半自动化" 的设计理念,将 SQL 语句从代码中分离出来进行集中管理,既保留了手动编写 SQL 的灵活性,又通过映射机制减少了重复的 JDBC 代码编写。
核心优势解析
- SQL 掌控力:开发者可以完全控制 SQL 语句的编写,针对复杂查询和性能优化具有天然优势,避免了全自动 ORM 框架可能产生的 "过度映射" 问题。
- 学习成本低:相较于 Hibernate 复杂的对象关系映射配置,MyBatis 的 XML 映射文件或注解配置更加直观,新手可以快速上手。
- 灵活的缓存机制:内置一级缓存(SqlSession 级别)和可配置的二级缓存(Mapper 级别),支持自定义缓存实现,能够有效提升查询性能。
- 与 Spring 无缝集成:在 Spring 生态中,MyBatis 通过 Spring Boot Starter 或 MyBatis-Spring 整合包,可以轻松实现事务管理和依赖注入。
二、环境搭建与项目初始化
Maven 依赖配置
首先创建一个 Maven 项目,在pom.xml中添加 MyBatis 及相关依赖。假设我们使用 MySQL 数据库,完整的依赖配置如下:
<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>
<!-- JUnit测试依赖 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>

数据库准备

创建一个示例数据库mybatis_demo,并建立一张用户表user,表结构如下:
CREATE DATABASE mybatis_demo;
USE mybatis_demo;
CREATE TABLE user (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL,
password VARCHAR(100) NOT NULL,
email VARCHAR(100),
age INT,
create_time DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- 插入测试数据
INSERT INTO user (username, password, email, age)
VALUES ('张三', '123456', 'zhangsan@example.com', 25),
('李四', 'abcdef', 'lisi@example.com', 30),
('王五', 'qwerty', 'wangwu@example.com', 28);
MyBatis 核心配置文件
在src/main/resources目录下创建mybatis-config.xml配置文件,这是 MyBatis 的全局配置文件,用于配置数据源、事务管理器等核心组件:
<?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">
<!-- 使用JDBC事务管理 -->
<transactionManager type="JDBC"/>
<!-- 配置数据源 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis_demo?useSSL=false&serverTimezone=UTC&characterEncoding=utf8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!-- 映射器配置,指定SQL映射文件的位置 -->
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
</configuration>
三、核心组件开发与映射配置
实体类设计
创建与数据库表对应的 Java 实体类User,位于com.example.entity包下:
package com.example.entity;
import java.util.Date;
public class User {
private Long id;
private String username;
private String password;
private String email;
private Integer age;
private Date createTime;
// 构造方法、getter和setter省略
// ...
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", email='" + email + '\'' +
", age=" + age +
", createTime=" + createTime +
'}';
}
}
Mapper 接口定义

在com.example.mapper包下创建UserMapper接口,定义数据库操作方法:
package com.example.mapper;
import com.example.entity.User;
import java.util.List;
import java.util.Map;
public interface UserMapper {
// 根据ID查询用户
User selectById(Long id);
// 查询所有用户
List<User> selectAll();
// 条件查询用户(使用Map传递参数)
List<User> selectByCondition(Map<String, Object> params);
// 插入用户
int insert(User user);
// 更新用户
int update(User user);
// 删除用户
int deleteById(Long id);
}
XML 映射文件实现

在src/main/resources/mapper目录下创建UserMapper.xml文件,实现 SQL 映射:
<?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.mapper.UserMapper">
<!-- 定义结果映射,解决数据库字段与实体类属性的映射关系 -->
<resultMap id="UserResultMap" type="com.example.entity.User">
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="email" property="email"/>
<result column="age" property="age"/>
<result column="create_time" property="createTime"/>
</resultMap>
<!-- 根据ID查询用户 -->
<select id="selectById" parameterType="long" resultMap="UserResultMap">
SELECT id, username, email, age, create_time
FROM user
WHERE id = #{id}
</select>
<!-- 查询所有用户 -->
<select id="selectAll" resultMap="UserResultMap">
SELECT id, username, email, age, create_time
FROM user
</select>
<!-- 条件查询用户 -->
<select id="selectByCondition" parameterType="map" resultMap="UserResultMap">
SELECT id, username, email, age, create_time
FROM user
<where>
<if test="username != null and username != ''">
AND username LIKE CONCAT('%', #{username}, '%')
</if>
<if test="age != null">
AND age = #{age}
</if>
</where>
ORDER BY create_time DESC
</select>
<!-- 插入用户 -->
<insert id="insert" parameterType="com.example.entity.User" useGeneratedKeys="true" keyProperty="id">
INSERT INTO user (username, password, email, age)
VALUES (#{username}, #{password}, #{email}, #{age})
</insert>
<!-- 更新用户 -->
<update id="update" parameterType="com.example.entity.User">
UPDATE user
<set>
<if test="username != null and username != ''">username = #{username},</if>
<if test="email != null and email != ''">email = #{email},</if>
<if test="age != null">age = #{age},</if>
</set>
WHERE id = #{id}
</update>
<!-- 删除用户 -->
<delete id="deleteById" parameterType="long">
DELETE FROM user
WHERE id = #{id}
</delete>
</mapper>
四、MyBatis 核心 API 使用与实战演示
SqlSessionFactory 的创建
创建MyBatisUtil工具类,用于获取SqlSession实例:
package com.example.util;
import java.io.IOException;
import java.io.Reader;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class MyBatisUtil {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
// 读取MyBatis配置文件
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
// 构建SqlSessionFactory
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
reader.close();
} catch (IOException e) {
e.printStackTrace();
throw new ExceptionInInitializerError("MyBatis初始化失败");
}
}
// 获取SqlSession实例
public static SqlSession getSqlSession() {
return sqlSessionFactory.openSession();
}
}
增删改查操作实战


创建测试类UserMapperTest,演示 MyBatis 的基本操作:
package com.example.test;
import com.example.entity.User;
import com.example.mapper.UserMapper;
import com.example.util.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class UserMapperTest {
private SqlSession sqlSession;
private UserMapper userMapper;
@Before
public void setUp() {
// 开启SqlSession,默认不自动提交事务
sqlSession = MyBatisUtil.getSqlSession();
// 获取Mapper接口代理对象
userMapper = sqlSession.getMapper(UserMapper.class);
}
@After
public void tearDown() {
// 关闭SqlSession
if (sqlSession != null) {
sqlSession.close();
}
}
@Test
public void testSelectAll() {
List<User> userList = userMapper.selectAll();
System.out.println("查询所有用户:");
for (User user : userList) {
System.out.println(user);
}
}
@Test
public void testSelectById() {
User user = userMapper.selectById(1L);
System.out.println("根据ID查询用户:");
System.out.println(user);
}
@Test
public void testInsert() {
User newUser = new User();
newUser.setUsername("赵六");
newUser.setPassword("123456");
newUser.setEmail("zhaoliu@example.com");
newUser.setAge(22);
int result = userMapper.insert(newUser);
// 提交事务
sqlSession.commit();
System.out.println("插入用户结果:" + result);
System.out.println("新插入用户ID:" + newUser.getId());
}
@Test
public void testUpdate() {
User user = userMapper.selectById(1L);
if (user != null) {
user.setEmail("zhangsan@new.com");
user.setAge(26);
int result = userMapper.update(user);
// 提交事务
sqlSession.commit();
System.out.println("更新用户结果:" + result);
User updatedUser = userMapper.selectById(1L);
System.out.println("更新后用户信息:");
System.out.println(updatedUser);
}
}
@Test
public void testDelete() {
Long deleteId = 4L; // 假设ID为4的用户存在
int result = userMapper.deleteById(deleteId);
// 提交事务
sqlSession.commit();
System.out.println("删除用户结果:" + result);
User deletedUser = userMapper.selectById(deleteId);
System.out.println("删除后查询结果:" + deletedUser);
}
@Test
public void testSelectByCondition() {
Map<String, Object> params = new HashMap<>();
params.put("username", "张");
params.put("age", 25);
List<User> userList = userMapper.selectByCondition(params);
System.out.println("条件查询结果:");
for (User user : userList) {
System.out.println(user);
}
}
}
五、MyBatis 高级特性初探
动态 SQL 的强大威力
MyBatis 的动态 SQL 元素(如<if>, <where>, <choose>, <foreach>等)能够根据参数动态拼接 SQL 语句,避免了手动拼接 SQL 的安全隐患和代码冗余。在前面的selectByCondition方法中,我们已经演示了<if>和<where>的基本用法,下面再来看一个使用<foreach>实现批量查询的例子:
在UserMapper接口中添加批量查询方法:
// 批量查询用户
List<User> selectByIds(List<Long> ids);
在UserMapper.xml中实现:
<select id="selectByIds" parameterType="java.util.List" resultMap="UserResultMap">
SELECT id, username, email, age, create_time
FROM user
WHERE id IN
<foreach collection="list" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
结果映射的高级配置
当数据库表结构与实体类属性命名不一致时,通过<resultMap>可以灵活配置映射关系。除了基本的字段映射,还可以配置复杂的关联查询映射(如一对一、一对多关系),例如假设有一个Order表与User表是一对多关系:
<resultMap id="OrderWithUserResultMap" type="com.example.entity.Order">
<id column="order_id" property="id"/>
<result column="order_name" property="name"/>
<result column="order_time" property="createTime"/>
<!-- 配置一对一关联,使用association标签 -->
<association property="user" javaType="com.example.entity.User">
<id column="user_id" property="id"/>
<result column="user_name" property="username"/>
<result column="user_email" property="email"/>
</association>
</resultMap>
<select id="selectOrderWithUser" resultMap="OrderWithUserResultMap">
SELECT
o.id AS order_id, o.name AS order_name, o.create_time AS order_time,
u.id AS user_id, u.username AS user_name, u.email AS user_email
FROM orders o
LEFT JOIN user u ON o.user_id = u.id
WHERE o.id = #{id}
</select>
六、MyBatis 与 Spring Boot 的集成
在实际开发中,MyBatis 通常与 Spring Boot 框架结合使用,下面简要介绍集成步骤:
添加 Spring Boot 依赖<dependencies>
<!-- Spring Boot Web依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- MyBatis Spring Boot Starter -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.2</version>
</dependency>
<!-- MySQL驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
</dependencies>
配置 application.properties# 数据库连接配置
spring.datasource.url=jdbc:mysql://localhost:3306
更多推荐


所有评论(0)