当前位置: 首页 > news >正文

【mybatisPlus详解】

mybatisPlus详解

一、MyBatis-Plus 简介

核心定位与优势

MyBatis-Plus(简称MP)是一个MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,为简化开发、提高效率而生。它的核心优势包括:

  • 无侵入性:引入MyBatis-Plus不会对现有MyBatis工程产生影响,可以平滑迁移

  • 低损耗:启动时自动注入基本CURD,性能基本无损耗

  • 强大的CRUD:内置通用Mapper和Service,少量配置即可实现大部分单表操作

  • 丰富的功能:提供条件构造器、分页插件、代码生成器等实用工具

适用场景

  • 快速开发CRUD应用:减少约90%的CRUD代码

  • 管理系统开发:简单的增删改查场景

  • 微服务架构:配合代码生成器快速生成各服务基础代码

  • 现有MyBatis项目优化:可平滑集成,逐步替换简单CRUD

二、基础配置与集成

1. 依赖配置

xml

<!-- Maven 依赖 -->
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.0</version>
</dependency>
  1. Spring Boot 配置
    yaml

application.yml

mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl  # 开启SQL日志global-config:db-config:id-type: assign_id  # 主键生成策略(雪花算法)
  1. 实体类配置
    java
    // 实体类示例
@Data
@TableName("sys_user")  // 指定表名
public class User {@TableId(type = IdType.ASSIGN_ID)  // 主键策略:雪花算法private Long id;@TableField("user_name")  // 字段映射(非必须,默认开启驼峰转换)private String userName;private Integer age;private String email;@TableField(exist = false)  // 非数据库字段private String temporaryData;
}

三、Mapper CRUD 接口详解

  1. BaseMapper 基础接口
    java
// Mapper接口需继承BaseMapper
@Mapper
public interface UserMapper extends BaseMapper<User> {// 无需编写XML,即可获得基础CRUD方法
}
  1. 插入操作
    java
@SpringBootTest
class InsertTests {@Autowiredprivate UserMapper userMapper;@Testvoid testInsert() {User user = new User();user.setUserName("张三");user.setAge(25);user.setEmail("zhangsan@example.com");int result = userMapper.insert(user);System.out.println("影响行数: " + result);System.out.println("生成ID: " + user.getId()); // 自动回填ID}
}
  1. 删除操作
    java
@SpringBootTest
class DeleteTests {@Autowiredprivate UserMapper userMapper;@Testvoid testDeleteById() {// 根据ID删除int result = userMapper.deleteById(1475754982694199298L);System.out.println("删除结果: " + result);}@Testvoid testDeleteBatchIds() {// 批量删除List<Long> idList = Arrays.asList(1L, 2L, 3L);int result = userMapper.deleteBatchIds(idList);System.out.println("批量删除结果: " + result);}@Testvoid testDeleteByMap() {// 根据条件删除Map<String, Object> conditionMap = new HashMap<>();conditionMap.put("user_name", "张三");conditionMap.put("age", 25);int result = userMapper.deleteByMap(conditionMap);System.out.println("条件删除结果: " + result);}
}
  1. 更新操作
    java
@SpringBootTest
class UpdateTests {@Autowiredprivate UserMapper userMapper;@Testvoid testUpdateById() {User user = new User();user.setId(1L);user.setUserName("李四");user.setEmail("lisi@example.com");int result = userMapper.updateById(user);System.out.println("更新结果: " + result);}
}
  1. 查询操作
    java
@SpringBootTest
class SelectTests {@Autowiredprivate UserMapper userMapper;@Testvoid testSelectById() {User user = userMapper.selectById(1L);System.out.println("查询结果: " + user);}@Testvoid testSelectBatchIds() {List<Long> idList = Arrays.asList(1L, 2L, 3L);List<User> users = userMapper.selectBatchIds(idList);users.forEach(System.out::println);}@Testvoid testSelectByMap() {Map<String, Object> conditionMap = new HashMap<>();conditionMap.put("user_name", "张三");conditionMap.put("age", 25);List<User> users = userMapper.selectByMap(conditionMap);users.forEach(System.out::println);}@Testvoid testSelectList() {// 查询所有数据List<User> users = userMapper.selectList(null);users.forEach(System.out::println);}
}

四、Service CRUD 接口详解

