引言:

在 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&amp;serverTimezone=UTC&amp;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

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