【SpringBoot专题】整合mybatis-plus之封装查询参数简化查询
![在这里插入图片描述](https://img-blog.csdnimg.cn/20191107115439578.jpeg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3MzYyODkx,size_16,color_FFFFFF,t_70)
通常开发过程中,操作数据库是作为后端开发必要掌握的本领,今天分享的是springboot整合mybatis-plus,官网上也有很多栗子,今天整合不是重点,重点是小B今天造了个轮子,想写成博客分享出来。
项目中需要引入pom依赖,如下:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatisplus-spring-boot-starter</artifactId>
<version>1.0.5</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>${mybatisplus.version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatisplus.version}</version>
</dependency>
<!-- MySQL Connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.6</version>
</dependency>
接着就是配置,我们可以用yml配置(仅仅是自己的爱好)
mybatis-plus:
mapper-locations: classpath*:/mapper/**/*.xml # 你的mapper sql文件位置
type-aliases-package: fast.cloud.nacos.mybatis.entity # mybatis 扫遍实体类的位置
configuration:
map-underscore-to-camel-case: true # 驼峰配置
#配置数据源
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/demo?useUnicode=true&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf8
username: root
password: root
# 打印sql配置
logging:
level:
fast.cloud.nacos.mybatis.mapper: debug
#pagehelper 配置
pagehelper:
helper-dialect: mysql
reasonable: false
support-methods-arguments: ture
params: count=countSql
创建实体类,mapper接口,以及mapper.xml文件,自己可以写一个test类测试,具体代码后面会分享github地址。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20191107113418987.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3MzYyODkx,size_16,color_FFFFFF,t_70)
下面要说的就是今天的重点了我们通常在查询的时候通常会写如下的代码:
QueryWrapper<DemoEntity> queryWrapper = new QueryWrapper<>();
queryWrapper.eq();
queryWrapper.lt();
queryWrapper.like();
.....还有很多查询条件,有时候还要加上参数的非空判断,很繁琐。
于是就造了一个轮子,能不能把这些查询条件给抽取出来呢,先给一个代码,就是封装的一个工具类,下面的代码思想就是,想把这些查询条件封装到一个类里面。
public class MyBaseRequest<T> extends CommonSearchRequest<T> {
public <ENTITY> QueryWrapper<ENTITY> getQuery(Class<ENTITY> entityClass) {
QueryWrapper<ENTITY> queryWrapper = new QueryWrapper<>();
//添加sort
if (this != null && this.getSortBy() != null) {
queryWrapper.orderBy(true, this.getSortBy().getDirection() == 1 ? true : false, this.getSortBy().getField());
}
MyBaseRequest request = this;
if (request.getCondition() == null) {
return queryWrapper;
}
Class clazz = request.getCondition().getClass();
//获取查询类Query的所有字段,包括父类字段
List<Field> fields = getAllFieldsWithRoot(clazz);
for (Field field : fields) {
//获取字段上的@QueryWord注解
QueryCondition qw = field.getAnnotation(QueryCondition.class);
if (qw == null) {
continue;
}
// 获取字段名
String column = qw.column();
//如果主注解上colume为默认值"",则以field为准
if (column.equals("")) {
column = field.getName();
}
field.setAccessible(true);
try {
Object value = field.get(request.getCondition());
//如果值为null,注解未标注nullable,跳过
if (value == null && !qw.nullable()) {
continue;
}
// can be empty
if (value != null && String.class.isAssignableFrom(value.getClass())) {
String s = (String) value;
//如果值为"",且注解未标注emptyable,跳过
if (s.equals("") && !qw.emptyable()) {
continue;
}
}
//通过注解上func属性,构建路径表达式
column = UnderlineToHump(column);
switch (qw.func()) {
case equal:
queryWrapper.eq(column, value);
break;
case like:
queryWrapper.like(column, "%" + value + "%");
break;
case gt:
queryWrapper.gt(column, value);
break;
case lt:
queryWrapper.lt(column, value);
break;
case ge:
queryWrapper.ge(column, value);
break;
case le:
queryWrapper.le(column, value);
break;
case notEqual:
queryWrapper.ne(column, value);
break;
case notLike:
queryWrapper.notLike(column, "%" + value + "%");
break;
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return queryWrapper;
}
public static String UnderlineToHump(String para) {
StringBuilder result = new StringBuilder();
String a[] = para.split("_");
for (String s : a) {
if (!para.contains("_")) {
result.append(s);
continue;
}
if (result.length() == 0) {
result.append(s.toLowerCase());
} else {
result.append(s.substring(0, 1).toUpperCase());
result.append(s.substring(1).toLowerCase());
}
}
return result.toString();
}
//获取类clazz的所有Field,包括其父类的Field
private List<Field> getAllFieldsWithRoot(Class<?> clazz) {
List<Field> fieldList = new ArrayList<>();
Field[] dFields = clazz.getDeclaredFields();//获取本类所有字段
if (null != dFields && dFields.length > 0) {
fieldList.addAll(Arrays.asList(dFields));
}
// 若父类是Object,则直接返回当前Field列表
Class<?> superClass = clazz.getSuperclass();
if (superClass == Object.class) {
return Arrays.asList(dFields);
}
// 递归查询父类的field列表
List<Field> superFields = getAllFieldsWithRoot(superClass);
if (null != superFields && !superFields.isEmpty()) {
superFields.stream().
filter(field -> !fieldList.contains(field)).//不重复字段
forEach(field -> fieldList.add(field));
}
return fieldList;
}
}
封装请求类的代码如下
@EqualsAndHashCode(callSuper = true)
@Data
public class DemoCondition extends PageCondition {
@QueryCondition(func = MatchType.like)
private String name;
}
基于这样我们就可以写下测试代码了,如果想加查询条件的话,直接请求里面加上就好了。
MyBaseRequest<DemoCondition> request = new MyBaseRequest<>();
DemoCondition demoCondition = new DemoCondition();
request.setCondition(demoCondition);
CommonSearchRequest.Sort sort = new CommonSearchRequest.Sort();
sort.setDirection(1);
sort.setField("name");
request.setSortBy(sort);
Page<DemoEntity> demoEntityPage = demoService.initPage(request);
demoMapper.selectDemoPage(demoEntityPage);
比如我们在开发的时候,需求是一直在变的,比如产品经理一会相加个查询条件,我们只需要在我们的请求类里面添加就好了,至于其他的我们不用动了,正所谓,拥抱变化吧,哈哈~ 最后奉上github地址
https://github.com/fafeidou/fast-cloud-nacos/tree/master/fast-common-examples/fast-common-example-web