[MyBatis Plus]是基于 MyBatis 的增强工具,简化了数据库操作、提高了开发效率,广泛用于 Spring Boot 项目中。
// 定义实体类
@Data
public class User {
private Long id;
private String name;
private Integer age;
private String email;
}
// Mapper 接口
public interface UserMapper extends BaseMapper<User> {
}
// 使用示例
@Autowired
private UserMapper userMapper;
public void testSelect() {
List<User> users = userMapper.selectList(null); // 查询所有用户
users.forEach(System.out::println);
}
当数据量达到 十万级、百万级甚至千万级 时,以下问题会逐渐暴露出来:
例如,下面是一个典型的低效分页查询:
// 错误写法:使用 offset 分页在大数据量下效率极低
Page<User> page = new Page<>(10000, 10); // 第 10000 页,每页 10 条
userMapper.selectPage(page, null);
上述代码在 MySQL 中生成的 SQL 类似于:
SELECT * FROM user LIMIT 100000, 10;
这会导致 MySQL 必须扫描前 100000 条记录后才返回结果,效率非常低。
如果查询没有走索引,MySQL 就会进行全表扫描,随着数据量增长,性能急剧下降。
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name", "Tom");
List<User> users = userMapper.selectList(wrapper);
如果 name
字段没有索引,MySQL 只能进行全表扫描。
为常用查询字段添加索引:
ALTER TABLE user ADD INDEX idx_name (name);
如前所述,使用 LIMIT offset, size
的方式在偏移量较大时性能极差。
Long lastId = 0L; // 上一页最后一个ID
int pageSize = 10;
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.gt("id", lastId)
.orderByAsc("id")
.last("LIMIT " + pageSize);
List<User> users = userMapper.selectList(wrapper);
索引不是越多越好,也不是所有查询都能命中索引。
wrapper.like("name", "Tom"); // LIKE '%Tom%' 不走索引
应尽量避免前缀模糊查询,或者使用全文索引替代。
ORM 框架虽然简化了开发,但也带来了对象创建、属性赋值等额外开销。
selectObjs()
获取简单数据。List<Map<String, Object>> maps = userMapper.selectMaps(new QueryWrapper<User>().eq("age", 25));
maps.forEach(System.out::println);
输出:
{
name=Tom, age