這個(gè)是干什么的?
簡(jiǎn)單介紹下:
作用:通過(guò)插件一鍵生成某個(gè)表對(duì)應(yīng)的增刪改查等基礎(chǔ)或者說(shuō)通用接口,這里面的代碼是基礎(chǔ)版的,后續(xù)改良后,很多業(yè)務(wù)的通用功能,比如流程的啟動(dòng),自動(dòng)下一步,通用導(dǎo)出,通用導(dǎo)入等等。
原理:核心就是BasicControllerPostProcessor
,通過(guò)動(dòng)態(tài)生成代理對(duì)象,完成邏輯實(shí)現(xiàn)。這里呢經(jīng)過(guò)實(shí)踐呢后續(xù)也有不少優(yōu)化的,后續(xù)我總結(jié)后發(fā)一個(gè)新版的文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-648458.html
一、核心處理類
package com.nari.core.handler;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TimeInterval;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.List;
import java.util.Map;
/**
* 動(dòng)態(tài)加載baseMapper,baseDao,baseService
*
* @author <a href="mailto:njpkhuan@gmail.com">朱永勝</a>
* @version 1.0.0
* @since 2021/3/2
*/
@Slf4j
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class BasicControllerPostProcessor extends CommonAnnotationBeanPostProcessor {
private static final long serialVersionUID = -945664767382485314L;
@SuppressWarnings("NullableProblems")
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
String packageName = beanClass.getPackage().getName();
log.trace("beanName---{},packageName:{}", beanName, packageName);
List<String> per = ListUtil.of("com.nari.supervision.daily");
List<String> tail = ListUtil.of("outbound","personal");
if (per.stream().anyMatch(packageName::contains)) {
if (tail.stream().map(v -> v + ".controller").anyMatch(packageName::contains)) {
try {
updateResourceName(beanClass, beanName, "basicService", "Controller", "Service");
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
if (tail.stream().map(v -> v + ".service").anyMatch(packageName::contains)) {
try {
updateResourceName(beanClass, beanName, "basicMapper", "Service", "TransformImpl");
updateResourceName(beanClass, beanName, "basicDao", "Service", "Mapper");
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
if (tail.stream().map(v -> v + "serviceImpl").anyMatch(packageName::contains)) {
try {
updateResourceName(beanClass, beanName, "basicMapper", "Service", "TransformImpl");
updateResourceName(beanClass, beanName, "basicDao", "Service", "Mapper");
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
return null;
}
private void updateResourceName(Class<?> beanClass, String beanName, String destField, String searchString, String replaceString)
throws NoSuchFieldException, IllegalAccessException {
Field field = beanClass.getSuperclass().getDeclaredField(destField);
Resource basicMapper = field.getAnnotation(Resource.class);
InvocationHandler invocationHandler = Proxy.getInvocationHandler(basicMapper);
Field memberValues = invocationHandler.getClass().getDeclaredField("memberValues");
memberValues.setAccessible(true);
//noinspection unchecked
Map<String, Object> map = (Map<String, Object>) memberValues.get(invocationHandler);
map.put("name", StringUtils.replace(beanName, searchString, replaceString));
}
}
二、基礎(chǔ)類
BasicController
package com.nari.core.basic;
import com.nari.core.annotation.OperationLog;
import com.nari.core.groups.basic.InsertGroup;
import com.nari.core.groups.basic.UpdateGroup;
import com.nari.core.groups.query.PageQueryGroup;
import com.nari.core.web.ApiResult;
import com.nari.core.web.BaseParam;
import com.nari.core.web.PageResult;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiSort;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;
/**
* 基礎(chǔ)接口管理
*
* @author <a href="mailto:njpkhuan@gmail.com">朱永勝</a>
* @version 1.0.0
* @since 2021/3/1
*/
@Slf4j
@Valid
public class BasicController<T extends BasicModel, Q extends BaseParam, V, D, M extends BasicMapper<T, Q, D, V>> extends com.nari.core.web.BaseController {
@Resource
private BasicService<T, Q, V, D, M> basicService;
/**
* 添加
*
* @param query {@link Q}
*/
@PostMapping
@ApiOperation(value = "1.1 添加")
@OperationLog(value = "添加")
@Validated(value = InsertGroup.class)
public ApiResult insert(@RequestBody Q query) {
basicService.insert(query);
return success("添加成功!");
}
/**
* 根據(jù)id刪除
*
* @param id 主鍵
*/
@DeleteMapping("/{id}")
@ApiOperation(value = "1.2 根據(jù)id刪除")
@OperationLog(value = "根據(jù)id刪除")
public ApiResult del(@PathVariable("id") String id) {
basicService.del(id);
return success("刪除成功!");
}
/**
* 根據(jù)id刪除-軟刪除,實(shí)際修改標(biāo)識(shí)符
*
* @param id 主鍵
*/
@DeleteMapping("/{id}/weak")
@ApiOperation(value = "1.3 根據(jù)id刪除-軟刪除,實(shí)際修改標(biāo)識(shí)符")
@OperationLog(value = "根據(jù)id刪除-軟刪除,實(shí)際修改標(biāo)識(shí)符")
public ApiResult delWeak(@PathVariable("id") String id) {
basicService.delWeak(id);
return success("刪除成功!");
}
/**
* 根據(jù)id更新信息
*
* @param query {@link Q}
*/
@PutMapping("update")
@ApiOperation(value = "1.4 根據(jù)id更新信息")
@OperationLog(value = "根據(jù)id更新信息")
@Validated(value = UpdateGroup.class)
public ApiResult<V> update(@RequestBody Q query) {
return success(basicService.update(query));
}
/**
* 根據(jù)id更新信息-批量
*
* @param query {@link Q}
*/
@PutMapping("updateBatch")
@ApiOperation(value = "1.5 根據(jù)id更新信息-批量")
@OperationLog(value = "根據(jù)id更新信息-批量")
@Validated(value = UpdateGroup.class)
public ApiResult updateBatch(@RequestBody List<Q> query) {
basicService.updateBatch(query);
return success();
}
/**
* 查詢單個(gè)數(shù)據(jù)
*
* @param id 主鍵
*/
@GetMapping("/{id}")
@ApiOperation(value = "1.6 查詢單個(gè)數(shù)據(jù)")
@OperationLog(value = "查詢單個(gè)數(shù)據(jù)")
public ApiResult<V> select(@PathVariable("id") String id) {
return success(basicService.select(id));
}
/**
* 分頁(yè)
*
* @param query {@link Q}
*/
@GetMapping("page")
@ApiOperation(value = "1.7 分頁(yè)")
@OperationLog(value = "分頁(yè)")
@Validated(value = PageQueryGroup.class)
public ApiResult<PageResult<V>> listUser(Q query) {
return success(basicService.page(query));
}
}
BasicDao
package com.nari.core.basic;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.nari.core.web.BaseParam;
import com.nari.core.web.PageParam;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 基礎(chǔ)接口
*
* @author <a href="mailto:njpkhuan@gmail.com">朱永勝</a>
* @version 1.0.0
* @since 2021/3/1
*/
public interface BasicDao<T extends BasicModel, D, Q extends BaseParam> extends BaseMapper<T> {
List<D> selectPageRel(@Param("page") PageParam<D, Q> page, @Param("param") Q param);
}
BasicEnum
package com.nari.core.basic;
/**
* 基礎(chǔ)枚舉
* 主要用來(lái)配合apijson實(shí)現(xiàn)枚舉展示
*
* @author <a href="mailto:17602556550@189.cn">朱永勝</a>
* @version 1.0.0
* @since 2023/5/25
*/
public interface BasicEnum {
String getName();
Integer getValue();
}
BasicMapper
package com.nari.core.basic;
import org.mapstruct.MappingTarget;
import java.util.List;
/**
* 基礎(chǔ)轉(zhuǎn)換
*
* @author <a href="mailto:njpkhuan@gmail.com">朱永勝</a>
* @version 1.0.0
* @since 2021/3/1
*/
public interface BasicMapper<T, Q, D, V> {
T query2do(Q query);
V dto2View(D dto);
D do2dto(T role);
void update(Q query, @MappingTarget T t);
List<V> dto2ViewPage(List<D> dto);
}
BasicModel
package com.nari.core.basic;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 通用模型
*
* @author <a href="mailto:17602556550@189.cn">朱永勝</a>
* @version 1.0.0
* @since 2023/5/26
*/
@Data
public class BasicModel {
/**
* 主鍵
*/
private String id;
/**
* 刪除標(biāo)識(shí)
*/
@ApiModelProperty(value = "刪除標(biāo)識(shí)")
private String deleted;
}
BasicService
package com.nari.core.basic;
import cn.hutool.core.util.IdUtil;
import com.nari.core.web.BaseParam;
import com.nari.core.web.PageParam;
import com.nari.core.web.PageResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* 基礎(chǔ)服務(wù)
*
* @author <a href="mailto:njpkhuan@gmail.com">朱永勝</a>
* @version 1.0.0
* @since 2021/3/1
*/
@Slf4j
public class BasicService<T extends BasicModel, Q extends BaseParam, V, D, M extends BasicMapper<T, Q, D, V>> {
@Resource
private BasicDao<T, D, Q> basicDao;
@Resource
private BasicMapper<T, Q, D, V> basicMapper;
/**
* 添加
*
* @param query {@link Q}
* @author <a href = "mailto:njpkhuan@gmail.com" >朱永勝</a >
* @since 2021/3/1
* @since 1.0.0
*/
@Transactional(rollbackFor = Exception.class)
public void insert(@Valid Q query) {
T t = basicMapper.query2do(query);
t.setId(IdUtil.simpleUUID());
basicDao.insert(t);
}
/**
* 刪除
*
* @param id {@link Q}
* @author <a href = "mailto:njpkhuan@gmail.com" >朱永勝</a >
* @since 2021/3/1
* @since 1.0.0
*/
@Transactional(rollbackFor = Exception.class)
public void del(@NotNull String id) {
basicDao.deleteById(id);
}
/**
* 根據(jù)用戶id更新
*
* @param query @{@link Q}
* @author <a href = "mailto:njpkhuan@gmail.com" >朱永勝</a >
* @since 2021/3/1
* @since 1.0.0
*/
@Transactional(rollbackFor = Exception.class)
public V update(@Valid Q query) {
T data = basicMapper.query2do(query);
basicDao.updateById(data);
D d = basicMapper.do2dto(data);
return basicMapper.dto2View(d);
}
/**
* 查詢
*
* @param id 主鍵
* @author <a href = "mailto:njpkhuan@gmail.com" >朱永勝</a >
* @since 2021/3/1
* @since 1.0.0
*/
public V select(@NotNull String id) {
T data = basicDao.selectById(id);
D d = basicMapper.do2dto(data);
return basicMapper.dto2View(d);
}
/**
* 查詢多條記錄
*
* @param query {@link Q}
* @author <a href = "mailto:njpkhuan@gmail.com" >朱永勝</a >
* @since 2021/2/23
* @since 1.0.0
*/
public PageResult<V> page(@Valid Q query) {
PageParam<D, Q> page = new PageParam<>(query);
page.setDefaultOrder("create_time desc");
List<D> list = basicDao.selectPageRel(page, query);
List<V> vList = basicMapper.dto2ViewPage(list);
log.trace("{}", list);
return new PageResult<>(vList, page.getTotal());
}
/**
* 軟刪除
*
* @author <a href="mailto:17602556550@189.cn">朱永勝</a>
* @since 2023/5/26
*/
@Transactional(rollbackFor = Exception.class)
public void delWeak(String id) {
T t = basicDao.selectById(id);
t.setDeleted("1");
basicDao.updateById(t);
}
/**
* 批量更新
*
* @author <a href="mailto:17602556550@189.cn">朱永勝</a>
* @since 2023/6/6
*/
@Transactional(rollbackFor = Exception.class)
public void updateBatch(List<Q> query) {
query.forEach(this::update);
}
}
GenericSuperclassUtil
package com.nari.core.basic;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
public class GenericSuperclassUtil {
/*
* 獲取泛型類Class對(duì)象,不是泛型類則返回null
*/
public static Class<?> getActualTypeArgument(Class<?> clazz) {
Class<?> entitiClass = null;
Type genericSuperclass = clazz.getGenericSuperclass();
if (genericSuperclass instanceof ParameterizedType) {
Type[] actualTypeArguments = ((ParameterizedType) genericSuperclass)
.getActualTypeArguments();
if (actualTypeArguments != null && actualTypeArguments.length > 0) {
entitiClass = (Class<?>) actualTypeArguments[0];
}
}
return entitiClass;
}
/*
* 獲取泛型類Class對(duì)象,不是泛型類則返回null
*/
static Class<?> getActualTypeArgument(Class<?> clazz, Integer pos) {
Class<?> entitiClass = null;
Type genericSuperclass = clazz.getGenericSuperclass();
if (genericSuperclass instanceof ParameterizedType) {
Type[] actualTypeArguments = ((ParameterizedType) genericSuperclass)
.getActualTypeArguments();
if (actualTypeArguments != null && actualTypeArguments.length > pos) {
entitiClass = (Class<?>) actualTypeArguments[pos];
}
}
return entitiClass;
}
}
三、POM
<org.mapstruct.version>1.5.5.Final</org.mapstruct.version>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>0.2.0</version>
</path>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
本文由 mdnice 多平臺(tái)發(fā)布文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-648458.html
到了這里,關(guān)于快速生成通用接口業(yè)務(wù)配置的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!