MyBatis 核心知识点与实战

1.1 MyBatis 简介与特点

MyBatis 是一款半自动的 ORM(对象关系映射)持久层框架,核心特点如下:

  • SQL 灵活性高:支持手动编写 SQL,可根据需求自由定制

  • 高级映射能力:支持一对一、一对多等关联关系映射

  • 动态 SQL:可根据参数条件动态拼接 SQL 语句

  • 支持延迟加载与缓存:提升数据查询性能

  • 数据库无关性较低:因需手写 SQL,切换数据库时可能需适配不同方言(Dialect)

1.2 ORM 概念

ORM(Object Relation Mapping)即对象关系映射,用于建立 Java 对象与数据库关系模型之间的对应关系:

  • 对象:Java 中的实体类(如 Student 类)

  • 关系:数据库中的表(如 student 表)

  • 映射规则:实体类属性与表字段一一对应,一个实体对象对应表中的一行数据

1.3 为什么 MyBatis 是半自动 ORM 框架?

半自动的核心原因是需要手动编写 SQL 语句,与全自动 ORM 框架(如 Hibernate)的区别如下:

  • MyBatis:需手动编写 SQL,灵活性高,但数据库无关性低,学习成本较低

  • Hibernate:无需编写 SQL,仅需定义 ORM 映射关系即可完成 CRUD 操作,数据库无关性高,但灵活性差,学习成本高

相比 JDBC,MyBatis 提供了输入映射、输出映射、关联查询等功能,简化了参数设置和结果集封装,大幅提升开发效率。

二、快速入门

2.1 核心步骤

  1. 编写全局配置文件(核心配置,含数据源等信息)

  2. 编写 Mapper 映射文件(编写 SQL 语句,定义输入/输出参数)

  3. 加载全局配置文件,生成 SqlSessionFactory

  4. 创建 SqlSession,调用 Mapper 中的 SQL 执行 CRUD 操作

2.2 原生开发示例

步骤 1:环境准备

  • 数据库:在本地 MySQL 创建库 yogurt,新建 student 表

  • 项目:IDEA 创建 Maven 项目,导入核心依赖

xml 复制代码
<dependencies>
  <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.10</version>
  </dependency>
  <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.6</version>
  </dependency>
  <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.12</version>
    <scope>provided</scope>
  </dependency>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.10</version>
    <scope>test</scope>
  </dependency>
</dependencies>

步骤 2:创建 PO 类

java 复制代码
package com.yogurt.po;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class Student {
  private Integer id;
  private String name;
  private Integer score;
  private Integer age;
  private Integer gender;
}