  1. Service层配置
    java
// Service接口
public interface UserService extends IService<User> {// 可扩展自定义方法
}
// Service实现类
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {// 已获得所有基础CRUD方法
}
  1. Service CRUD 操作
    java
@SpringBootTest
class ServiceTests {@Autowiredprivate UserService userService;@Testvoid testSave() {User user = new User();user.setUserName("王五");user.setAge(30);boolean result = userService.save(user);System.out.println("保存结果: " + result);}@Testvoid testSaveBatch() {List<User> userList = new ArrayList<>();for (int i = 0; i < 5; i++) {User user = new User();user.setUserName("用户" + i);user.setAge(20 + i);userList.add(user);}boolean result = userService.saveBatch(userList);System.out.println("批量保存结果: " + result);}@Testvoid testGetById() {User user = userService.getById(1L);System.out.println("查询结果: " + user);}@Testvoid testUpdate() {User user = new User();user.setId(1L);user.setUserName("更新后的名字");boolean result = userService.updateById(user);System.out.println("更新结果: " + result);}@Testvoid testRemove() {boolean result = userService.removeById(1L);System.out.println("删除结果: " + result);}@Testvoid testList() {List<User> userList = userService.list();userList.forEach(System.out::println);}
}
  1. 复杂查询方法
    java
@SpringBootTest
class ComplexQueryTests {@Autowiredprivate UserService userService;@Testvoid testGetOne() {// 查询一条记录,如果找到多条会抛出异常QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.eq("user_name", "张三");User user = userService.getOne(queryWrapper, true); // 第二个参数为是否抛出异常System.out.println("查询结果: " + user);}@Testvoid testCount() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.gt("age", 20); // 年龄大于20long count = userService.count(queryWrapper);System.out.println("统计结果: " + count);}@Testvoid testPage() {// 分页查询Page<User> page = new Page<>(1, 10); // 当前页,每页大小QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.orderByDesc("id");Page<User> result = userService.page(page, queryWrapper);System.out.println("总记录数: " + result.getTotal());System.out.println("总页数: " + result.getPages());result.getRecords().forEach(System.out::println);}
}

五、条件构造器详解

  1. QueryWrapper 基础用法
    java
@SpringBootTest
class QueryWrapperTests {@Autowiredprivate UserMapper userMapper;@Testvoid testBasicQuery() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();// 等值查询queryWrapper.eq("user_name", "张三").ge("age", 18)  // 大于等于.le("age", 65)  // 小于等于.like("email", "@example.com")  // 模糊查询.isNotNull("create_time");  // 不为空List<User> users = userMapper.selectList(queryWrapper);users.forEach(System.out::println);}@Testvoid testComplexQuery() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();// 复杂条件: (age > 18 AND age < 30) OR (user_name LIKE '%张%')queryWrapper.and(wrapper -> wrapper.gt("age", 18).lt("age", 30)).or(wrapper -> wrapper.like("user_name", "张"));List<User> users = userMapper.selectList(queryWrapper);users.forEach(System.out::println);}@Testvoid testSelectFields() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();// 指定查询字段queryWrapper.select("id", "user_name", "age").eq("age", 25).orderByDesc("id");List<User> users = userMapper.selectList(queryWrapper);users.forEach(System.out::println);}
}
  1. Lambda 条件构造器
    java
@SpringBootTest
class LambdaWrapperTests {@Autowiredprivate UserMapper userMapper;@Testvoid testLambdaQuery() {LambdaQueryWrapper<User> lambdaWrapper = new LambdaQueryWrapper<>();// 使用Lambda表达式,避免硬编码字段名lambdaWrapper.eq(User::getUserName, "张三").ge(User::getAge, 18).between(User::getCreateTime, LocalDateTime.now().minusDays(7), LocalDateTime.now());List<User> users = userMapper.selectList(lambdaWrapper);users.forEach(System.out::println);}@Testvoid testLambdaWithService() {List<User> users = userService.lambdaQuery().eq(User::getAge, 25).like(User::getUserName, "张").list();users.forEach(System.out::println);}
}
  1. UpdateWrapper 更新构造器
    java
@SpringBootTest
class UpdateWrapperTests {@Autowiredprivate UserMapper userMapper;@Testvoid testUpdateWithWrapper() {UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();// 设置更新内容和条件updateWrapper.set("age", 30).set("update_time", LocalDateTime.now()).eq("user_name", "张三").ge("age", 25);int result = userMapper.update(null, updateWrapper);System.out.println("更新影响行数: " + result);}@Testvoid testLambdaUpdate() {boolean result = userService.lambdaUpdate().set(User::getAge, 35).set(User::getUpdateTime, LocalDateTime.now()).eq(User::getUserName, "张三").update();System.out.println("Lambda更新结果: " + result);}
}

六、高级功能

