Spring Boot 工厂模式 + 抽象类 + 泛型干掉重复代码

业务场景:N个Excel导入,实现动态加载,只需要定义Excel实体,即可实现功能开发,

核心代码

import cn.afterturn.easypoi.excel.annotation.ExcelTarget;
import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;

public abstract class ScreenImportService<E, L, M extends BaseMapper<E>, S extends ServiceImpl<M, E>> implements InitializingBean {

    @Autowired
    private S service;

    @Override
    public void afterPropertiesSet() {
        String fileName = AnnotationUtil.getAnnotationValue(this.getExcelClass(), ExcelTarget.class, "value");
        ScreenImportFactory.register(fileName, this);
    }

    /**
     * 获取当前泛型-Excel
     */
    public abstract Class<L> getExcelClass();

    /**
     * excel 转 entity 并补全参数
     */
    public abstract List<E> excel2Entity(List<L> excelList);

    /**
     * 数据批量导入数据库
     */
    public void dataImportDb(List<L> excelList) {
        // 全量导入
        service.remove(Wrappers.lambdaQuery());

        // excel 转 entity 并补全参数
        List<E> entityList = this.excel2Entity(excelList);

        if (CollectionUtil.isNotEmpty(entityList)) {
            service.saveBatch(entityList);
        }
    }

}

工厂类

import cn.hutool.core.util.StrUtil;

import java.util.HashMap;
import java.util.Map;

/**
 * 大屏相关数据导入-工厂类
 *
 * @author jason
 */
public class ScreenImportFactory {
    private static final Map<String, ScreenImportService<?, ?, ?, ?>> strategyMap = new HashMap<>();

    public static ScreenImportService<?, ?, ?, ?> getInvokeStrategy(String name) {
        return strategyMap.get(name);
    }

    public static void register(String name, ScreenImportService<?, ?, ?, ?> service) {
        if (StrUtil.isBlank(name)) {
            return;
        }
        if (service == null) {
            return;
        }
        strategyMap.put(name, service);
    }

    public static Map<String, ScreenImportService<?, ?, ?, ?>> getStrategyMap() {
        return strategyMap;
    }

}

实现类-每个文件有不同的实现

import cn.hutool.core.bean.BeanUtil;
import com.luoan.biz.hansi.domain.ScreenDataCountExcel;
import com.luoan.biz.hansi.entity.ScreenDataCount;
import com.luoan.biz.hansi.mapper.ScreenDataCountMapper;
import com.luoan.biz.hansi.service.ScreenImportService;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * <p>
 * 大屏数据导入-汇总表 服务实现类
 * </p>
 *
 * @author luoan
 * @since 2023-09-26
 */
@Service
public class ImportCountServiceImpl extends ScreenImportService<ScreenDataCount, ScreenDataCountExcel, ScreenDataCountMapper, ScreenDataCountServiceImpl> {

    @Override
    public Class<ScreenDataCountExcel> getExcelClass() {
        return ScreenDataCountExcel.class;
    }

    @Override
    public List<ScreenDataCount> excel2Entity(List<ScreenDataCountExcel> excelList) {
        return Optional.ofNullable(excelList)
                .orElse(new ArrayList<>())
                .stream()
                .filter(Objects::nonNull)
                .map(excel -> {
                    ScreenDataCount entity = new ScreenDataCount();

                    BeanUtil.copyProperties(excel, entity);

                    // 参数补全
                    entity.setCreateTime(LocalDateTime.now());
                    entity.setCreateUserId(0);
                    entity.setUpdateTime(LocalDateTime.now());
                    entity.setUpdateUserId(0);

                    return entity;
                })
                .collect(Collectors.toList())
                ;
    }

}

统一调用,后续扩展很方便,N个导入,这块不用动了

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Assert;
import com.luoan.biz.hansi.service.ScreenImportFactory;
import com.luoan.biz.hansi.service.ScreenImportService;
import com.luoan.biz.hansi.utils.ExcelUtil;
import com.luoan.common.vo.Result;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.util.Arrays;
import java.util.Optional;

/**
 * <p>
 * 大屏相关数据 前端控制器
 * </p>
 *
 * @author luoan
 * @since 2023-08-09
 */
@RestController
@RequestMapping("/admin/screen")
public class ScreenImportCommonController {

    @ApiOperation(value = "批量导入")
    @PostMapping("/batch_import")
    public Result<Object> batchImport(@RequestPart(value = "files") MultipartFile[] files) {

        Assert.notEmpty(files, "请检查上传的文件");

        Arrays.stream(Optional.ofNullable(files).orElse(new MultipartFile[]{}))
                .forEach(file -> {
                            String originalFilename = file.getOriginalFilename();
                            String fileName = FileUtil.mainName(file.getOriginalFilename());
                            ScreenImportService<?, ?, ?, ?> service = ScreenImportFactory.getInvokeStrategy(fileName);

                            Assert.notNull(service, "请检查文件名:{}", originalFilename);

                            service.dataImportDb(ExcelUtil.importExcel(file, service.getExcelClass()));
                        }
                );
        return Result.ok();
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值