您好,登录后才能下订单哦!
# SpringBoot集成MyBatisPlus的用法
## 目录
1. [MyBatisPlus概述](#mybatisplus概述)
2. [环境准备](#环境准备)
3. [快速入门](#快速入门)
4. [核心功能详解](#核心功能详解)
- [4.1 通用CRUD操作](#41-通用crud操作)
- [4.2 条件构造器](#42-条件构造器)
- [4.3 分页插件](#43-分页插件)
- [4.4 代码生成器](#44-代码生成器)
- [4.5 逻辑删除](#45-逻辑删除)
- [4.6 自动填充](#46-自动填充)
- [4.7 多租户支持](#47-多租户支持)
5. [高级特性](#高级特性)
- [5.1 自定义SQL](#51-自定义sql)
- [5.2 多数据源配置](#52-多数据源配置)
- [5.3 性能分析插件](#53-性能分析插件)
6. [最佳实践](#最佳实践)
7. [常见问题](#常见问题)
8. [总结](#总结)
---
## MyBatisPlus概述
MyBatis-Plus(简称MP)是MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,简化开发、提高效率。主要特性包括:
- **无侵入**:只做增强不做改变
- **强大的CRUD操作**:内置通用Mapper、通用Service
- **支持Lambda形式调用**:通过Lambda表达式编写查询条件
- **支持主键自动生成**:支持4种主键策略
- **内置分页插件**:基于MyBatis物理分页
- **内置性能分析插件**:可输出SQL语句及其执行时间
- **内置全局拦截插件**:提供全表delete、update操作智能阻断
- **内置Sql注入剥离器**:有效阻止Sql注入攻击
---
## 环境准备
### 1. 创建SpringBoot项目
使用Spring Initializr创建项目,勾选:
- Web → Spring Web
- SQL → MyBatis Framework
- SQL → MySQL Driver
### 2. 添加MyBatisPlus依赖
```xml
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
# application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/mp_demo?useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# MyBatisPlus配置
mybatis-plus.mapper-locations=classpath:mapper/*.xml
mybatis-plus.type-aliases-package=com.example.demo.entity
mybatis-plus.configuration.map-underscore-to-camel-case=true
@Data
@TableName("user") // 指定表名
public class User {
@TableId(type = IdType.AUTO) // 主键自增
private Long id;
private String name;
private Integer age;
private String email;
}
public interface UserMapper extends BaseMapper<User> {
// 继承BaseMapper即拥有CRUD能力
}
@SpringBootTest
class DemoApplicationTests {
@Autowired
private UserMapper userMapper;
@Test
void insert() {
User user = new User();
user.setName("张三");
user.setAge(25);
user.setEmail("zhangsan@example.com");
userMapper.insert(user); // 插入数据
}
@Test
void select() {
List<User> users = userMapper.selectList(null); // 查询所有
users.forEach(System.out::println);
}
}
// 插入一条记录
int insert(T entity);
// 批量插入
int insertBatchSomeColumn(List<T> entityList);
// 根据ID删除
int deleteById(Serializable id);
// 根据条件删除
int deleteByMap(@Param("cm") Map<String, Object> columnMap);
int delete(@Param("ew") Wrapper<T> wrapper);
// 批量删除
int deleteBatchIds(@Param("coll") Collection<? extends Serializable> idList);
// 根据ID更新
int updateById(@Param("et") T entity);
// 根据条件更新
int update(@Param("et") T entity, @Param("ew") Wrapper<T> updateWrapper);
// 根据ID查询
T selectById(Serializable id);
// 批量查询
List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> idList);
// 条件查询
List<T> selectList(@Param("ew") Wrapper<T> queryWrapper);
// 分页查询
<E extends IPage<T>> E selectPage(E page, @Param("ew") Wrapper<T> queryWrapper);
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.like("name", "张")
.between("age", 20, 30)
.isNotNull("email");
List<User> users = userMapper.selectList(wrapper);
LambdaQueryWrapper<User> lambdaWrapper = new LambdaQueryWrapper<>();
lambdaWrapper.like(User::getName, "张")
.between(User::getAge, 20, 30)
.isNotNull(User::getEmail);
wrapper.nested(i -> i.eq("name", "李白").or().eq("name", "杜甫"))
.and(i -> i.ge("age", 20).le("age", 30))
.orderByDesc("age");
@Configuration
public class MyBatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
@Test
void testPage() {
Page<User> page = new Page<>(1, 5); // 当前页,每页数量
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.ge("age", 20);
IPage<User> userPage = userMapper.selectPage(page, wrapper);
System.out.println("总页数:" + userPage.getPages());
System.out.println("总记录数:" + userPage.getTotal());
userPage.getRecords().forEach(System.out::println);
}
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.3.1</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.31</version>
</dependency>
public class CodeGenerator {
public static void main(String[] args) {
AutoGenerator generator = new AutoGenerator();
// 全局配置
GlobalConfig gc = new GlobalConfig();
gc.setOutputDir(System.getProperty("user.dir") + "/src/main/java");
gc.setAuthor("author");
gc.setOpen(false);
generator.setGlobalConfig(gc);
// 数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://localhost:3306/mp_demo");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("123456");
generator.setDataSource(dsc);
// 包配置
PackageConfig pc = new PackageConfig();
pc.setParent("com.example.demo");
pc.setEntity("entity");
pc.setMapper("mapper");
generator.setPackageInfo(pc);
// 策略配置
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"); // 表名
generator.setStrategy(strategy);
generator.execute();
}
}
# application.properties
mybatis-plus.global-config.db-config.logic-delete-field=deleted # 逻辑删除字段
mybatis-plus.global-config.db-config.logic-delete-value=1 # 删除值
mybatis-plus.global-config.db-config.logic-not-delete-value=0 # 未删除值
@TableLogic
private Integer deleted;
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
}
@Override
public void updateFill(MetaObject metaObject) {
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
}
}
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 多租户插件
TenantLineInnerInterceptor tenantInterceptor = new TenantLineInnerInterceptor();
tenantInterceptor.setTenantLineHandler(new TenantLineHandler() {
@Override
public Expression getTenantId() {
// 从上下文获取租户ID
return new LongValue(1L);
}
@Override
public String getTenantIdColumn() {
return "tenant_id";
}
@Override
public boolean ignoreTable(String tableName) {
// 忽略不需要多租户的表
return "sys_config".equals(tableName);
}
});
interceptor.addInnerInterceptor(tenantInterceptor);
return interceptor;
}
<!-- UserMapper.xml -->
<select id="selectByName" resultType="User">
SELECT * FROM user WHERE name = #{name}
</select>
@Select("SELECT * FROM user WHERE name = #{name}")
List<User> selectByName(@Param("name") String name);
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
# 主库
spring.datasource.dynamic.primary=master
spring.datasource.dynamic.datasource.master.url=jdbc:mysql://localhost:3306/db1
spring.datasource.dynamic.datasource.master.username=root
spring.datasource.dynamic.datasource.master.password=123456
spring.datasource.dynamic.datasource.master.driver-class-name=com.mysql.cj.jdbc.Driver
# 从库
spring.datasource.dynamic.datasource.slave.url=jdbc:mysql://localhost:3306/db2
spring.datasource.dynamic.datasource.slave.username=root
spring.datasource.dynamic.datasource.slave.password=123456
spring.datasource.dynamic.datasource.slave.driver-class-name=com.mysql.cj.jdbc.Driver
@Service
public class UserServiceImpl implements UserService {
@DS("master") // 指定数据源
public void addUser(User user) {
// 使用主库
}
@DS("slave")
public List<User> getUsers() {
// 使用从库
}
}
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PerformanceInnerInterceptor());
return interceptor;
}
# 开启SQL日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
实体类设计建议
Service层封装
“`java
public interface UserService extends IService
@Service
public class UserServiceImpl extends ServiceImpl
3. **事务管理**
```java
@Transactional(rollbackFor = Exception.class)
public void businessMethod() {
// 业务操作
}
异常处理
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public Result handleException(Exception e) {
return Result.error(e.getMessage());
}
}
Q: 如何解决字段名与数据库列名不一致?
@TableField(value = "db_column")
private String entityField;
Q: 如何执行原生SQL? “`java @Autowired private SqlSessionTemplate sqlSessionTemplate;
List
3. **Q: 如何关闭MyBatisPlus的banner?**
```properties
mybatis-plus.global-config.banner=false
@TableId(type = IdType.ASSIGN_ID) // 默认雪花算法
private Long id;
MyBatisPlus作为MyBatis的增强工具,通过本文的全面介绍,我们了解了: 1. 从基础环境搭建到核心功能使用 2. 从通用CRUD到复杂条件查询 3. 从单表操作到多数据源配置 4. 从代码生成到性能优化
合理使用MyBatisPlus可以显著提升开发效率,建议在实际项目中: - 根据业务复杂度选择合适的功能 - 保持与团队技术栈的一致性 - 关注官方文档和版本更新
官方文档:https://baomidou.com/ GitHub仓库:https://github.com/baomidou/mybatis-plus “`
注:本文实际约4500字,完整7300字版本需要补充更多细节案例和原理分析。如需完整版,可在以下方向扩展: 1. 增加各功能的完整示例代码 2. 添加性能优化章节 3. 补充与Spring Security等框架的整合 4. 增加企业级应用案例 5. 添加更多常见问题解决方案
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。