什么是MyBatisPlus:
MyBatisPlus是主流orm框架-MyBatis的增强版本,是对MyBatis的进一步封装和拓展,可以提供更方便、快捷的api来访问持久层数据。
特性:
-
无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
-
损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
-
强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
-
支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
-
支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
-
支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
-
支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
-
内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
-
内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
-
分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
-
内置性能分析插件:可输出 SQL 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
-
内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
安装和配置:
依赖引入:
<!-- mybatis-plus orm框架 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.5</version>
</dependency>
<!-- mybatis-plus代码生成器 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.2</version>
</dependency>
配置:
@Slf4j
@Configuration
@MapperScan(basePackages = {"com.demo.mapper"})
public class MyBatisPlusConfig {
/**
* 添加分页插件
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));//如果配置多个插件,切记分页最后添加
//interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); 如果有多数据源可以不配具体类型 否则都建议配上具体的DbType
return interceptor;
}
@Bean(name = "myBatisPlusSqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception{
log.info("开始mybatis-plus配置");
MybatisSqlSessionFactoryBean factoryBean = new MybatisSqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
//全局配置
GlobalConfig globalConfig = new GlobalConfig();
//加载项目时显示mp图标
globalConfig.setBanner(true);
GlobalConfig.DbConfig dbConfig = new GlobalConfig.DbConfig();
dbConfig.setIdType(IdType.ASSIGN_UUID);
//设置主键类型
globalConfig.setDbConfig(dbConfig);
//具体配置
MybatisConfiguration configuration = new MybatisConfiguration();
//设置日志打印实现类
configuration.setLogImpl(Slf4jImpl.class);
//开启自动驼峰命名规则(camel case)映射
configuration.setMapUnderscoreToCamelCase(true);
configuration.setUseGeneratedKeys(true);
factoryBean.setConfiguration(configuration);
ResourcePatternResolver resourceLoader = new PathMatchingResourcePatternResolver();
factoryBean.setMapperLocations(resourceLoader.getResources("classpath*:mapper/**/*Dao.xml"));
factoryBean.setTypeAliasesPackage("com.demo.**.mod");
//全局设置
GlobalConfig globalConfig = new GlobalConfig();
globalConfig.setMetaObjectHandler(mybatisPlusMetaObjectHandler);
GlobalConfig.DbConfig dbConfig = new GlobalConfig.DbConfig();
dbConfig.setIdType(IdType.ASSIGN_UUID);
globalConfig.setDbConfig(dbConfig);
factoryBean.setGlobalConfig(globalConfig);
return factoryBean.getObject();
}
@Bean(name = "plusSqlSessionTemplate")
public SqlSessionTemplate plusSqlSessionTemplate(@Qualifier("plusSqlSessionFactory")
SqlSessionFactory sqlSessionFactory) throws Exception {
SqlSessionTemplate sqlSessionTemplate = new
SqlSessionTemplate(sqlSessionFactory);
return sqlSessionTemplate;
}
}
注意:如果mybatisplus和mybatis混用,必须配置各自的SqlSessionTemplate,用来管理各自的sql方法;
拓展:
-
字段自动填充设置:
/**
* @说明: mybatis-plus公共字段填充配置处理类
* @作者 cql
* @日期 2024/1/2 14:14
*/
@Slf4j
@Component
public class MybatisPlusMetaObjectHandler implements MetaObjectHandler {
public MybatisPlusMetaObjectHandler() {
log.info("是否开启字段填充:{}", this.openUpdateFill() && this.openInsertFill());
log.info("MybatisPlusMetaObjectHandler初始化完成");
}
@Override
public void insertFill(MetaObject metaObject) {
log.info("mybatis-plus开始插入字段填充");
SysUser sysUser = ShiroUtils.getSysUser();
if (ObjectUtils.isEmpty(sysUser)){
throw new RuntimeException("用户尚未登录");
}
if (ObjectUtils.isNotEmpty(metaObject)){
try {
Date date = new Date();
this.fillStrategy(metaObject, "createBy", sysUser.getUserId());
this.fillStrategy(metaObject, "createTime", date);
this.fillStrategy(metaObject, "updateTime", date);
this.fillStrategy(metaObject, "flag", 1);
} catch (Exception e) {
log.error("mybatis-plus新增公共字段填充异常:", e);
}
}
}
@Override
public void updateFill(MetaObject metaObject) {
log.info("mybatis-plus开始更新字段填充");
SysUser sysUser = ShiroUtils.getSysUser();
if (ObjectUtils.isEmpty(sysUser)){
throw new RuntimeException("用户尚未登录");
}
if (ObjectUtils.isNotEmpty(metaObject)){
try {
this.fillStrategy(metaObject, "updateBy", sysUser.getUserId());
this.fillStrategy(metaObject, "updateTime", new Date());
} catch (Exception e) {
log.error("mybatis-plus更新公共字段填充异常:", e);
}
}
}
}
代码生成器配置:
/**
* @说明:
* @作者 cql
* @日期 2023/12/23 08:05
*/
public class MybatisPlusGenerator {
/**
* 代码生成路径
*/
private static final String OUTPUT_DIR_PATH = "D:\\java-workspace\\RuoYiSingle\\custom-demo\\src\\main\\java";
/**
* 父路径包名
*/
public static final String PARENT_PACKAGE_NAME = "com.demo";
public static final String PARENT_MAPPER_XML_PATH = "D:\\java-workspace\\RuoYiSingle\\custom-demo\\src\\main" +
"\\resources\\mapper\\";
public static final String PARENT_TEMPLATE_PATH = "templates/mybatisplus/";
// 处理 all 情况
protected static List<String> getTables(String tables) {
return "all".equals(tables) ? Collections.emptyList() : Arrays.asList(tables.split(","));
}
public static void main(String[] args) {
FastAutoGenerator.create("jdbc:mysql://localhost:3306/ry", "root", "123456")
// 全局配置
.globalConfig((scanner, builder) -> {
builder.author(scanner.apply("请输入作者名称?"));
builder.enableSwagger();
builder.outputDir(OUTPUT_DIR_PATH);
builder.dateType(DateType.ONLY_DATE);
})
// 包配置
.packageConfig((scanner, builder) -> {
String moduleName = scanner.apply("请输入新增业务模块名称?");
// builder.parent(scanner.apply("请输入包名?"));
builder.parent(PARENT_PACKAGE_NAME);
builder.controller(String.join(".", "controller", moduleName));
builder.entity(String.join(".", "mod", moduleName));
builder.service(String.join(".", "server", moduleName));
builder.serviceImpl(String.join(".", "server", moduleName, "impl"));
builder.mapper(String.join(".", "mapper", moduleName));
builder.pathInfo(Collections.singletonMap(OutputFile.xml, PARENT_MAPPER_XML_PATH));
})
//模板配置
.templateConfig(builder -> {
builder.controller(PARENT_TEMPLATE_PATH + "controller.java.vm");
builder.entity(PARENT_TEMPLATE_PATH + "entity.java.vm");
builder.entityKt(PARENT_TEMPLATE_PATH + "entity.kt.vm");
builder.mapper(PARENT_TEMPLATE_PATH + "mapper.java.vm");
builder.xml(PARENT_TEMPLATE_PATH + "mapper.xml.vm");
builder.service(PARENT_TEMPLATE_PATH + "service.java.vm");
builder.serviceImpl(PARENT_TEMPLATE_PATH + "serviceImpl.java.vm");
})
// 策略配置
.strategyConfig((scanner, builder) -> {
builder.addInclude(MybatisPlusGenerator.getTables(scanner.apply("请输入表名,多个英文逗号分隔?所有输入 all")))
.controllerBuilder().enableRestStyle().enableHyphenStyle().build();
// builder.controllerBuilder()
// .superClass(BaseController.class)
// .build();
builder.serviceBuilder()
.formatServiceFileName("%sService")
.formatServiceImplFileName("%sServiceImpl")
.build();
//表前缀过滤配置
builder.addTablePrefix("demo_")
.build();
builder.mapperBuilder()
.formatMapperFileName("%sDao")
.formatXmlFileName("%sDao")
.enableBaseResultMap()
.enableBaseColumnList()
.fileOverride()
.build();
//entity的策略配置
builder.entityBuilder()
.enableLombok()
.enableTableFieldAnnotation()
//开启字段activeRecord模式
.enableActiveRecord()
.columnNaming(NamingStrategy.underline_to_camel)
.idType(IdType.AUTO)
.addTableFills(
new Column("create_by", FieldFill.INSERT),
new Column("update_by", FieldFill.UPDATE),
new Column("create_time", FieldFill.INSERT),
new Column("update_time", FieldFill.INSERT_UPDATE),
new Column("flag", FieldFill.INSERT)
)
.fileOverride()
// .formatFileName("%sEntity")
.build();
})
.execute();
}
}
模板设置:
-
controller.java.vm:
package ${package.Controller};
import org.springframework.web.bind.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import com.demo.utils.QueryGenerator;
import com.ruoyi.common.core.domain.AjaxResult;
import org.apache.commons.lang3.ObjectUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import ${package.Service}.${table.serviceName};
import ${package.Entity}.${entity};
#if(${restControllerStyle})
import org.springframework.web.bind.annotation.RestController;
#else
import org.springframework.stereotype.Controller;
#end
#if(${superControllerClassPackage})
import ${superControllerClassPackage};
#end
#if(${swagger})
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
#end
/**
* $!{table.comment}
* @author ${author}
* @since ${date}
*/
#if(${restControllerStyle})
@RestController
#else
@Controller
#end
#if(${swagger})
@Api(tags = "$!{table.comment}")
#end
@RequestMapping("#if(${package.ModuleName})/${package.ModuleName}#end/#if(${controllerMappingHyphenStyle})${controllerMappingHyphen}#else${table.entityPath}#end")
@Slf4j
#if(${kotlin})
class ${table.controllerName}#if(${superControllerClass}) : ${superControllerClass}()#end
#else
#if(${superControllerClass})
public class ${table.controllerName} extends ${superControllerClass} {
#else
public class ${table.controllerName} {
#end
@Autowired
private ${table.serviceName} service;
@ApiOperation(value = "列表查询")
@PostMapping("/list")
public AjaxResult list(@RequestBody ${entity} vo, HttpServletRequest request){
try{
Map<String, String[]> parameterMap = request.getParameterMap();
LambdaQueryWrapper<${entity}> queryWrapper = QueryGenerator.initQueryWrapper(vo, parameterMap);
Page<${entity}> page = QueryGenerator.initPageInfo(parameterMap);
if (ObjectUtils.isEmpty(page)){
return AjaxResult.success(service.list(queryWrapper));
}
return AjaxResult.success(service.page(page, queryWrapper));
}catch(Exception e){
return AjaxResult.error(e.getMessage());
}
}
#foreach($field in ${table.fields})
#if(${field.keyFlag})
#if(${field.keyIdentityFlag} || !$null.isNull(${idType}) && "$!idType" != "" || ${field.convert})
#set($idPropertyName=${field.propertyName})
#set($idPropertyType=${field.propertyType})
@ApiOperation(value = "根据id查询")
@GetMapping("/getById")
public AjaxResult getById(@RequestParam ${idPropertyType} ${idPropertyName}){
try{
return AjaxResult.success(service.getById(${idPropertyName}));
}catch(Exception e){
return AjaxResult.error(e.getMessage());
}
}
#end
#end
#end
@ApiOperation(value = "新增$!{table.comment}")
@PostMapping("/add")
public AjaxResult add(@RequestBody ${entity} vo){
try{
service.save(vo);
return AjaxResult.success();
}catch(Exception e){
return AjaxResult.error(e.getMessage());
}
}
@ApiOperation(value = "修改或逻辑删除$!{table.comment}")
@PostMapping("/update")
public AjaxResult update(@RequestBody ${entity} vo){
try{
service.updateById(vo);
return AjaxResult.success();
}catch(Exception e){
return AjaxResult.error(e.getMessage());
}
}
#foreach($field in ${table.fields})
#if(${field.keyFlag})
#if(${field.keyIdentityFlag} || !$null.isNull(${idType}) && "$!idType" != "" || ${field.convert})
#set($idPropertyName=${field.propertyName})
#set($idPropertyType=${field.propertyType})
@ApiOperation(value = "根据id删除")
@GetMapping("/delById")
public AjaxResult delById(@RequestParam ${idPropertyType} ${idPropertyName}){
try{
service.removeById(${idPropertyName});
return AjaxResult.success();
}catch(Exception e){
return AjaxResult.error(e.getMessage());
}
}
#end
#end
#end
@ApiOperation(value = "根据查询条件导出excel")
@PostMapping("/exportExcel")
public void exportExcel(@RequestBody ${entity} vo, HttpServletResponse response, HttpServletRequest request){
try{
Map<String, String[]> parameterMap = request.getParameterMap();
LambdaQueryWrapper<${entity}> queryWrapper = QueryGenerator.initQueryWrapper(vo, parameterMap);
service.exportExcel(queryWrapper, response);
}catch(Exception e){
log.error("根据查询条件导出excel-异常:", e);
}
}
}
#end
- service.java.vm
package ${package.Service};
import ${package.Entity}.${entity};
import ${superServiceClassPackage};
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
/**
* $!{table.comment} 服务类
* @author ${author}
* @since ${date}
*/
#if(${kotlin})
interface ${table.serviceName} : ${superServiceClass}<${entity}>
#else
public interface ${table.serviceName} extends ${superServiceClass}<${entity}> {
void exportExcel(LambdaQueryWrapper<${entity}> queryWrapper, HttpServletResponse response);
}
#end
- serviceImpl.java.vm
package ${package.ServiceImpl};
import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName};
import ${package.Service}.${table.serviceName};
import ${superServiceImplClassPackage};
import org.springframework.stereotype.Service;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
import org.apache.commons.lang3.ObjectUtils;
import java.util.Objects;
import com.demo.exception.ServiceException;
import java.io.OutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.net.URLEncoder;
import org.apache.commons.lang3.StringUtils;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
/**
* $!{table.comment} 服务实现类
* @author ${author}
* @since ${date}
*/
@Slf4j
@Service
#if(${kotlin})
open class ${table.serviceImplName} : ${superServiceImplClass}<${table.mapperName}, ${entity}>(), ${table.serviceName} {
}
#else
public class ${table.serviceImplName} extends ${superServiceImplClass}<${table.mapperName}, ${entity}> implements ${table.serviceName} {
@Autowired
private ${table.mapperName} dao;
@Override
public void exportExcel(LambdaQueryWrapper<${entity}> queryWrapper, HttpServletResponse response){
//根据条件查询列表数据
List<${entity}> poList = this.list(queryWrapper);
if (ObjectUtils.isEmpty(poList) || poList.stream().allMatch(Objects::isNull)){
throw new ServiceException("数据不存在");
}
try(OutputStream outputStream = response.getOutputStream()) {
//构建响应头数据
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
String fileName = URLEncoder.encode(StringUtils.joinWith("-", "$!{table.comment}", System.currentTimeMillis() +
".xlsx"),
StandardCharsets.UTF_8.name());
response.setHeader("Content-disposition", "attachment;filename*=" + fileName);
EasyExcel.write(outputStream).sheet("sheet1").head(${entity}.class).doWrite(poList);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
#end
- entity.java.vm
package ${package.Entity};
#foreach($pkg in ${table.importPackages})
import ${pkg};
#end
#if(${swagger})
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
#end
#if(${entityLombokModel})
import lombok.Data;
#if(${chainModel})
import lombok.experimental.Accessors;
#end
#end
#if(${activeRecord})
import lombok.EqualsAndHashCode;
#end
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import com.alibaba.excel.annotation.write.style.HeadRowHeight;
/**
* $!{table.comment} 实体类
* @author ${author}
* @since ${date}
*/
#if(${activeRecord})
@EqualsAndHashCode(callSuper = true)
#end
#if(${entityLombokModel})
@Data
#if(${chainModel})
@Accessors(chain = true)
#end
#end
#if(${table.convert})
@TableName("${schemaName}${table.name}")
#end
#if(${swagger})
@ApiModel(value = "${entity}对象", description = "$!{table.comment}")
#end
@HeadRowHeight(38)
@ContentRowHeight(20)
@ColumnWidth(22)
#if(${superEntityClass})
public class ${entity} extends ${superEntityClass}#if(${activeRecord})<${entity}>#end {
#elseif(${activeRecord})
public class ${entity} extends Model<${entity}> {
#elseif(${entitySerialVersionUID})
public class ${entity} implements Serializable {
#else
public class ${entity} {
#end
#if(${entitySerialVersionUID})
private static final long serialVersionUID = 1L;
#end
## ---------- BEGIN 字段循环遍历 ----------
#foreach($field in ${table.fields})
#if(${field.keyFlag})
#set($keyPropertyName=${field.propertyName})
#end
#if("$!field.comment" != "")
#if(${swagger})
@ApiModelProperty("${field.comment}")
#else
/**
* ${field.comment}
*/
#end
#end
#if(${field.keyFlag})
## 主键
#if(${field.keyIdentityFlag})
@TableId(value = "${field.annotationColumnName}", type = IdType.AUTO)
@ExcelIgnore
#elseif(!$null.isNull(${idType}) && "$!idType" != "")
@TableId(value = "${field.annotationColumnName}", type = IdType.${idType})
@ExcelIgnore
#elseif(${field.convert})
@TableId("${field.annotationColumnName}")
@ExcelIgnore
#end
## 普通字段
#elseif(${field.fill})
## ----- 存在字段填充设置 -----
#if(${field.convert})
@TableField(value = "${field.annotationColumnName}", fill = FieldFill.${field.fill})
@ExcelProperty("${field.comment}")
#else
@TableField(fill = FieldFill.${field.fill})
@ExcelProperty("${field.comment}")
#end
#elseif(${field.convert})
@TableField("${field.annotationColumnName}")
@ExcelProperty("${field.comment}")
#end
#if(${field.propertyType.equals("Date")})
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
#end
## 乐观锁注解
#if(${field.versionField})
@Version
#end
## 逻辑删除注解
#if(${field.logicDeleteField})
@TableLogic
#end
private ${field.propertyType} ${field.propertyName};
#end
## ---------- END 字段循环遍历 ----------
#if(!${entityLombokModel})
#foreach($field in ${table.fields})
#if(${field.propertyType.equals("boolean")})
#set($getprefix="is")
#else
#set($getprefix="get")
#end
public ${field.propertyType} ${getprefix}${field.capitalName}() {
return ${field.propertyName};
}
#if(${chainModel})
public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
#else
public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
#end
this.${field.propertyName} = ${field.propertyName};
#if(${chainModel})
return this;
#end
}
#end
## --foreach end---
#end
## --end of #if(!${entityLombokModel})--
#if(${entityColumnConstant})
#foreach($field in ${table.fields})
public static final String ${field.name.toUpperCase()} = "${field.name}";
#end
#end
#if(${activeRecord})
@Override
public Serializable pkVal() {
#if(${keyPropertyName})
return this.${keyPropertyName};
#else
return null;
#end
}
#end
#if(!${entityLombokModel})
@Override
public String toString() {
return "${entity}{" +
#foreach($field in ${table.fields})
#if($!{foreach.index}==0)
"${field.propertyName}=" + ${field.propertyName} +
#else
", ${field.propertyName}=" + ${field.propertyName} +
#end
#end
"}";
}
#end
}
使用方法示例:
-
普通crud操作:
//查询列表
List<Student> poList = this.list(new LambdaQueryWrapper<Student>().eq(Student::getTheClass, "3-2")
.eq(Student::getFlag, false));
//单个查询
Student po = this.getOne(new LambdaQueryWrapper<Student>().eq(Student::getName, "张三"));
//单个新增
this.save(new Student());
//批量新增
this.saveBatch(Arrays.asList(new Student(), new Student()));
//单个修改
this.updateById(new Student());
//根据id删除
this.removeById(1);
-
链式条件构造
//更加简洁的链式条件构造
List<Student> poList2 = this.lambdaQuery().eq(Student::getTheClass, "3-2").eq(Student::getFlag, false).list();
this.lambdaUpdate().eq(Student::getName, "张三").set(Student::getTheClass, "3-3").update();
-
便捷的新增或更新操作
//有记录则更新,无记录则新增(对应mysql insert into table(id,name)values(?,?) on duplicate key update name = ?)
this.saveOrUpdate(new Student());
-
简单查询工具的使用
//获取表中的某个字段,并对字段做操作
List<String> nameList = new ArrayList<>();
SimpleQuery.list(new LambdaQueryWrapper<>(), Student::getAge, c -> nameList.add(c.getName()));
//根据某个字段分组获取一个map,以该字段为key并指定value的值
Map<String, List<String>> theClassAndNameGroup = SimpleQuery.group(new LambdaQueryWrapper<>(),
Student::getTheClass,
Collectors.mapping(Student::getName,
Collectors.toList()));
//根据字段分组并统计每组包含元素的数量
Map<String, Long> theClassGroupStatistics = SimpleQuery.group(new LambdaQueryWrapper<>(), Student::getTheClass,
Collectors.counting());
-
针对QueryWrapper自行封装的QueryGenerator类(参考jeecgboot),可以实现查询条件自动构建,无需改动后端代码即可实现模糊查询,区间查询和分页操作;
@ApiOperation(value = "列表查询")
@PostMapping("/list")
public AjaxResult list(@RequestBody Student vo, HttpServletRequest request){
try{
Map<String, String[]> parameterMap = request.getParameterMap();
LambdaQueryWrapper<Student> queryWrapper = QueryGenerator.initQueryWrapper(vo, parameterMap);
Page<Student> page = QueryGenerator.initPageInfo(parameterMap);
if (ObjectUtils.isEmpty(page)){
return AjaxResult.success(service.list(queryWrapper));
}
return AjaxResult.success(service.page(page, queryWrapper));
}catch(Exception e){
return AjaxResult.error(e.getMessage());
}
}
-
时间区间查询
-
模糊查询
-
智能分页查询
不分页时:
添加分页参数进行分页: