jeecgBoot导入数据添加校验规则

背景:系统在进行数据导入的时候要进行唯一性校验

一、导入跟踪

1.查看jeecgBoot文档发现其导入功能使用autoPoi,查看官方文档发现autoPoi暂不支持添加数据校验规则

jeecgBoot文档地址 : http://doc.jeecg.com/2044224
autoPoi文档地址 : http://doc.autopoi.jeecg.com/1623974

在这里插入图片描述2.跟踪其导入找到后端接口
前端请求接口
在这里插入图片描述找到后端接口,类为 org.jeecg.modules.online.cgform.b.a
在这里插入图片描述跟踪发现其调用的方法为
在这里插入图片描述在这里插入图片描述在这里插入图片描述可以看到IOnlCgformSqlService是一个接口,路径为 org.jeecg.modules.online.cgform.service.IOnlCgformSqlService
在这里插入图片描述找到其实现类为g类,路径为 org.jeecg.modules.online.cgform.service.impl.g在这里插入图片描述根据导入的数据量执行不同的操作,最终都调用了this.a方法
在这里插入图片描述查看a方法发现其调用org.jeecg.modules.online.cgform.util.b.a方法后返回一个可执行的的sql变量var8,然后再执行sql语句
在这里插入图片描述注意这个类中还有一个saveOrUpdateSubData方法也调用了this.a,所有我们要想在导入时添加校验必须修改saveBatchOnlineTable方法的逻辑。
在这里插入图片描述

二、添加校验规则

思路:根据我们前面的代码跟踪发现org.jeecg.modules.online.cgform.b.a类的onlCgformSqlService属性是通过@Autowired注入,那我们重新实现onlCgformSqlService接口,并将我们自己的类添加到spring容器中。

在这里插入图片描述在这里插入图片描述1.新建接口类IBaseCheckService

@FunctionalInterface
public interface IBaseCheckService<T> {


    /**
     *  校验数据
     * @param t
     */
    void checkData(T t);

}

2.在我们要导入的表的Impl类中实现IBaseCheckService接口,重写其checkData方法。
比如数据库表名为sys_user,对应的Impl类为SysUserServiceImpl

implements IBaseCheckService<String>
@Override
	public void checkData(String studentStr) {
		// 这里写我们的校验逻辑
		// 校验不通过抛出异常 throw new RuntimeException("数据校验不通过");
	}

3.新建BaseCheck类

public class BaseCheck<T> {

    private IBaseCheckService baseCheckService;

    public void setBaseCheckService(IBaseCheckService baseCheckService) {
        this.baseCheckService = baseCheckService;
    }

    public BaseCheck() {
    }

    public void checkData(T t){
        baseCheckService.checkData(t);
    }
}

4.新建工具类,主要作用是将下划线转成驼峰

/**
 * 下划线转驼峰
 * @Author 
 * @Date 
 * @Description
 **/
public class HumpUtil {

    /**
     * 下划线对应的ASCII
     */
    private static final byte ASCII_UNDER_LINE = 95;

    /**
     * 小写字母a的ASCII
     */
    private static final byte ASCII_a = 97;

    /**
     * 大写字母A的ASCII
     */
    private static final byte ASCII_A = 65;

    /**
     * 小写字母z的ASCII
     */
    private static final byte ASCII_z = 122;

    /**
     * 字母a和A的ASCII差距(a-A的值)
     */
    private static final byte ASCII_a_A = ASCII_a - ASCII_A;

    public static String toHump(String column) {
        byte[] bytes = changeIdx(column);
        bytes = removeUnderLine(bytes);
        return new String(bytes);
    }

    /**
     * 交换下划线和其后面字符的下标
     * 将column从下划线命名方式转换成驼峰命名方式
     * 0. 找到‘_’符号的ASCII码(95)对应的下标
     * 1. 将下划线的下标的下一个元素转换为大写字段(如果是小写字母的话)并放到下划线对应的下标
     * 2. 将下划线下标的下一个元素设置为下划线
     * 3. 返回数组
     *
     * @param column 字段名称
     */
    private static byte[] changeIdx(String column) {
        byte[] bytes = column.getBytes();
        for (int i = 0; i < bytes.length; i++) {
            if (bytes[i] == ASCII_UNDER_LINE) {
                if (i < bytes.length - 1) {
                    bytes[i] = toUpper(bytes[i + 1]);
                    bytes[i + 1] = ASCII_UNDER_LINE;
                    i++;
                }
            }
        }
        return bytes;
    }

    /**
     * 将参数b转换为大写字母,小写字母ASCII范围(97~122)
     * 0. 判断参数是否为小写字母
     * 1. 将小写字母转换为大写字母(减去32)
     */
    private static byte toUpper(byte b) {
        if (b >= ASCII_a && b <= ASCII_z) {
            return (byte) (b - ASCII_a_A);
        }
        return b;
    }

    /**
     * 去除所有下划线
     * 0. 新创建一个数组
     * 1. 将所有非下划线字符都放入新数组中
     *
     * @param bytes 原始数组
     * @return 处理后的字节数组
     */
    private static byte[] removeUnderLine(byte[] bytes) {
        // 存放非下划线字符的数量
        int count = 0;
        for (byte b : bytes) {
            if (b == ASCII_UNDER_LINE) {
                continue;
            }
            count++;
        }
        byte[] nBytes = new byte[count];
        count = 0;
        for (byte b : bytes) {
            if (b == ASCII_UNDER_LINE) {
                continue;
            }
            nBytes[count] = b;
            count++;
        }
        return nBytes;
    }

}

5.新建MyIOnlCgformSqlServiceImpl类实现IOnlCgformSqlService接口,复制org.jeecg.modules.online.cgform.service.impl.g类的代码,在saveBatchOnlineTable中调用this.a方法前调用数据校验的方法
在这里插入图片描述代码如下

/**
 *  org.jeecg.modules.online.cgform.service.impl.g
 * @Author 
 * @Date 
 * @Description
 **/
public class MyIOnlCgformSqlServiceImpl implements IOnlCgformSqlService {

    @Autowired
    private SqlSessionTemplate sqlSessionTemplate;
    @Autowired
    private IOnlCgformHeadService onlCgformHeadService;

    public MyIOnlCgformSqlServiceImpl() {
    }

    @Override
    public void saveBatchOnlineTable(OnlCgformHead head, List<OnlCgformField> fieldList, List<Map<String, Object>> dataList) throws BusinessException {
        SqlSession var4 = null;

        try {
            b.a(2, dataList, fieldList);
            var4 = this.sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
            OnlCgformFieldMapper var5 = (OnlCgformFieldMapper)var4.getMapper(OnlCgformFieldMapper.class);
            short var6 = 1000;
            int var7;
            String var8;
            if (var6 >= dataList.size()) {
                for(var7 = 0; var7 < dataList.size(); ++var7) {
                    var8 = JSON.toJSONString(dataList.get(var7));
                    this.checkData(var8, head);
                    this.a(var8, head, fieldList, var5);
                }
            } else {
                for(var7 = 0; var7 < dataList.size(); ++var7) {
                    var8 = JSON.toJSONString(dataList.get(var7));
                    this.checkData(var8, head);
                    this.a(var8, head, fieldList, var5);
                    if (var7 % var6 == 0) {
                        var4.commit();
                        var4.clearCache();
                    }
                }
            }

            var4.commit();
        } catch (Exception var12) {
            throw new BusinessException(var12.getMessage());
        } finally {
            var4.close();
        }

    }

    @Override
    public void saveOrUpdateSubData(String subDataJsonStr, OnlCgformHead head, List<OnlCgformField> subFiledList) throws BusinessException {
        OnlCgformFieldMapper var4 = (OnlCgformFieldMapper) SpringContextUtils.getBean(OnlCgformFieldMapper.class);
        this.a(subDataJsonStr, head, subFiledList, var4);
    }

    private void a(String var1, OnlCgformHead var2, List<OnlCgformField> var3, OnlCgformFieldMapper var4) throws BusinessException {
        JSONObject var5 = JSONObject.parseObject(var1);
        int var6 = this.onlCgformHeadService.executeEnhanceJava("import", "start", var2, var5);
        String var7 = var2.getTableName();
        Map var8;
        if (1 == var6) {
            var8 = org.jeecg.modules.online.cgform.util.b.a(var7, var3, var5);
            var4.executeInsertSQL(var8);
        } else if (2 == var6) {
            var8 = org.jeecg.modules.online.cgform.util.b.b(var7, var3, var5);
            var4.executeUpdatetSQL(var8);
        } else if (0 == var6) {
        }

    }

    /**
     * @param var1 导入的行数据
     * @param var2 表信息
     */
    private void checkData(String var1, OnlCgformHead var2) {
        // 将表明转成驼峰
        String service = HumpUtil.toHump(var2.getTableName());
        BaseCheck<String> studentBaseCheck = new BaseCheck<>();
        // 获取spring容器中对应的bean并设值
        studentBaseCheck.setBaseCheckService(SpringContextUtils.getBean(service + "ServiceImpl", IBaseCheckService.class));
        // 调用校验方法
        studentBaseCheck.checkData(var1);
    }
    
}

6.新建配置类,将spring容器中名为onlCgformSqlServiceImpl的bean移除,并将我们自己实现类的bean添加到spring容器中。beanName对应实现IOnlCgformSqlService接口的g类。
在这里插入图片描述

/**
 *  前端页面导入按钮
 * @Author 
 * @Date 
 * @Description
 **/
@Configuration
public class ModifyImportConfig {

    @Bean
    public void modifyFormSqlServiceImplBean(){
        String beanName="onlCgformSqlServiceImpl";
        //获取context.
        ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) SpringContextUtils.getApplicationContext();
        //获取BeanFactory
        DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableApplicationContext.getBeanFactory();
        Object oldBean = SpringContextUtils.getBean(beanName);
        if (!ObjectUtils.isEmpty(oldBean)){
            // 移除
            defaultListableBeanFactory.removeBeanDefinition(beanName);
        }
        // 重新注册
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(MyIOnlCgformSqlServiceImpl.class);
        defaultListableBeanFactory.registerBeanDefinition(beanName,beanDefinitionBuilder.getBeanDefinition());
    }

}

7.重启项目

注意:表对应的impl实现类一定要实现我们自定的校验接口,并重写checkData方法,否则在执行MyIOnlCgformSqlServiceImpl的checkData方法会报错
在这里插入图片描述

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值