缘博客
发布日期

MyBatis基础

作者
  • 姓名
    社交账号

MyBatis概述

MyBatis 是一款持久层框架,主要用于简化 JDBC 开发。

在典型的三层架构中:

Controller
Service
Mapper / DAO
Database

MyBatis 主要工作在持久层,也就是 Mapper / DAO 这一层。

使用 JDBC 直接操作数据库时,需要手动完成连接获取、SQL 执行、结果集解析和资源释放。MyBatis 对这些重复工作进行了封装,开发时通常只需要定义 Mapper 接口以及对应的 SQL。


Spring Boot + MyBatis入门

准备工作

基本步骤:

  1. 创建 Spring Boot 工程。
  2. 引入 MyBatis 和 MySQL 驱动等依赖。
  3. 准备数据库表和实体类。
  4. 配置数据库连接信息。
  5. 定义 Mapper 接口并编写 SQL。

例如实体类:

public class User {
    private Integer id;
    private String username;
    private String password;
    private String name;
    private Integer age;
}

数据库配置

使用 application.yml

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/web
    username: root
    password: 1234

Mapper接口

MyBatis 的持久层接口通常命名为 XxxMapper

@Mapper
public interface UserMapper {

    @Select("select * from user")
    List<User> findAll();
}

@Mapper 用于告诉 Spring:这是一个 MyBatis Mapper 接口,需要为它创建代理对象并交给 Spring 容器管理。


单元测试

Spring Boot 项目中可以通过 @SpringBootTest 加载完整的 Spring Boot 环境。

@SpringBootTest
class MybatisDemoApplicationTests {

    @Autowired
    private UserMapper userMapper;

    @Test
    void testFindAll() {
        List<User> users = userMapper.findAll();
        System.out.println(users);
    }
}

测试类一般放在启动类所在包或其子包中,保证 Spring Boot 能够正确扫描。


JDBC与MyBatis对比

JDBC 查询数据通常需要完成:

注册驱动
获取Connection
创建PreparedStatement
执行SQL
解析ResultSet
手动封装对象
释放资源

而使用 MyBatis 后:

@Mapper
public interface UserMapper {

    @Select("select * from user")
    List<User> findAll();
}

MyBatis 帮助处理了大量重复代码,包括数据库连接管理、SQL 执行、结果集解析、对象封装和资源释放。


数据库连接池

数据库连接池本质上是一个用于管理 Connection 的容器。

应用程序
   ↓ 获取连接
数据库连接池
Connection 1
Connection 2
Connection 3
...

应用使用完成后,不是直接销毁连接,而是将连接归还给连接池,后续请求可以继续复用。

主要优势:

  • 资源复用
  • 提升系统响应速度
  • 减少频繁创建连接的开销
  • 避免连接未释放造成的问题

Java 数据库连接池使用统一接口 DataSource

常见连接池包括:C3P0、DBCP、Druid、Hikari,其中 Spring Boot 默认使用 Hikari。


MyBatis增删改查

删除数据

@Delete("delete from user where id = #{id}")
int deleteById(Integer id);

执行 DML 语句时,可以使用 int 作为返回值,表示受影响的记录数。

新增数据

@Insert("""
    insert into user(username, password, name, age)
    values(#{username}, #{password}, #{name}, #{age})
    """)
void insert(User user);

当方法参数是对象时,可以直接通过对象属性名获取对应值。

修改数据

@Update("""
    update user
    set username = #{username},
        password = #{password},
        name = #{name},
        age = #{age}
    where id = #{id}
    """)
void update(User user);

查询数据

@Select("""
    select *
    from user
    where username = #{username}
      and password = #{password}
    """)
User findByUsernameAndPassword(String username, String password);

如果需要显式指定参数名称,也可以使用 @Param

@Select("""
    select *
    from user
    where username = #{uname}
      and password = #{pwd}
    """)
User findByUsernameAndPassword(
        @Param("uname") String username,
        @Param("pwd") String password
);

#{}${}

写法原理常见场景特点
#{...}使用占位符,最终生成预编译 SQL普通参数值安全、性能较好,推荐
${...}直接进行字符串拼接动态表名、动态字段名等存在 SQL 注入风险

例如:

@Delete("delete from dept where id = #{id}")
void delete(Integer id);

实际执行时类似:

delete from dept where id = ?

而:

@Select("select * from ${tableName}")
List<User> list(String tableName);

会把字符串直接拼接进 SQL,因此必须谨慎使用。

一般参数值优先使用 #{},只有无法使用占位符的动态 SQL 位置才考虑 ${}


MyBatis结果映射

如果数据库字段名和 Java 属性名完全一致,MyBatis 可以自动完成封装。

但数据库中经常使用下划线命名:

create_time
update_time

Java 中通常使用驼峰命名:

createTime
updateTime

可以开启驼峰映射:

mybatis:
  configuration:
    map-underscore-to-camel-case: true

之后 MyBatis 会自动按照下划线转驼峰完成映射。


SQL日志

如果希望在开发过程中查看 MyBatis 执行的 SQL,可以配置日志输出:

mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

配置后,控制台可以看到 MyBatis 实际执行的 SQL 和参数信息。


XML映射文件

MyBatis 除了使用注解配置 SQL,还可以使用 XML 映射文件。

Mapper 接口:

@Mapper
public interface UserMapper {
    List<User> findAll();
}

XML:

<mapper namespace="com.itheima.mapper.UserMapper">

    <select id="findAll"
            resultType="com.itheima.pojo.User">
        select id, username, password, name, age
        from user
    </select>

</mapper>

默认规则:

  1. XML 文件名称与 Mapper 接口名称一致。
  2. XML 中的 namespace 与 Mapper 接口全限定名一致。
  3. SQL 标签的 id 与 Mapper 方法名一致。
  4. 返回类型与 Mapper 方法返回类型匹配。

也可以统一放到:

src/main/resources/mapper/

并配置:

mybatis:
  mapper-locations: classpath:mapper/*.xml

注解还是XML

简单 SQL 使用注解比较直接:

@Select("select * from user")
List<User> findAll();

当 SQL 较复杂时,更适合使用 XML。

简单CRUD → 注解
复杂SQL / 动态SQL → XML