步骤 3:编写 Mapper 映射文件(StudentMapper.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="test">
  <select id="findAll" resultType="com.yogurt.po.Student">
    SELECT * FROM student;
  </select>
  <insert id="insert" parameterType="com.yogurt.po.Student">
    INSERT INTO student (name,score,age,gender) VALUES (#{name},#{score},#{age},#{gender});
  </insert>
  <delete id="delete" parameterType="int">
    DELETE FROM student WHERE id = #{id};
  </delete>
</mapper>

步骤 4:编写数据源配置文件(db.properties)

properties 复制代码
db.url=jdbc:mysql://192.168.183.129:3306/yogurt?characterEncoding=utf8
db.user=root
db.password=root
db.driver=com.mysql.jdbc.Driver

步骤 5:编写全局配置文件(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>
  <!-- 引入数据源配置文件 -->
  <properties resource="properties/db.properties"></properties>
  <!-- 配置环境 -->
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="${db.driver}"/>
        <property name="url" value="${db.url}"/>
        <property name="username" value="${db.user}"/>
        <property name="password" value="${db.password}"/>
      </dataSource>
    </environment>
  </environments>
  <!-- 加载 Mapper 映射文件 -->
  <mappers>
    <mapper resource="StudentMapper.xml"/>
  </mappers>
</configuration>

步骤 6:编写 DAO 类

java 复制代码
package com.yogurt.dao;
import com.yogurt.po.Student;
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.IOException;
import java.io.InputStream;
import java.util.List;

public class StudentDao {
  private SqlSessionFactory sqlSessionFactory;

  public StudentDao(String configPath) throws IOException {
    InputStream inputStream = Resources.getResourceAsStream(configPath);
    sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
  }

  public List<Student> findAll() {
    SqlSession sqlSession = sqlSessionFactory.openSession();
    List<Student> studentList = sqlSession.selectList("findAll");
    sqlSession.close();
    return studentList;
  }

  public int addStudent(Student student) {
    SqlSession sqlSession = sqlSessionFactory.openSession();
    int rowsAffected = sqlSession.insert("insert", student);
    sqlSession.commit();
    sqlSession.close();
    return rowsAffected;
  }

  public int deleteStudent(int id) {
    SqlSession sqlSession = sqlSessionFactory.openSession();
    int rowsAffected = sqlSession.delete("delete", id);
    sqlSession.commit();
    sqlSession.close();
    return rowsAffected;
  }
}

步骤 7:编写测试类

java 复制代码
import com.yogurt.dao.StudentDao;
import com.yogurt.po.Student;
import org.junit.Before;
import org.junit.Test;
import java.util.List;

public class SimpleTest {
  private StudentDao studentDao;

  @Before
  public void init() throws IOException {
    studentDao = new StudentDao("mybatis-config.xml");
  }

  @Test
  public void insertTest() {
    Student student = new Student();
    student.setName("yogurt");
    student.setAge(24);
    student.setGender(1);
    student.setScore(100);
    studentDao.addStudent(student);
  }

  @Test
  public void findAllTest() {
    List<Student> all = studentDao.findAll();
    all.forEach(System.out::println);
  }
}

三、核心配置详解

3.1 全局配置文件标签顺序

MyBatis 加载配置文件时按固定顺序解析标签,需严格遵循以下顺序:

xml 复制代码
<configuration>
  <!-- 1. 属性配置 -->
  <properties/>
  <!-- 2. 全局设置 -->
  <settings/>
  <!-- 3. 类型别名 -->
  <typeAliases/>
  <!-- 4. 类型处理器 -->
  <typeHandlers/>
  <!-- 5. 对象工厂 -->
  <objectFactory/>
  <!-- 6. 插件 -->
  <plugins/>
  <!-- 7. 环境配置 -->
  <environments>
    <environment>
      <transactionManager/>
      <dataSource/>
    </environment>
  </environments>
  <!-- 8. Mapper 加载 -->
  <mappers/>
</configuration>

3.2 核心子标签说明

3.2.1 properties

用于引入外部属性文件(如数据源配置),可通过 ${} 占位符引用属性值,简化配置维护。

3.2.2 settings

用于开启/关闭 MyBatis 核心特性,常用配置:

  • lazyLoadingEnabled:开启延迟加载(默认 false)

  • cacheEnabled:开启二级缓存(默认 true)

xml 复制代码
<settings>
  <setting name="lazyLoadingEnabled" value="true"/>
  <setting name="cacheEnabled" value="true"/>
</settings>

3.2.3 typeAliases

为实体类配置别名,简化 Mapper 中参数类型和返回值类型的书写,支持两种配置方式:

xml 复制代码
<!-- 单个类配置别名 -->
<typeAliases>
  <typeAlias type="com.yogurt.po.Student" alias="student"/>
</typeAliases>

<!-- 包扫描配置(所有类别名默认为简单类名小写) -->
<typeAliases>
  <package name="com.yogurt.po"/>
</typeAliases>

MyBatis 对基本类型、包装类及 String 提供默认别名(如 String → string、Integer → integer)。

3.2.4 plugins

配置 MyBatis 插件(如分页插件),底层通过责任链模式+动态代理实现。示例:PageHelper 分页插件配置

xml 复制代码
<plugins>
  <plugin interceptor="com.github.pagehelper.PageInterceptor">
    <property name="helperDialect" value="mysql"/>
  </plugin>
</plugins>

3.2.5 mappers

加载 Mapper 映射文件或接口,支持三种方式:

xml 复制代码
<!-- 1. 加载 XML 文件(相对类路径) -->
<mappers>
  <mapper resource="StudentMapper.xml"/>
</mappers>

<!-- 2. 加载 Mapper 接口(注解开发或 XML 与接口同目录同名) -->
<mappers>
  <mapper class="com.yogurt.mapper.StudentMapper"/>
</mappers>

<!-- 3. 包扫描加载(XML 与接口需同目录同名) -->
<mappers>
  <package name="com.yogurt.mapper"/>
</mappers>

注意:Maven 环境下,src/main/java 目录下的 XML 文件需通过 build-resources 配置才能被打包,否则会丢失。

xml 复制代码
<build>
  <resources>
    <resource>
      <directory>src/main/java</directory>
      <includes>
        <include>**/*.xml</include>
      </includes>
    </resource>
  </resources>
</build>

3.3 Mapper 中 #{} 与 ${} 的区别

特性 #{} ${}
解析方式 解析为 PreparedStatement 的 ?,预编译 直接字符串拼接,无预编译
SQL 注入 可防止 SQL 注入 存在 SQL 注入风险
参数类型解析 自动解析参数类型(如 String 加引号) 不解析类型,直接拼接
适用场景 普通参数传递(推荐) 模糊查询、表名/列名动态拼接
简单类型参数名 可任意命名 必须为 value

示例:

xml 复制代码
<!-- #{} 普通参数传递 -->
<select id="findById" parameterType="int" resultType="student">
  SELECT * FROM student WHERE id = #{id}
</select>

<!-- ${} 模糊查询 -->
<select id="findByName" parameterType="string" resultType="student">
  SELECT * FROM student WHERE name like '%${value}%'
</select>

四、MyBatis 开发方式

4.1 原生 DAO 开发(已过时)

即快速入门中的开发方式,需手动编写 DAO 类,通过 SqlSession 调用 SQL 标签 ID(字符串形式),易出错、维护成本高。

4.2 Mapper 接口代理开发(推荐)

无需编写 DAO 类,通过 Mapper 接口与 XML 映射文件绑定,MyBatis 自动生成代理实现类,简化开发。

4.2.1 核心绑定规则

  • Mapper 接口全限定名 = XML 标签的 namespace 属性值

  • 接口方法名 = XML 中 SQL 标签的 id 属性值

  • 接口方法入参类型 = XML 中 parameterType 属性值

  • 接口方法出参类型 = XML 中 resultType/resultMap 属性值

4.2.2 开发示例

java 复制代码
// 1. 创建 Mapper 接口
package com.yogurt.mapper;
import com.yogurt.po.Student;
import java.util.List;

public interface StudentMapper {
  List<Student> findAll();
  int insert(Student student);
  int delete(Integer id);
  List<Student> findByName(String value);
}
xml 复制代码
<!-- 2. 编写 Mapper XML(namespace 绑定接口) -->
<mapper namespace="com.yogurt.mapper.StudentMapper">
  <select id="findAll" resultType="com.yogurt.po.Student">
    SELECT * FROM student;
  </select>
  <insert id="insert" parameterType="com.yogurt.po.Student">
    INSERT INTO student (name,score,age,gender) VALUES (#{name},#{score},#{age},#{gender});
  </insert>
  <delete id="delete" parameterType="int">
    DELETE FROM student WHERE id = #{id};
  </delete>
  <select id="findByName" parameterType="string" resultType="student">
    SELECT * FROM student WHERE name like '%${value}%';
  &lt;/select&gt;
&lt;/mapper&gt;
java 复制代码
// 3. 测试代码
public class MapperProxyTest {
  private SqlSessionFactory sqlSessionFactory;

  @Before
  public void init() throws IOException {
    InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");
    sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
  }

  @Test
  public void test() {
    SqlSession sqlSession = sqlSessionFactory.openSession();
    // 获取 Mapper 代理对象
    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    // 调用接口方法(自动关联 XML 中的 SQL)
    List<Student> studentList = mapper.findAll();
    studentList.forEach(System.out::println);
    sqlSession.close();
  }
}

4.3 注解开发(简化配置)

无需编写 Mapper XML,直接在接口方法上通过注解编写 SQL,适合简单场景,维护性较差(修改 SQL 需改代码)。

4.3.1 开发示例

java 复制代码
// 1. 创建注解式 Mapper 接口
package com.yogurt.mapper;
import com.yogurt.po.Student;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import java.util.List;

public interface PureStudentMapper {
  @Select("SELECT * FROM student")
  List<Student> findAll();

  @Insert("INSERT INTO student (name,age,score,gender) VALUES (#{name},#{age},#{score},#{gender})")
  int insert(Student student);
}
xml 复制代码
<!-- 2. 全局配置文件加载 Mapper 接口 -->
<mappers>
  <mapper class="com.yogurt.mapper.PureStudentMapper"/>
</mappers>

4.3.2 多参数传递(@Param 注解)

多参数场景需通过 @Param 注解指定参数名,MyBatis 会自动封装为 Map 对象:

java 复制代码
import org.apache.ibatis.annotations.Param;

public interface PureStudentMapper {
  @Select("SELECT * FROM student WHERE name like '%${name}%' AND gender = #{gender}")
  List<Student> findByCondition(@Param("name") String name, @Param("gender") Integer gender);
}

五、核心应用场景

5.1 主键返回

针对自增主键,插入数据后获取数据库生成的主键 ID,支持两种方式:

xml 复制代码
<!-- 方式 1:useGeneratedKeys + keyProperty(推荐,适用于 MySQL 等支持自增的数据库) -->
<insert id="insert" parameterType="student" useGeneratedKeys="true" keyProperty="id">
  INSERT INTO student (name,score,age,gender) VALUES (#{name},#{score},#{age},#{gender});
</insert>

<!-- 方式 2:selectKey 子标签(通用,支持非自增主键) -->
<insert id="insert" parameterType="student">
  INSERT INTO student (name,score,age,gender) VALUES (#{name},#{score},#{age},#{gender});
  <selectKey keyProperty="id" order="AFTER" resultType="int">
    SELECT LAST_INSERT_ID(); <!-- MySQL 函数,获取最新插入的主键 -->
  </selectKey>
</insert>

测试验证:插入后通过实体对象的 getId() 方法获取主键。

5.2 动态 SQL

根据参数条件动态拼接 SQL,避免冗余代码,MyBatis 提供多种动态标签:

5.2.1 if 标签(条件判断)

xml 复制代码
<select id="find" resultType="student" parameterType="student">
  SELECT * FROM student WHERE age >= 18
  <if test="name != null and name != ''">
    AND name like '%${name}%'
  </if>
</select>

5.2.2 choose/when/otherwise 标签(分支选择)

类似 Java 的 switch 语句,仅执行第一个满足条件的分支:

xml 复制代码
<select id="findActiveBlogLike" resultType="Blog">
  SELECT * FROM BLOG WHERE state = 'ACTIVE'
  <choose>
    <when test="title != null">
      AND title like #{title}
    </when>
    <when test="author != null and author.name != null">
      AND author_name like #{author.name}
    </when>
    <otherwise>
      AND featured = 1
    </otherwise>
  </choose>
</select>

5.2.3 where/trim 标签(SQL 拼接优化)

where 标签自动处理 AND/OR 前缀,避免 SQL 语法错误:

xml 复制代码
<select id="findActiveBlogLike" resultType="Blog">
  SELECT * FROM BLOG
  <where>
    <if test="state != null">state = #{state}</if>
    <if test="title != null">AND title like #{title}</if>
    <if test="author != null and author.name != null">AND author_name like #{author.name}</if>
  </where>
</select>

trim 标签更灵活,可自定义前缀/后缀及需要去除的字符:

xml 复制代码
<!-- 等效于 where 标签 -->
<trim prefix="WHERE" prefixOverrides="AND | OR">
  <if test="state != null">state = #{state}</if>
  <if test="title != null">AND title like #{title}</if>
</trim>

5.2.4 set 标签(更新语句优化)

自动处理字段后的逗号,避免更新语句语法错误:

xml 复制代码
<update id="updateStudent" parameterType="student">
  UPDATE student
  <set>
    <if test="name != null">name = #{name},</if>
    <if test="age != null">age = #{age},</if>
    <if test="score != null">score = #{score}</if>
  </set>
  WHERE id = #{id}
</update>

5.2.5 foreach 标签(循环迭代)

常用于 IN 查询、批量操作,支持 List/Array 类型参数:

xml 复制代码
<!-- 批量查询(参数为 List,引用时变量名必须为 list) -->
<select id="batchFind" resultType="student" parameterType="java.util.List">
  SELECT * FROM student
  <where>
    <if test="list != null and list.size() > 0">
      AND id in
      <foreach collection="list" item="id" open="(" separator="," close=")">
        #{id}
      </foreach>
    </if>
  </where>
</select>

5.2.6 sql/include 标签(SQL 片段复用)

提取重复 SQL 片段,通过 include 引用,减少冗余:

xml 复制代码
<!-- 定义 SQL 片段 -->
<sql id="whereClause">
  <where>
    <if test="name != null and name != ''">
      AND name like '%${name}%'
    </if>
  </where>
</sql>

<!-- 引用 SQL 片段 -->
<select id="findUser" parameterType="student" resultType="student">
  SELECT * FROM student
  <include refid="whereClause"/>
</select>

5.3 缓存机制

MyBatis 提供两级缓存,用于减少数据库查询次数,提升性能:

5.3.1 一级缓存(默认开启)

  • 作用域:SqlSession 级别,同一 SqlSession 内重复查询相同 SQL 会复用缓存

  • 清除时机:执行 DML 操作、SqlSession 提交/关闭、设置 flushCache=true、开启 localCacheScope=STATEMENT

5.3.2 二级缓存(默认关闭)

  • 作用域:Mapper 级别,多个 SqlSession 可共享同一 Mapper 的缓存

  • 开启方式:1. 全局配置开启 cacheEnabled=true;2. Mapper XML 中添加 标签

  • 注意:缓存数据需序列化(实体类实现 Serializable 接口),SqlSession 提交后数据才会写入二级缓存

5.4 关联查询与延迟加载

5.4.1 关联查询标签

通过 resultMap 中的 association(一对一)和 collection(一对多)标签实现关联查询:

xml 复制代码
<resultMap id="studentExt" type="com.yogurt.po.StudentExt">
  <result property="id" column="id"/>
  <result property="name" column="name"/>
  <!-- 一对一关联:学生 → 班级 -->
  <association property="clazz" javaType="com.yogurt.po.Clazz" 
               column="class_id" select="com.yogurt.mapper.ClassMapper.findById"/>
</resultMap>

5.4.2 延迟加载(解决 N+1 问题)

N+1 问题:查询 N 个主对象时,触发 N 次从对象查询,性能低下。延迟加载可按需加载从对象,提升性能。

  • 开启方式:全局配置

  • 局部禁用:在 association/collection 标签中设置 fetchType="eager"

  • 触发时机:访问主对象的从对象属性时,才执行关联查询

N+1 问题其他解决方案:

  • 连接查询:通过 LEFT JOIN 一次性查询主从数据(需手动处理笛卡尔积)

  • 子查询:先查询主对象 ID 集合,再通过 IN 子查询查询从对象

六、实用工具

6.1 MyBatis 逆向工程

通过 mybatis-generator 工具自动生成单表的 PO 类、Mapper 接口和 XML 文件,支持单表 CRUD,不支持关联查询。

6.1.1 配置步骤

xml 复制代码
<!-- 1. 配置 Maven 插件 -->
<build>
  <plugins>
    <plugin>
      <groupId>org.mybatis.generator</groupId>
      <artifactId>mybatis-generator-maven-plugin</artifactId>
      <version>1.3.7</version>
      <configuration>
        <verbose>true</verbose>
        <overwrite>true</overwrite>
      </configuration>
    </plugin>
  </plugins>
</build>
xml 复制代码
<!-- 2. 编写 generatorConfig.xml 配置文件 -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
  <properties resource="properties/db.properties"/>
  <!-- 指定 MySQL 驱动路径 -->
  <classPathEntry location="C:\Users\Vergi\.m2\repository\mysql\mysql-connector-java\8.0.11\mysql-connector-java-8.0.11.jar"/>
  <context id="default" targetRuntime="MyBatis3">
    <!-- 关闭自动生成注释 -->
    <commentGenerator>
      <property name="suppressDate" value="true"/>
      <property name="suppressAllComments" value="true"/>
    </commentGenerator>
    <!-- 数据库连接配置 -->
    <jdbcConnection driverClass="${db.driver}"
                    connectionURL="${db.url}"
                    userId="${db.user}"
                    password="${db.password}">
    </jdbcConnection>
    <!-- Java 类型解析 -->
    <javaTypeResolver>
      <property name="forceBigDecimals" value="false"/>
    </javaTypeResolver>
    <!-- PO 类生成配置 -->
    <javaModelGenerator targetPackage="mybatis.generator.model" targetProject=".\src\main\java">
      <property name="enableSubPackages" value="false"/>
      <property name="trimStrings" value="true"/>
    </javaModelGenerator>
    <!-- Mapper XML 生成配置 -->
    <sqlMapGenerator targetPackage="mybatis.generator.mappers" targetProject=".\src\main\resources">
      <property name="enableSubPackages" value="false"/>
    </sqlMapGenerator>
    <!-- Mapper 接口生成配置 -->
    <javaClientGenerator type="XMLMAPPER" targetPackage="mybatis.generator.dao" targetProject=".\src\main\java">
      <property name="enableSubPackages" value="false"/>
    </javaClientGenerator>
    <!-- 指定要生成的表 -->
    <table tableName="student"/>
    <table tableName="product"/>
  </context>
</generatorConfiguration>

6.1.2 执行与使用

  • 执行:双击 Maven 插件 mybatis-generator:generate

  • 生成文件:PO 类、Example 类(条件查询工具)、Mapper 接口、Mapper XML

  • Example 类使用示例:

java 复制代码
@Test
public void testExample() {
  SqlSession sqlSession = sqlSessionFactory.openSession();
  StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
  // 创建条件对象
  StudentExample example = new StudentExample();
  StudentExample.Criteria criteria = example.createCriteria();
  // 添加查询条件:name 包含 "o"
  criteria.andNameLike("%o%");
  // 执行查询
  List<Student> students = mapper.selectByExample(example);
  students.forEach(System.out::println);
  sqlSession.close();
}

6.2 PageHelper 分页插件

快速实现分页功能,底层通过拼接 LIMIT 关键字(MySQL)实现。

6.2.1 配置步骤

xml 复制代码
<!-- 1. 导入依赖 -->
<dependency>
  <groupId>com.github.pagehelper</groupId>
  <artifactId>pagehelper</artifactId>
  <version>5.1.6</version>
</dependency>
xml 复制代码
<!-- 2. 全局配置文件添加插件 -->
<plugins>
  <plugin interceptor="com.github.pagehelper.PageInterceptor">
    <property name="helperDialect" value="mysql"/>
  </plugin>
</plugins>

6.2.2 使用示例

java 复制代码
@Test
public void testPageHelper() {
  SqlSession sqlSession = sqlSessionFactory.openSession();
  ProductMapper mapper = sqlSession.getMapper(ProductMapper.class);
  // 设置分页:第 1 页,每页 3 条数据
  PageHelper.startPage(1, 3);
  // 执行查询(自动分页)
  List<Product> products = mapper.selectByExample(new ProductExample());
  // 获取分页信息
  PageInfo&lt;Product&gt; pageInfo = new PageInfo<>(products);
  System.out.println("总记录数:" + pageInfo.getTotal());
  System.out.println("总页数:" + pageInfo.getPages());
  products.forEach(System.out::println);
  sqlSession.close();
}

注意:Mapper XML 中的 SQL 结尾不要加 ;,否则会导致 LIMIT 拼接失败。

相关推荐
薛不痒2 小时前
MySQL中使用SQL语言
数据库·sql·mysql
五阿哥永琪2 小时前
SQL中的函数--开窗函数
大数据·数据库·sql
为什么不问问神奇的海螺呢丶2 小时前
Oracle 数据库对象导出脚本-含创建语句
数据库·oracle
码农阿豪3 小时前
告别兼容焦虑:电科金仓 KES 如何把 Oracle 的 PL/SQL 和 JSON 业务“接住”
数据库·sql·oracle·json·金仓数据库
曹牧3 小时前
Oracle SQL 中,& 字符
数据库·sql·oracle
wdfk_prog3 小时前
[Linux]学习笔记系列 -- [fs]dcache
linux·数据库·笔记·学习·ubuntu
xrl20123 小时前
ruoyi-vue2集成flowable6.7.2后端篇
数据库·ruoyi·flowable·工作流集成
java1234_小锋3 小时前
Redis到底支不支持事务啊?
java·数据库·redis
云和恩墨4 小时前
告别 “事后救火”:7 大前置动作规避 80% 数据库故障
数据库·oracle