  1. 分页插件配置与使用
    java
@Configuration
public class MybatisPlusConfig {/*** 分页插件配置*/@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));return interceptor;}
}// 分页使用示例
@SpringBootTest
class PageTests {@Autowiredprivate UserMapper userMapper;@Testvoid testPageQuery() {// 第一页,每页10条Page<User> page = new Page<>(1, 10);QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.orderByDesc("id");Page<User> result = userMapper.selectPage(page, queryWrapper);System.out.println("总记录数: " + result.getTotal());System.out.println("总页数: " + result.getPages());System.out.println("当前页: " + result.getCurrent());System.out.println("每页大小: " + result.getSize());result.getRecords().forEach(System.out::println);}@Testvoid testCustomPage() {Page<User> page = new Page<>(1, 5);// 自定义分页查询Page<User> result = userMapper.selectPage(page, Wrappers.<User>lambdaQuery().ge(User::getAge, 18).orderByAsc(User::getAge));result.getRecords().forEach(System.out::println);}
}

2. 逻辑删除配置

yaml

application.yml

mybatis-plus:global-config:db-config:logic-delete-field: deleted  # 逻辑删除字段名logic-delete-value: 1  # 删除值logic-not-delete-value: 0  # 未删除值

java

// 实体类配置
@Data
@TableName("sys_user")
public class User {// 其他字段...@TableLogic  // 逻辑删除注解private Integer deleted;
}
// 使用示例:删除操作会自动变为更新deleted字段
@Test
void testLogicDelete() {// 实际执行的是:UPDATE sys_user SET deleted = 1 WHERE id = ? AND deleted = 0boolean result = userService.removeById(1L);System.out.println("逻辑删除结果: " + result);// 查询时会自动加上 deleted = 0 条件User user = userService.getById(1L); // 返回null,因为已被逻辑删除
}

3. 自动填充功能

java

// 实体类配置
@Data
@TableName("sys_user")
public class User {// 其他字段...@TableField(fill = FieldFill.INSERT)private LocalDateTime createTime;@TableField(fill = FieldFill.INSERT_UPDATE)private LocalDateTime updateTime;
}

自动填充处理器

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {@Overridepublic void insertFill(MetaObject metaObject) {this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());}@Overridepublic void updateFill(MetaObject metaObject) {this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());}
}

4. 枚举类型处理

java

// 枚举定义
public enum UserStatus {ENABLED(1, "启用"),DISABLED(0, "禁用");private final Integer code;private final String desc;UserStatus(Integer code, String desc) {this.code = code;this.desc = desc;}public Integer getCode() {return code;}
}

实体类使用枚举

@Data
@TableName("sys_user")
public class User {// 其他字段...@EnumValue  // 标记数据库存储的是code值private UserStatus status;
}

配置枚举包扫描

@Configuration
public class MybatisPlusConfig {@Beanpublic MybatisPlusPropertiesCustomizer mybatisPlusPropertiesCustomizer() {return properties -> {properties.getConfiguration().setDefaultEnumTypeHandler(MybatisEnumTypeHandler.class);};}
}
  1. 多数据源支持
    java
// 多数据源配置示例
@Configuration
@MapperScan(basePackages = "com.example.mapper.primary", sqlSessionFactoryRef = "primarySqlSessionFactory")
public class PrimaryDataSourceConfig {@Bean@Primary@ConfigurationProperties("spring.datasource.primary")public DataSource primaryDataSource() {return DruidDataSourceBuilder.create().build();}@Bean@Primarypublic SqlSessionFactory primarySqlSessionFactory() throws Exception {MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();sqlSessionFactory.setDataSource(primaryDataSource());return sqlSessionFactory.getObject();}
}

七、代码生成器

java

// 代码生成器配置
public class CodeGenerator {public static void main(String[] args) {// 代码生成器AutoGenerator generator = new AutoGenerator();// 全局配置GlobalConfig globalConfig = new GlobalConfig();globalConfig.setOutputDir(System.getProperty("user.dir") + "/src/main/java");globalConfig.setAuthor("YourName");globalConfig.setOpen(false);globalConfig.setFileOverride(true);generator.setGlobalConfig(globalConfig);// 数据源配置DataSourceConfig dataSourceConfig = new DataSourceConfig();dataSourceConfig.setUrl("jdbc:mysql://localhost:3306/test?useSSL=false");dataSourceConfig.setDriverName("com.mysql.cj.jdbc.Driver");dataSourceConfig.setUsername("root");dataSourceConfig.setPassword("password");generator.setDataSource(dataSourceConfig);// 包配置PackageConfig packageConfig = new PackageConfig();packageConfig.setParent("com.example");packageConfig.setModuleName("system");packageConfig.setEntity("entity");packageConfig.setMapper("mapper");packageConfig.setService("service");packageConfig.setController("controller");generator.setPackageInfo(packageConfig);// 策略配置StrategyConfig strategy = new StrategyConfig();strategy.setNaming(NamingStrategy.underline_to_camel);strategy.setColumnNaming(NamingStrategy.underline_to_camel);strategy.setEntityLombokModel(true);strategy.setRestControllerStyle(true);strategy.setInclude("user", "role", "menu"); // 要生成的表generator.setStrategy(strategy);// 执行生成generator.execute();}
}

八、最佳实践与注意事项

