MyBatis 是一款优秀的持久层框架,它对 JDBC 进行了封装,使开发者能够更方便地操作数据库。在 MyBatis 中,Mapper 接口是一个非常重要的概念,它为开发者提供了一种简洁、高效的方式来定义数据库操作。本文将详细介绍 MyBatis Mapper 接口的相关知识,并提供使用指南。

一、Mapper 接口概述

Mapper 接口是 MyBatis 中用于定义数据库操作的接口。在传统的 JDBC 编程中,我们需要编写大量的 SQL 语句和数据库操作代码,而使用 MyBatis 的 Mapper 接口,我们只需要定义接口方法,MyBatis 会自动将这些方法与相应的 SQL 语句进行映射,从而实现数据库操作。Mapper 接口的主要优点包括:

1. 代码简洁:通过接口方法来定义数据库操作,避免了大量的 SQL 拼接和 JDBC 操作代码,使代码更加简洁易读。

2. 类型安全:接口方法的参数和返回值类型明确,编译器可以进行类型检查,减少了运行时错误。

3. 易于维护:将 SQL 语句与 Java 代码分离,便于后续的维护和修改。

二、Mapper 接口的定义

定义 Mapper 接口非常简单,只需要创建一个普通的 Java 接口,并在接口中定义数据库操作方法。以下是一个简单的 Mapper 接口示例:

public interface UserMapper {
    // 根据 ID 查询用户
    User selectUserById(int id);

    // 添加用户
    int insertUser(User user);

    // 更新用户信息
    int updateUser(User user);

    // 删除用户
    int deleteUser(int id);
}

在上述示例中,我们定义了一个名为 UserMapper 的接口,其中包含了四个方法,分别用于查询、添加、更新和删除用户信息。需要注意的是,接口方法的参数和返回值类型可以根据实际需求进行定义。

三、Mapper 接口与 SQL 语句的映射

定义好 Mapper 接口后,我们需要将接口方法与相应的 SQL 语句进行映射。MyBatis 提供了两种方式来实现这种映射:XML 映射文件和注解。

1. XML 映射文件

