MybatisPlus查询更so easy
前言
MybatisPlus已经比Mybatis好用太多了,少了很多模板代码。但是使用多了,总是感觉仍然有很多模板代码要处理。昨天搞了SpringJPA以后,想了想,MybatisPlus也能so easy
现状
如果是普通的eq,直接可以使用Wrappers.query(entity)实现。但是in,between的查询也很常见,仍然需要写一些逻辑
环境
JDK1.8
SpringBoot2.7.11
mybatis-plus-boot-starter3.4.2
mysql-connector-j8.0.33
核心代码
调用queryWrapper方法, 入参为构造的参数对象和实体类型,返回查询条件
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.db.query.Range;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author dzh
* @since 2024/12/30
*/
public class QueryMybatisPlusUtils {
public static <T> QueryWrapper<T> queryWrapper(Object param, Class<T> entityType) {
Field[] fields = FieldUtils.getAllFields(param.getClass());
QueryWrapper<T> qr = Wrappers.query();
try {
for (Field field : fields) {
field.setAccessible(true);
String name = toColumnName(field.getName(), entityType);
Class<?> type = field.getType();
Object value = field.get(param);
if (ObjectUtil.isNotEmpty(value)) {
if (value instanceof Range) {
Range<?> range = (Range<?>) value;
if (ObjectUtils.allNotNull(range.getMinimum(), range.getMaximum())) {
qr.between(name, range.getMinimum(), range.getMaximum());
} else if (range.getMinimum() != null) {
qr.ge(name, range.getMinimum());
} else if (range.getMaximum() != null) {
qr.le(name, range.getMaximum());
}
} else if (type.isPrimitive()) {
qr.eq(name, value);
} else if (value instanceof Collection) {
Collection<?> collection = (Collection<?>) value;
qr.in(name, collection);
} else if (value.getClass().isArray()) {
Collection<?> collection = Arrays.stream(((Object[]) value)).collect(Collectors.toList());
qr.in(name, collection);
}
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return qr;
}
public static String toColumnName(String name, Class<?> type) {
TableInfo tableInfo = TableInfoHelper.getTableInfo(type);
if (tableInfo.getKeyProperty().equals(name)) {
return tableInfo.getKeyColumn();
}
List<TableFieldInfo> fieldList = tableInfo.getFieldList();
return fieldList.stream()
.filter(item -> item.getField().getName().equals(name))
.findAny()
.map(TableFieldInfo::getColumn)
.orElseThrow(() -> new RuntimeException("字段不存在:" + name));
}
}
业务和测试代码
- 测试代码
@Test
void query() {
BookQuery bookQuery = new BookQuery();
QueryWrapper<Book> queryWrapper = QueryMybatisPlusUtils.queryWrapper(bookQuery, Book.class);
System.out.println(queryWrapper);
List<Book> books = bookMapper.selectList(queryWrapper);
System.out.println(books);
}
- Book 实体
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.solr.client.solrj.beans.Field;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import java.time.LocalDate;
import java.util.Date;
/**
* @author dzh
* @since 2024/10/22
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Document("books")
@org.springframework.data.elasticsearch.annotations.Document(indexName = "books")
public class Book {
@Id
@TableId(type = IdType.AUTO)
private Integer id;
private String line;
private Long pid;
private String title;
private Integer age;
private LocalDate publishDay;
private Date createTime;
}
- BookQuery 查询参数
import java.time.LocalDate;
import java.util.Date;
import java.util.List;
/**
* @author dzh
* @since 2024/12/30
*/
@Data
public class BookQuery {
private List<Long> id;
private List<String> title;
private Range<Integer> age;
private Range<LocalDate> publishDay;
private Range<Date> createTime;
}
- Range 辅助区间查询类
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 区间
* @author dzh
* @since 2024/12/31
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Range<T> {
private T minimum;
private T maximum;
public static <T> Range<T> between(T minimum, T maximum) {
return new Range<>(minimum, maximum);
}
}
- BookMapper
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.db.entity.Book;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface BookMapper extends BaseMapper<Book> {
}
总结
这个只是懒人想的懒办法,技术能力有限,后续项目迭代中可以持续优化