  1. 性能优化建议
    java
// 批量操作示例
@SpringBootTest
class BatchOperationTests {@Autowiredprivate UserService userService;@Testvoid testBatchInsert() {List<User> userList = new ArrayList<>();for (int i = 0; i < 1000; i++) {User user = new User();user.setUserName("batch_user_" + i);user.setAge(20 + (i % 30));userList.add(user);}// 分批插入,每批100条boolean result = userService.saveBatch(userList, 100);System.out.println("批量插入结果: " + result);}@Testvoid testBatchUpdate() {List<User> userList = userService.list();userList.forEach(user -> user.setAge(user.getAge() + 1));// 分批更新boolean result = userService.updateBatchById(userList, 100);System.out.println("批量更新结果: " + result);}
}
  1. 复杂SQL处理
    java
// 自定义SQL方法
public interface UserMapper extends BaseMapper<User> {// 自定义查询方法@Select("SELECT u.*, d.department_name " +"FROM sys_user u " +"LEFT JOIN sys_department d ON u.department_id = d.id " +"WHERE u.age > #{minAge}")List<User> selectUsersWithDepartment(@Param("minAge") Integer minAge);// 自定义分页查询IPage<User> selectUserPageWithDepartment(Page<User> page, @Param("userName") String userName);
}// 对应的XML配置(在resources/mapper/UserMapper.xml中)
<select id="selectUserPageWithDepartment" resultType="com.example.entity.User">SELECT u.*, d.department_name FROM sys_user u LEFT JOIN sys_department d ON u.department_id = d.id WHERE u.user_name LIKE CONCAT('%', #{userName}, '%')
</select>

总结

MyBatis-Plus通过提供丰富的功能和简洁的API,极大地提升了开发效率。关键优势包括:

  • 开发效率:减少约90%的CRUD代码

  • 维护性:统一的代码风格和最佳实践

  • 灵活性:既可以使用MP的快捷方法,也可以编写自定义SQL

  • 安全性:内置SQL注入防护和逻辑删除等功能

对于复杂业务场景,建议:

简单CRUD使用MP提供的方法

复杂查询使用Wrapper条件构造器

特别复杂的多表关联使用自定义SQL

合理使用代码生成器减少重复工作

mybatisPlus查询指定字段

方法一:使用QueryWrapper + select指定字段
java

@Service
public class UserService {@Autowiredprivate UserMapper userMapper;public List<String> getNamesByAgeGreaterThan30() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.select("name")  // 只查询name字段.gt("age", 30);  // age > 30List<User> users = userMapper.selectList(queryWrapper);return users.stream().map(User::getName).collect(Collectors.toList());}
}

方法二:使用LambdaQueryWrapper(推荐)

@Service
public class UserService {@Autowiredprivate UserMapper userMapper;public List<String> getNamesByAgeGreaterThan30() {LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();lambdaQueryWrapper.select(User::getName)  // 只选择name字段.gt(User::getAge, 30);  // age > 30List<User> users = userMapper.selectList(lambdaQueryWrapper);return users.stream().map(User::getName).collect(Collectors.toList());}
}

方法三:自定义Mapper方法(最高效)
在UserMapper中定义自定义方法:

public interface UserMapper extends BaseMapper<User> {@Select("SELECT name FROM user WHERE age > 30")List<String> selectNamesByAgeGreaterThan30();// 或者使用参数化的方式@Select("SELECT name FROM user WHERE age > #{age}")List<String> selectNamesByAgeGreaterThan(@Param("age") Integer age);
}

然后在Service中调用:

@Service
public class UserService {@Autowiredprivate UserMapper userMapper;public List<String> getNamesByAgeGreaterThan30() {return userMapper.selectNamesByAgeGreaterThan30();// 或者// return userMapper.selectNamesByAgeGreaterThan(30);}
}

实体类定义

@Data
@TableName("user")
public class User {@TableIdprivate Long id;private String name;private Integer age;
}

推荐方案
推荐使用方法三(自定义Mapper方法),因为:

性能最优,直接返回字符串列表

代码最简洁

避免不必要的对象转换

SQL清晰易懂

如果你坚持使用Wrapper方式,方法二(LambdaQueryWrapper)是更好的选择,类型安全且可读性强。

http://www.dtcms.com/a/473757.html

相关文章:

  • 回归与分类算法全解析:从理论到实践
  • 什么是 Qt 的元对象系统?
  • 【LeetCode】68. 文本左右对齐
  • 第十九周周报
  • Springboot 常见面试题汇总
  • 驻马店市做网站百度收录软件
  • 在实际项目中,Java 应用的性能瓶颈通常出现在哪些方面,又该如何有效地进行优化?
  • 08_Freqtrade配置与开发环境
  • C++实例
  • 复习总结最终版:Linux驱动
  • Python全栈(基础篇)——Day09:后端内容(列表生成式+生成器+迭代器+实战演示+每日一题)
  • kanass入门到实战(18) - 如何通过仪表盘,快速直观掌握项目进度及度量
  • seo网站优化工具大全wordpress 百度地图api
  • webstorm 调试时不能连接网页
  • 互助网站建设公司网页制作 主流软件
  • 微信公众号登录wordpress网站安徽城乡建设厅网站证件
  • 用wordpress建公司网站步骤郑州橱柜网站建设
  • StringBuffer和StringBuilder的扩容机制
  • 计数 dp
  • 数据结构 实现二叉搜索树与哈希表
  • 深度解析:使用ZIP流式读取大型PPTX文件的最佳实践
  • 商家运营优化:基于京东API返回值的商品管理策略
  • SpringAI+DeepSeek大模型应用开发自用笔记
  • 220kV变电站电气一次系统设计(论文+CAD图纸)
  • 网站快照诊断qq空间 wordpress
  • sql优化思路
  • LeetCode 分类刷题:92. 反转链表 II
  • 视频背景音乐怎么做mp3下载网站wordpress 密码验证失败
  • 医疗区块链:电子病历的零知识证明实现
  • Redis 核心文件、命令与操作指南