XML 映射文件是 MyBatis 中最常用的映射方式。我们可以创建一个与 Mapper 接口同名的 XML 文件,并在文件中编写 SQL 语句。以下是一个与上述 UserMapper 接口对应的 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.mapper.UserMapper">
    <select id="selectUserById" parameterType="int" resultType="com.example.entity.User">
        SELECT * FROM users WHERE id = #{id}
    </select>
    <insert id="insertUser" parameterType="com.example.entity.User">
        INSERT INTO users (name, age) VALUES (#{name}, #{age})
    </insert>
    <update id="updateUser" parameterType="com.example.entity.User">
        UPDATE users SET name = #{name}, age = #{age} WHERE id = #{id}
    </update>
    <delete id="deleteUser" parameterType="int">
        DELETE FROM users WHERE id = #{id}
    </delete>
</mapper>

在上述 XML 文件中,我们使用 <select>、<insert>、<update> 和 <delete> 标签分别定义了查询、添加、更新和删除操作的 SQL 语句。其中,id 属性对应 Mapper 接口中的方法名,parameterType 属性指定方法的参数类型,resultType 属性指定查询结果的类型。

2. 注解方式

除了使用 XML 映射文件,我们还可以使用注解来实现 Mapper 接口与 SQL 语句的映射。以下是使用注解实现上述 UserMapper 接口的示例:

import org.apache.ibatis.annotations.*;

public interface UserMapper {
    @Select("SELECT * FROM users WHERE id = #{id}")
    User selectUserById(int id);

    @Insert("INSERT INTO users (name, age) VALUES (#{name}, #{age})")
    int insertUser(User user);

    @Update("UPDATE users SET name = #{name}, age = #{age} WHERE id = #{id}")
    int updateUser(User user);

    @Delete("DELETE FROM users WHERE id = #{id}")
    int deleteUser(int id);
}

在上述示例中,我们使用 @Select、@Insert、@Update 和 @Delete 注解分别定义了查询、添加、更新和删除操作的 SQL 语句。注解的使用更加简洁,但对于复杂的 SQL 语句,可能不如 XML 映射文件灵活。

四、Mapper 接口的使用

定义好 Mapper 接口并完成映射后,我们就可以在代码中使用 Mapper 接口来进行数据库操作了。以下是一个简单的使用示例:

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.InputStream;

public class Main {
    public static void main(String[] args) throws Exception {
        // 加载 MyBatis 配置文件
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        // 获取 SqlSession 对象
        try (SqlSession session = sqlSessionFactory.openSession()) {
            // 获取 Mapper 接口实例
            UserMapper userMapper = session.getMapper(UserMapper.class);

            // 查询用户
            User user = userMapper.selectUserById(1);
            System.out.println(user);

            // 添加用户
            User newUser = new User();
            newUser.setName("John");
            newUser.setAge(25);
            int rows = userMapper.insertUser(newUser);
            session.commit();
            System.out.println("Inserted rows: " + rows);

            // 更新用户信息
            user.setName("Updated Name");
            rows = userMapper.updateUser(user);
            session.commit();
            System.out.println("Updated rows: " + rows);

            // 删除用户
            rows = userMapper.deleteUser(1);
            session.commit();
            System.out.println("Deleted rows: " + rows);
        }
    }
}

在上述示例中,我们首先加载 MyBatis 配置文件,创建 SqlSessionFactory 对象,然后通过 SqlSessionFactory 获取 SqlSession 对象。接着,我们使用 SqlSession 的 getMapper 方法获取 UserMapper 接口的实例,并调用接口方法进行数据库操作。最后,我们需要调用 SqlSession 的 commit 方法提交事务。

五、Mapper 接口的高级特性

1. 动态 SQL

MyBatis 支持动态 SQL,允许我们根据不同的条件动态生成 SQL 语句。在 XML 映射文件中,我们可以使用 <if>、<choose>、<when>、<otherwise>、<where>、<set> 和 <foreach> 等标签来实现动态 SQL。以下是一个使用 <if> 标签的示例:

<select id="selectUsersByCondition" parameterType="com.example.entity.User" resultType="com.example.entity.User">
    SELECT * FROM users
    <where>
        <if test="name != null and name != ''">
            AND name = #{name}
        </if>
        <if test="age != null">
            AND age = #{age}
        </if>
    </where>
</select>

在上述示例中,我们根据用户传入的参数动态生成查询条件。如果 name 不为空,则添加 name 条件;如果 age 不为空,则添加 age 条件。

2. 多参数传递

当 Mapper 接口方法需要传递多个参数时,我们可以使用 @Param 注解来指定参数名称。以下是一个示例:

public interface UserMapper {
    @Select("SELECT * FROM users WHERE name = #{name} AND age = #{age}")
    List<User> selectUsersByNameAndAge(@Param("name") String name, @Param("age") int age);
}

在上述示例中,我们使用 @Param 注解为方法参数指定了名称,这样在 SQL 语句中就可以通过参数名称来引用参数。

3. 结果映射

MyBatis 支持复杂的结果映射,允许我们将查询结果映射到不同的 Java 对象中。在 XML 映射文件中,我们可以使用 <resultMap> 标签来定义复杂的结果映射。以下是一个示例:

<resultMap id="UserResultMap" type="com.example.entity.User">
    <id property="id" column="id" />
    <result property="name" column="name" />
    <result property="age" column="age" />
</resultMap>
<select id="selectUserById" parameterType="int" resultMap="UserResultMap">
    SELECT * FROM users WHERE id = #{id}
</select>

在上述示例中,我们使用 <resultMap> 标签定义了一个名为 UserResultMap 的结果映射,将数据库表中的列映射到 Java 对象的属性上。然后,在 <select> 标签中使用 resultMap 属性引用该结果映射。

六、总结

MyBatis 的 Mapper 接口为开发者提供了一种简洁、高效的方式来操作数据库。通过定义接口方法并将其与 SQL 语句进行映射,我们可以避免编写大量的 JDBC 代码,提高开发效率。同时,MyBatis 还提供了丰富的高级特性,如动态 SQL、多参数传递和结果映射等,使我们能够处理各种复杂的数据库操作。在实际开发中,我们可以根据项目的需求选择合适的映射方式和高级特性,以实现高效、灵活的数据库操作。