Example API指南2

文章目录

  • [揭秘极简风格:TkMyBatis 通用 Example 类实战指南](#揭秘极简风格:TkMyBatis 通用 Example 类实战指南)
    • [一、为什么你用的是统一的 `Example`?](#一、为什么你用的是统一的 Example?)
    • 二、基础语法与初始化机制
    • 三、高频实战场景代码
      • [1. 基础 AND 条件查询](#1. 基础 AND 条件查询)
      • [2. 模糊查询 (LIKE) 与 集合过滤 (IN)](#2. 模糊查询 (LIKE) 与 集合过滤 (IN))
      • [3. 多分支 OR 查询](#3. 多分支 OR 查询)
      • [4. 排序 (ORDER BY) 与指定查询列 (SelectProperties)](#4. 排序 (ORDER BY) 与指定查询列 (SelectProperties))
      • [5. 结合 PageHelper 分页查询](#5. 结合 PageHelper 分页查询)
    • 四、动态条件拼接最佳实践
    • [五、TkMyBatis 的 `Example.builder` 链式进阶语法](#五、TkMyBatis 的 Example.builder 链式进阶语法)
    • 六、关键避坑点

你代码里直接使用 Example(而不是 UserExampleOrderExample 等表名专属类),说明你的项目使用的并不是 MyBatis 官方原生的 MyBatis Generator (MBG),而是国内非常主流的 TkMyBatis (通用 Mapper,作者 Abel533)

在 TkMyBatis 中,官方提供了一个统配所有实体类的通用泛型容器:tk.mybatis.mapper.entity.Example


揭秘极简风格:TkMyBatis 通用 Example 类实战指南

一、为什么你用的是统一的 Example

对比项 官方原生 MyBatis Generator TkMyBatis 通用 Mapper
类的全类名 自动生成在各实体包下的 com.xxx.model.UserExample 统一引用 tk.mybatis.mapper.entity.Example
文件生成量 每张表都需要生成一个数千行的 Java 文件 零物理生成,由框架提供统一的通用类
实现原理 编译期强类型绑定方法(如 andAgeEqualTo 运行时反射 解析实体类属性或 @Column 注解

TkMyBatis 的核心设计思想是通过实体类型 Class<T> 初始化上下文,从而省去了庞大的代码生成负担。


二、基础语法与初始化机制

创建 Example 时,必须将实体类的 Class 传入构造函数:

java 复制代码
import tk.mybatis.mapper.entity.Example;

// 1. 初始化,指定作用的实体类
Example example = new Example(User.class);

// 2. 创建条件容器
Example.Criteria criteria = example.createCriteria();

特别注意(新手最易踩坑点):

传给条件方法的字段名,默认是Java 实体类的属性名(驼峰命名,如 userIduserName ,而不是数据库底层的下划线字段名(user_iduser_name),TkMyBatis 会自动完成映射转换。


三、高频实战场景代码

1. 基础 AND 条件查询

目标 SQL:

sql 复制代码
SELECT * FROM user 
WHERE status = 1 
  AND age >= 18 
  AND age <= 30;

Java 代码:

java 复制代码
Example example = new Example(User.class);
example.createCriteria()
       .andEqualTo("status", 1)
       .andGreaterThanOrEqualTo("age", 18)
       .andLessThanOrEqualTo("age", 30);

List<User> users = userMapper.selectByExample(example);

2. 模糊查询 (LIKE) 与 集合过滤 (IN)

目标 SQL:

sql 复制代码
SELECT * FROM user 
WHERE user_name LIKE '%jack%' 
  AND role_id IN (1, 2, 3);

Java 代码:

java 复制代码
Example example = new Example(User.class);
example.createCriteria()
       .andLike("userName", "%jack%")       // 属性名 userName,需手写 %
       .andIn("roleId", Arrays.asList(1, 2, 3));

List<User> users = userMapper.selectByExample(example);

3. 多分支 OR 查询

目标 SQL:

sql 复制代码
SELECT * FROM user 
WHERE (dept_id = 10 AND status = 1) 
   OR (dept_id = 20 AND role_id = 2);

Java 代码:

java 复制代码
Example example = new Example(User.class);

// 第一个括号的分支 (deptId = 10 AND status = 1)
Example.Criteria criteria1 = example.createCriteria();
criteria1.andEqualTo("deptId", 10)
         .andEqualTo("status", 1);

// 新建第二个 Criteria 并用 OR 连接
Example.Criteria criteria2 = example.or();
criteria2.andEqualTo("deptId", 20)
         .andEqualTo("roleId", 2);

List<User> users = userMapper.selectByExample(example);

4. 排序 (ORDER BY) 与指定查询列 (SelectProperties)

TkMyBatis 在通用 Example 上扩展了非常便利的专属 API:

java 复制代码
Example example = new Example(User.class);
example.createCriteria().andEqualTo("status", 1);

// 方式一:面向属性名的安全排序(推荐,防止 SQL 注入)
example.orderBy("createTime").desc().orderBy("id").asc();

// 方式二:直接书写 SQL 排序片段
// example.setOrderByClause("create_time DESC, id ASC");

// 仅查询指定列(相当于 SELECT id, user_name),避免 SELECT *
example.selectProperties("id", "userName");

List<User> users = userMapper.selectByExample(example);

5. 结合 PageHelper 分页查询

在基于 TkMyBatis 的工程中,分页通常与 PageHelper 原生搭配:

java 复制代码
PageHelper.startPage(1, 10);

Example example = new Example(User.class);
example.createCriteria().andEqualTo("status", 1);
example.orderBy("createTime").desc();

List<User> list = userMapper.selectByExample(example);
PageInfo<User> pageInfo = new PageInfo<>(list);

四、动态条件拼接最佳实践

面对前端传入的动态搜索筛选(字段可能为空),常规写法是叠加 if 分支:

java 复制代码
Example example = new Example(User.class);
Example.Criteria criteria = example.createCriteria();

if (dto.getStatus() != null) {
    criteria.andEqualTo("status", dto.getStatus());
}
if (StringUtils.hasText(dto.getUserName())) {
    criteria.andLike("userName", "%" + dto.getUserName() + "%");
}
if (dto.getRoleIds() != null && !dto.getRoleIds().isEmpty()) {
    criteria.andIn("roleId", dto.getRoleIds());
}

List<User> list = userMapper.selectByExample(example);

五、TkMyBatis 的 Example.builder 链式进阶语法

TkMyBatis 还提供了更现代的 Builder 风格,可以将上述逻辑进一步压缩:

java 复制代码
Example example = Example.builder(User.class)
        .select("id", "userName", "status")
        .where(WeekendSqls.<User>custom()
                .andEqualTo(User::getStatus, 1)
                .andLike(User::getUserName, "%jack%"))
        .orderByDesc("createTime")
        .build();

List<User> users = userMapper.selectByExample(example);

提示 :如果使用的是 WeekendSqls,支持通过 Java 8 方法引用(如 User::getUserName)来避免写错字符串属性名。


六、关键避坑点

  • 传参是属性名,不是列名 :调用 andEqualTo("userId", 1),写 userId(Java 属性),不要user_id(数据库列名),否则会抛出找不到属性的反射异常。
  • **每次查询必须全新 new Example()**:不可跨请求复用 Example 单例,否则多线程并发时条件会混乱,且历史查询条件会被持续追加。
  • 空集合保护 :使用 andIn("roleId", list) 时,务必先判断 list != null && !list.isEmpty()。如果传入空集合,拼接出的 SQL 为 WHERE role_id IN (),会导致数据库直接报语法错误。
相关推荐
极客互动API43 分钟前
企业微信 AI 智能客服实战:Spring Boot+Vue 接入豆包、扣子、DeepSeek
java·人工智能·微信·企业微信
今天AI了吗44 分钟前
Codex使用技巧:深度解析 Plan Mode 与 Goal Mode
java·网络·人工智能·架构·java-ee
Huangxy__1 小时前
java+ai 全栈项目
java·开发语言
神仙别闹1 小时前
基于C#实现(WinForm)文件管理系统
java·开发语言·c#
砚底藏山河1 小时前
存储选型实战:CSV-SQLite-MySQL同机基准(魔码量化实战 #02)
java·数据库·python·金融·maven
huaweichenai1 小时前
spring boot 打包并部署到线上服务
java·数据库·spring boot
土司大王1 小时前
LeetCode hot100——实现 Trie (前缀树)
java·算法·leetcode
lhldsg1 小时前
从零构建智慧场馆解决方案小程序:开发全流程实战
java·前端·小程序
小七在进步1 小时前
类和对象(一)
java·数据结构·算法