赞
踩
MyBatis Plus(简称 MP)是一个流行的 Java ORM 框架 MyBatis 的扩展工具集,致力于简化 MyBatis 的开发工作,尤其是针对日常的 CRUD 操作进行了大幅的优化和增强,同时保持了 MyBatis 的灵活性和可扩展性。以下是 MyBatis Plus 的一些核心特性和详解:
要在 Spring Boot 项目中集成 MyBatis Plus,可以按照以下步骤进行:
在 pom.xml
文件中添加 MyBatis Plus 和 MyBatis 的相关依赖:
<dependencies> <!-- Spring Boot Starter Web 或其他 Starter --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Spring Data JPA 或 JDBC Starter 根据项目需求选择 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jdbc</artifactId> <!-- 或 --> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <!-- MyBatis Plus 依赖 --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>最新版本号</version> </dependency> <!-- MySQL JDBC Driver --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> </dependencies>
在 application.properties
或 application.yml
文件中配置数据库连接信息:
spring.datasource.url=jdbc:mysql://localhost:3306/your_database?serverTimezone=UTC&useSSL=false
spring.datasource.username=root
spring.datasource.password=root_password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
创建一个配置类,用于配置 MyBatis Plus:
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import org.mybatis.spring.annotation.MapperScan; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration @MapperScan("com.example.yourproject.mapper") // 替换为你的Mapper接口所在的包名 public class MybatisPlusConfig { /** * 分页插件 */ @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); return interceptor; } }
创建实体类,继承 com.baomidou.mybatisplus.extension.activerecord.Model
或实现 com.baomidou.mybatisplus.annotation.TableId
等注解:
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
@TableName("your_table_name")
public class YourEntity implements Serializable {
@TableId(type = IdType.AUTO)
private Long id;
// 其他属性和 getter、setter 方法
}
创建对应的 Mapper 接口,继承 com.baomidou.mybatisplus.core.mapper.BaseMapper
:
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface YourEntityMapper extends BaseMapper<YourEntity> {
// 可以在此添加自定义的查询方法
}
创建 Service 类,注入 Mapper,并实现相关业务逻辑;创建 RESTful API 控制器,注入 Service,处理 HTTP 请求。
无侵入设计:
强大的 CRUD 支持:
@TableField(fill = FieldFill.INSERT)
可以在插入时自动填充创建时间和更新时间等字段)。// 定义实体类 User public class User extends Model<User> { private String id; private String name; // 其他属性及 getter/setter 方法... } // 在 Service 层中添加用户 @Service public class UserServiceImpl implements IService<User> { @Autowired private UserMapper userMapper; // 继承自 BaseMapper<User> public boolean addUser(User user) { return userMapper.insert(user) > 0; } }
通过调用 UserMapper
中继承自 BaseMapper
的 insert()
方法,可以插入一条新的用户记录。由于 User 类继承了 Model
类,因此主键(例如ID)会根据配置的主键策略自动处理。
public boolean deleteUserById(String id) {
return userMapper.deleteById(id) > 0;
}
删除操作通过 deleteById()
方法完成,传入待删除记录的主键值即可。
public boolean updateUser(User user) {
return userMapper.updateById(user) > 0;
}
若要根据实体对象全量更新记录,直接调用 updateById()
方法即可。如果只想更新部分字段,可以先调用 update()
方法并配合一个 UpdateWrapper
进行条件筛选后再执行更新。
public User getUserById(String id) {
return userMapper.selectById(id);
}
单个记录的查询可以通过 selectById()
方法完成。
public List<User> getUsersByName(String name) {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getName, name);
return userMapper.selectList(wrapper);
}
对于更复杂的查询,可以利用 LambdaQueryWrapper
或 Wrapper
构造查询条件,然后调用 selectList()
方法获取满足条件的所有记录。
此外,MyBatis Plus 还提供了分页查询、逻辑删除等功能,同样也对增删查改操作进行了进一步的增强和便利化。逻辑删除是指在数据库中并不真正物理删除数据,而是通过标记的方式模拟删除状态,从而实现软删除功能。
条件构造器(Query Wrapper):
Wrapper
Wrapper
是所有条件构造器的父接口,包含两种实现类:QueryWrapper
和 UpdateWrapper
。QueryWrapper
用于构建查询条件,可以应用于 select*
类型的操作。UpdateWrapper
用于构建更新条件,可以应用于 update
类型的操作。Lambda 表达式风格的条件构造器
LambdaQueryWrapper
和 LambdaUpdateWrapper
是 Wrapper 的 lambda 表达式版本,可以直接使用实体类的字段名进行条件构建,更具可读性。示例:
// QueryWrapper 示例 QueryWrapper<User> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("name", "张三") // 等于 .like("email", "%@gmail.com") // 模糊匹配 .gt("age", 18) // 大于 .orderByDesc("create_time"); // 按照创建时间降序排序 List<User> users = userMapper.selectList(queryWrapper); // LambdaQueryWrapper 示例 LambdaQueryWrapper<User> lambdaQuery = new LambdaQueryWrapper<>(); lambdaQuery.eq(User::getName, "张三") .likeRight(User::getEmail, "@gmail.com") .ge(User::getAge, 18) .orderByDesc(User::getCreateTime); List<User> usersByLambda = userMapper.selectList(lambdaQuery);
复杂查询
and
、or
条件。in
、between
、isNull
、isNotNull
等。示例:
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.and(i -> i.eq("status", "active").eq("type", "admin"))
.or(i -> i.like("name", "Tom").like("email", "@qq.com"));
List<User> complexUsers = userMapper.selectList(wrapper);
分组查询与统计函数
groupBy
方法设置分组字段。count
、sum
、avg
、max
、min
等。动态表名、列名:
早期版本中,MyBatis Plus提供了com.baomidou.mybatisplus.core.handlers.TableNameHandler
接口,用户可以自定义实现该接口来处理动态表名。但在后续版本中,MyBatis Plus引入了更多元化的解决方案。
在较新版本的MyBatis Plus中,可以通过全局配置的方式来实现动态表名。例如,可以在实体类上使用@TableName
注解,并在注解中提供一个SpEL表达式或者其他动态计算表名的方法。
@TableField(exist = false)
private String month;
@TableName(value = "`${dynamicTableName(month)}`")
public class User {
// ...
public String getDynamicTableName(String month) {
return "user_" + month;
}
// ...
}
还可以通过扩展SQL解析器的方式实现动态表名,如使用@SqlParser
注解结合@Sql
片段来动态构建SQL语句中的表名。
对于动态列名,MyBatis Plus没有直接提供原生的支持,但可以通过以下方式进行:
在MyBatis中,可以利用动态SQL标签如<if>
、<choose>
、<when>
、<otherwise>
、<set>
等来动态构建SQL中的列名。
<select id="selectByDynamicColumns" resultType="map">
SELECT
<if test="includeName">name,</if>
<if test="includeAge">age,</if>
...
FROM user
</select>
在Mapper的XML文件中编写自定义SQL片段,根据传入的参数动态组装查询字段。
在特殊情况下,如果需要高度动态的列名处理,可能需要自定义映射器接口和对应的XML文件,通过编程方式动态拼接SQL,甚至直接执行自定义的SQL字符串。
总之,虽然MyBatis Plus并未直接提供对动态列名的标准支持,但可以通过MyBatis本身的动态SQL机制以及结合自定义逻辑来达到目的。而对于动态表名,MyBatis Plus提供了更为明确的扩展机制,通过注解或自定义处理器可以轻松实现。务必关注官方文档和最新版本的更新说明,因为随着框架的发展,具体的实现方式可能会有所变化。
主键策略:
分页插件:
启用分页插件:
在 MyBatis Plus 的配置类中,需要启用分页插件并进行必要的配置,例如:
@Configuration
public class MybatisPlusConfig {
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
// 设置请求的页面大于最大页后操作,true表示继续查询(截断查询),false表示直接返回最大页数
paginationInterceptor.setOverflow(false);
// 设置是否采用合理化分页参数,默认true
paginationInterceptor.setReasonable(true);
return paginationInterceptor;
}
}
使用分页查询:
在 Service 层或 DAO 层中,通过 IPage
接口来进行分页查询,例如:
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@Override
public IPage<User> selectPageUsers(IPage<User> page, QueryWrapper<User> queryWrapper) {
return baseMapper.selectPage(page, queryWrapper);
}
}
上述例子中,IPage
是 MyBatis Plus 提供的一个分页接口,包含了分页所需的各项参数,如当前页码、每页大小、总记录数、总页数等。baseMapper
是继承自 BaseMapper
的接口,内部已经集成了分页查询的方法。
传递分页参数:
在 Controller 层,创建 IPage
实例并设置分页参数,然后传递给 Service 层进行查询:
@GetMapping("/users")
public R<IPage<User>> getUsers(@RequestParam Map<String, Object> params) {
Page<User> page = new Page<>(Integer.parseInt(params.get("current").toString()),
Integer.parseInt(params.get("size").toString()));
IPage<User> userPage = userService.selectPageUsers(page, new QueryWrapper<>());
return R.ok(userPage);
}
此处 Page
是 IPage
的实现类,包含了分页请求的当前页码(current)和每页大小(size)。
通过 MyBatis Plus 分页插件,我们可以简单高效地处理数据库分页查询,不仅减少了代码量,而且提高了系统性能。同时,分页插件还支持多种数据库,如MySQL、Oracle、SQLServer等。
代码生成器:
配置:
首先,你需要在项目中创建一个配置文件,例如 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> <!-- 数据库驱动 --> <classPathEntry location="mysql-connector-java-x.x.x.jar"/> <context id="default" targetRuntime="MyBatis3Plus"> <!-- 数据源配置 --> <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/your_database" userId="username" password="password"/> <!-- 默认全局策略配置 --> <plugin type="com.baomidou.mybatisplus.generator.plugins.OptimisticLockerPlugin"/> <plugin type="com.baomidou.mybatisplus.generator.plugins.PaginationPlugin"/> <!-- 其他策略配置... --> <!-- 模型生成配置 --> <javaModelGenerator targetPackage="com.example.model" targetProject="src/main/java"> <!-- 是否去除表前缀 --> <property name="trimPrefix" value="your_table_prefix"/> </javaModelGenerator> <!-- Mapper接口生成配置 --> <mapperGenerator targetPackage="com.example.mapper" targetProject="src/main/java"> <property name="enableSubPackages" value="true"/> <!-- Mapper XML 文件生成位置 --> <property name="mapperXmlLocation" value="src/main/resources/mapper/${tableName}Mapper.xml"/> </mapperGenerator> <!-- Mapper XML 生成配置 --> <sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources"/> <!-- Service 和 Controller 生成配置(如果需要的话) --> <javaClientGenerator type="XMLMAPPER" targetPackage="com.example.service.impl" targetProject="src/main/java"> <property name="enableSubPackages" value="true"/> </javaClientGenerator> <!-- 要生成代码的表 --> <table tableName="your_table_name" domainObjectName="YourClassName" mapperName="YourMapperName" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" /> </context> </generatorConfiguration>
运行代码生成器:
创建一个主类,通过调用 MyBatis Plus Generator 的 API 来执行代码生成任务:
import com.baomidou.mybatisplus.generator.FastAutoGenerator; public class CodeGenerator { public static void main(String[] args) { FastAutoGenerator.create("jdbc:mysql://localhost:3306/your_database", "username", "password") .globalConfig(builder -> { builder.author("Your Name") // 设置作者名 .outputDir("path/to/output"); // 设置输出目录 }) .packageConfig(builder -> { builder.parent("com.example") // 设置父包名 .moduleName("your_module_name"); // 设置模块名 }) .strategyConfig(builder -> { builder.addInclude("your_table_name") // 添加需要生成的表名 .entityBuilder() .enableLombok(); // 启用 Lombok 插件 }) .execute(); // 执行生成代码 } }
如果你使用的是较新版本的 MyBatis Plus,推荐使用 FastAutoGenerator
进行快速配置和生成,其简化了原生 XML 配置文件的方式,提供了更为简洁的 Java API 使用方式。
执行与检查:
运行上述主类中的 main
方法,MyBatis Plus 代码生成器会读取配置,并根据数据库表结构生成相应的 Java 类及 XML 文件。检查生成的代码,确保它们符合预期,并将其整合到你的项目中。
性能分析插件:
以下是启用 MyBatis Plus 性能分析插件的一般步骤:
MybatisPlusConfig
)中添加 PerformanceInterceptor
的 Bean 定义,并通过 @Profile
注解指定只在特定环境下启用,比如开发环境(“dev”)和测试环境(“test”):import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; @Configuration public class MybatisPlusConfig { @Bean @Profile({"dev", "test"}) public PerformanceInterceptor performanceInterceptor() { PerformanceInterceptor interceptor = new PerformanceInterceptor(); // 可以设置最大执行时长阈值,超过这个时长的 SQL 将会被记录下来 interceptor.setMaxTime(500); return interceptor; } }
maxTime
属性来定义 SQL 执行的最大允许时长,超过这个时长的 SQL 将被拦截并记录。当启用性能分析插件后,每次执行 SQL 查询时,MyBatis Plus 将在控制台输出相关的 SQL 语句以及其执行所花费的时间。这有助于开发者了解应用中哪些 SQL 查询可能是性能瓶颈,并据此进行优化。
除了 MyBatis Plus 自带的性能分析插件外,还可以选择集成第三方组件如 P6Spy,它也能够提供类似的 SQL 打印和性能监控功能,并且可以和其他数据访问框架配合使用。不过,具体如何配置和使用这些插件,请查阅相应版本的官方文档获取最新信息。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。