DBUnit增强:填充随机数据和相对时间数据

痛点

测试环境验证时,遇到与当前相对时间相关的测试吗?准备一份SQL?隔一段时间就不能用了。每过一段时间去更新脚本或重置系统时间?看上去也不是很合适的解决方案。依赖数据测试时要重新做,演示时候得全部改,如果你遇到一样的问题,可以看下本人使用的这个解决方案

DBUnit

DBUnit是一个测试框架,它通过一份XML数据反向设置到数据库,能自动维护数据的格式(有多少人遇到数值字段忘记加引号的BUG的举手)。准备的数据类似这样:

	<!-- 省份树节点 -->
	<SYS_TREE_NODE TREE_NODE_ID="10000" UPPER_TREE_NODE_ID="5" TREE_NODE_TYPE_CODE="4" SYS_OBJECT_ID="10000" ICON="[null]" TREE_NODE_NM="安徽省" TREE_NODE_POSITION="100" IF_SYS_RESERVE="N" NODE_PATH_DATA="5" CREATE_TIME="$R{T0*}R$" UPDATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
	<SYS_TREE_NODE TREE_NODE_ID="10900" UPPER_TREE_NODE_ID="5" TREE_NODE_TYPE_CODE="4" SYS_OBJECT_ID="10900" ICON="[null]" TREE_NODE_NM="北京市" TREE_NODE_POSITION="100" IF_SYS_RESERVE="N" NODE_PATH_DATA="5" CREATE_TIME="$R{T0*}R$" UPDATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
	<SYS_TREE_NODE TREE_NODE_ID="11800" UPPER_TREE_NODE_ID="5" TREE_NODE_TYPE_CODE="4" SYS_OBJECT_ID="11800" ICON="[null]" TREE_NODE_NM="重庆市" TREE_NODE_POSITION="100" IF_SYS_RESERVE="N" NODE_PATH_DATA="5" CREATE_TIME="$R{T0*}R$" UPDATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>

由于统一都是字符形式,手写比较舒服。也可以从数据库导出为XML

方案

DBUnit有一个扩展点,就是可以添加FilteredDataSet来实现加载过程中的数据过滤/替换,因为操作的执行接口:

    public abstract void execute(IDatabaseConnection connection,
            IDataSet dataSet) throws DatabaseUnitException, SQLException;

执行的是一个IDataSet接口,该接口实现数据的状态过程,我们可以基于该接口进行扩展,在状态的过程中,对于我们需要的数据进行替换。这里我们选择从AbstractDataSet进行扩展。

替换处理器

我们定义了一组ReplacementProcessor,用于对读取过程的数据进行替换处理

public interface ReplacementProcessor {
	Object replacementSubStrToObject(ITable table, String column,  String string, IDatabaseConnection connection, DBTYPE dbType);
	String getStartDelim();
	String getEndDelim();
}

我们实现的ReplacementDataSet如下

package org.ccframe.commons.dbunit;

import org.ccframe.commons.util.DbUnitUtils.DBTYPE;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.dataset.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

public class ReplacementDataSet extends AbstractDataSet {

    /**
     * Logger for this class
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(ReplacementDataSet.class);

    private final IDataSet dataSet;
    private IDatabaseConnection connection;
    private DBTYPE dbType;
    private List<ReplacementProcessor> processorList = new ArrayList<ReplacementProcessor>();

    private static int tableId = 0;

    public ReplacementDataSet(IDataSet dataSet, IDatabaseConnection connection, DBTYPE dbType, List<ReplacementProcessor> processorList)
    {
        this.dataSet = dataSet;
        this.connection = connection;
        this.dbType = dbType;
        this.processorList.addAll(processorList);
    }

    private ReplacementTable createReplacementTable(ITable table)
    {
        tableId ++;
        return  new ReplacementTable(table, tableId, connection, dbType, processorList);
    }

    
    // AbstractDataSet class

    protected ITableIterator createIterator(boolean reversed)
            throws DataSetException
    {
        return new ReplacementIterator(reversed ?
                dataSet.reverseIterator() : dataSet.iterator());
    }

    
    // IDataSet interface

    public String[] getTableNames() throws DataSetException
    {
        LOGGER.debug("getTableNames() - start");

        return dataSet.getTableNames();
    }

    public ITableMetaData getTableMetaData(String tableName)
            throws DataSetException
    {
        return dataSet.getTableMetaData(tableName);
    }

    public ITable getTable(String tableName) throws DataSetException
    {
        return createReplacementTable(dataSet.getTable(tableName));
    }

    
    // ReplacementIterator class

    private class ReplacementIterator implements ITableIterator
    {

//        private final Logger logger = LoggerFactory.getLogger(ReplacementIterator.class);

        private final ITableIterator iterator;

        public ReplacementIterator(ITableIterator iterator)
        {
            this.iterator = iterator;
        }

        
        // ITableIterator interface

        public boolean next() throws DataSetException
        {
            return iterator.next();
        }

        public ITableMetaData getTableMetaData() throws DataSetException
        {
            return iterator.getTableMetaData();
        }

        public ITable getTable() throws DataSetException
        {
            return createReplacementTable(iterator.getTable());
        }
    }
}

这里我们针对ITable实现了自己的替换用的数据表ReplacementTable,用于在读取过程中getValue时进行替换

package org.ccframe.commons.dbunit;

import com.google.common.base.CaseFormat;
import org.ccframe.commons.helper.SpringContextHelper;
import org.ccframe.commons.util.DbUnitUtils.DBTYPE;
import org.ccframe.config.Global;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.dataset.DataSetException;
import org.dbunit.dataset.ITable;
import org.dbunit.dataset.ITableMetaData;
import org.redisson.api.RAtomicLong;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class ReplacementTable implements ITable{

    /**
     * Logger for this class
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(ReplacementTable.class);
    
    private static final int OBJECT_CACHE_SIZE = 50; //50个field

    private final ITable table;
    private IDatabaseConnection connection;
    private DBTYPE dbType;
    private List<ReplacementProcessor> processorList;
    /**
     * 每切换一个不同的表代表一个新的tableId,用于结合行号标记唯一的XML表位置。例如XML1和XML2的SYS_USER表的tableId就会不一样.
     */
    private int tableId;
    private String pkId;
    private RAtomicLong atomicLong;

	private RAtomicLong getAtomicLong() {
		if(atomicLong == null) {
			atomicLong = SpringContextHelper.getBean(RedissonClient.class).getAtomicLong(Global.REDIS_PERFIX + CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, this.pkId));
			if(atomicLong.get() == 0) {
				atomicLong.getAndIncrement();
			}
		}
		return atomicLong;
	}

	private Map<String, Object> getRowObjectCache = new LinkedHashMap<String, Object>(5){
		private static final long serialVersionUID = 1L;
		@Override
		protected boolean removeEldestEntry(Map.Entry<String, Object> eldest) {
		    // 当前记录数大于设置的最大的记录数,删除最旧记录(即最近访问最少的记录)
		    return size() > OBJECT_CACHE_SIZE;
		}
	};

	private Map<String, Object> getRowIdCache = new LinkedHashMap<String, Object>(5){
		private static final long serialVersionUID = 1L;
		@Override
		protected boolean removeEldestEntry(Map.Entry<String, Object> eldest) {
		    // 当前记录数大于设置的最大的记录数,删除最旧记录(即最近访问最少的记录)
		    return size() > OBJECT_CACHE_SIZE;
		}
	};

    public ReplacementTable(ITable table, int tableId, IDatabaseConnection connection, DBTYPE dbType, List<ReplacementProcessor> processorList)
    {
        this.table = table;
        this.connection = connection;
        this.dbType = dbType;
        this.processorList = processorList;
        this.tableId = tableId;
        this.pkId = table.getTableMetaData().getTableName();
        this.pkId = this.pkId.substring(this.pkId.indexOf("_") + 1) + "_ID";
    }

    
    // ITable interface

    public ITableMetaData getTableMetaData()
    {
        return table.getTableMetaData();
    }

    public int getRowCount()
    {
        return table.getRowCount();
    }

    public Object getValue(int row, String column) throws DataSetException{
		//注意会进来2次,第一次是ignore mapping,第二次才是取值。因此要cache住行号列号位置,避免某些替换的动作重复了2次
    	String value = (String)table.getValue(row, column);

    	if(pkId.equals(column)) { //主键
        	if(value == null) {
        		Object objectCached = getRowIdCache.get(tableId + "-" + row);
        		if(objectCached == null) {
        			objectCached = new Long(getAtomicLong().getAndIncrement()).intValue();
        			getRowIdCache.put(tableId + "-" + row, objectCached);
        		}
        		return objectCached;
        	} else { //同步ID
        		long next = getAtomicLong().get();
        		int dbId = Integer.parseInt(value); //id必须是Integer
        		if(next <= dbId) {
        			getAtomicLong().set(dbId + 1);
        		}
        		return dbId;
        	}
    	}else { //非主键
            if (value == null){
            	return null;
            }
            for(ReplacementProcessor processor: processorList){
                if (processor.getStartDelim() != null && processor.getEndDelim() != null && value.toString().startsWith(processor.getStartDelim()) && value.toString().endsWith( processor.getEndDelim())){
                	Object objectCached = getRowObjectCache.get(tableId + "-" + row + "-" + column);
                	if(objectCached == null) {
                		objectCached = processor.replacementSubStrToObject(table, column, value.substring(processor.getStartDelim().length(), value.length() - processor.getEndDelim().length()), connection, dbType); 
                    	getRowObjectCache.put(tableId + "-" + row + "-" + column, objectCached);
                	}
    				return objectCached;
                }
            }
            return value;
    	}
    }

    public String toString()
    {
    	StringBuffer sb = new StringBuffer();
    	sb.append(getClass().getName()).append("[");
    	sb.append(", table=").append(table);
    	sb.append("]");
    	return sb.toString();
    }
}

语法

接下来我们实现一个替换处理器,该处理器实现了随机数、相对时间等常用的逻辑。为了避免和正常数据冲突,我定义了一组前缀/后缀正则$R{<控制语法>}R$来激活我们的替换:

随机数生成器,根据字段的类型自动填充数据.
内容格式:类型标识符+是否动态(-或+)+长度+是否必输(*),由于XML的<要转义,故用-代替
类型标识符:S=字符串 I=整型 L=长整 T=时间 B=二进制 Y=是否 E=ENUM D=浮点

整型的长度是限制输入位数,而时间的长度是限制随机距离当前时间的天数范围.

一个必输的从1个字符到16个字符的随机长度随机字符填充的表达式:S-16*
一个可以为空的从1位到5位的整数:I-5
一个不允许为空的11位长整数:L11*
一个不允许为空的距离当前时间前后30天内的时间:T30*
一个不允许为空的距离当前时间后60天的时间:T+60*
一个距离当前3天前时间:T-3*(注意前后的时间均只到日期的00:00:00),不包含时分秒
一个距离当前4天后时间:T+4*
一个现在的时间:T0*
一个不允许为空的10随机字符的二进制:B10*
package org.ccframe.commons.dbunit;

import org.apache.commons.lang3.RandomUtils;
import org.ccframe.commons.util.DbUnitUtils.DBTYPE;
import org.ccframe.commons.util.UtilDateTime;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.dataset.ITable;

import java.util.Date;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 随机数生成器,根据字段的类型自动填充数据.
 *
 * 内容格式:类型标识符+是否动态(-或+)+长度+是否必输(*),由于XML的<要转义,故用-代替
 * 类型标识符:S=字符串 I=整型 L=长整 T=时间 B=二进制 Y=是否 E=ENUM D=浮点
 * 
 * 整型的长度是限制输入位数,而时间的长度是限制随机距离当前时间的天数范围.
 * 
 * 一个必输的从1个字符到16个字符的随机长度随机字符填充的表达式:S-16*
 * 一个可以为空的从1位到5位的整数:I-5
 * 一个不允许为空的11位长整数:L11*
 * 一个不允许为空的距离当前时间前后30天内的时间:T30*
 * 一个不允许为空的距离当前时间后60天的时间:T+60*
 * 一个距离当前3天前时间:T-3*(注意前后的时间均只到日期的00:00:00),不包含时分秒
 * 一个距离当前4天后时间:T+4*
 * 一个现在的时间:T0*
 * 一个不允许为空的10随机字符的二进制:B10*
 * 
 * @author JIM
 *
 */
public class RandomReplacementProcessor implements ReplacementProcessor {

	private static final String FILE_START_DELIMITER = "$R{";
	private static final String FILE_END_DELIMITER = "}R$";

//	private Logger logger = Logger.getLogger(RandomReplacementProcessor.class);
	
	private static Pattern extractPattern = Pattern.compile("([SILTBY])([-+]{1})?(\\d+)?(\\*)?"); 
	
	@Override
	public Object replacementSubStrToObject(ITable table, String column, String substring, IDatabaseConnection connection, DBTYPE dbType){
		Matcher matcher = extractPattern.matcher(substring);
		if(!matcher.find()) {
			return null;
		}
		String mode = matcher.group(1);
		Boolean growFlag = (matcher.group(2) == null ? null: "+".equals(matcher.group(2)));
		Integer maxLength = (matcher.group(3) == null ? null: Integer.parseInt(matcher.group(3)));
		boolean notNull = (matcher.group(4) != null);
		
		switch(mode.charAt(0)) {
			case 'S': //字符
				return randomString(growFlag, maxLength, notNull);
			case 'I': //
				return randomInteger(growFlag, maxLength, notNull);
			case 'L':
				return randomLong(growFlag, maxLength, notNull);
			case 'T':
				return randomTime(growFlag, maxLength, notNull);
			case 'B':
				return randomByteString(growFlag, maxLength, notNull);
			case 'Y':
				return randomBooleanString(notNull);
			case 'E':
				return randomEnumString(notNull);
			case 'D':
				return randomDouble(maxLength, notNull);
			default:
				return null;
		}
	}

	private static final boolean randomNull() { //如果可以为空,1/10 概率出现NULL或空串
		return RandomUtils.nextInt(0, 10) == 0;
	}
	
	private static final String ALLCHAR = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

	private String randomString(Boolean growFlag, Integer maxLength, boolean notNull) {
		
		if(!notNull && randomNull()) {
			return "";
		}

		if(maxLength == null){
			maxLength = 16;
		}

		StringBuilder sb = new StringBuilder();

		int length = maxLength - 1;
		if (growFlag != null) {
			length = RandomUtils.nextInt(0, maxLength);
		}
		for (int i = 0; i <= length; i++) {
			sb.append(ALLCHAR.charAt(RandomUtils.nextInt(0, ALLCHAR.length())));
		}
		return sb.toString();
	}

	private Integer randomInteger(Boolean growFlag, Integer maxLength, boolean notNull) {
		return 0; //BoolCodeEnum.fromValue(RandomUtils.nextBoolean());
	}

	private Integer randomLong(Boolean growFlag, Integer maxLength, boolean notNull) {
		return 0;
	}

	private static final Random LONG_RANDOM = new Random();
	private static final Date NOW_TIME = new Date(); //系统初始化的时间
	private Date randomTime(Boolean growFlag, Integer maxLength, boolean notNull) {
		if(!notNull && randomNull()) {
			return null;
		}
		if(maxLength == null || maxLength == 0) {
			return NOW_TIME;
		}
		if(growFlag == null) { //随机范围时间
			long grow = LONG_RANDOM.nextLong() % (maxLength*2*24L*3600L*1000L); //随机天数范围
			return new Date(NOW_TIME.getTime() - (maxLength*24L*3600L*1000L) + grow);
		}else { //固定时间差
			return UtilDateTime.addDays(UtilDateTime.getDayStartTime(NOW_TIME), growFlag ? maxLength: -maxLength);
		}
	}

	private byte[] randomByteString(Boolean growFlag, Integer maxLength, boolean notNull) {
		String value = randomString(growFlag, maxLength, notNull);
		return value == null ? null : value.getBytes();
	}

	private String randomBooleanString(boolean notNull) {
		return null;
	}

	private String randomEnumString(boolean notNull) {
		return null;
	}

	private Double randomDouble(Integer maxLength, boolean notNull) { //double默认就是grow取范围
		return null;
	}

	@Override
	public String getStartDelim() {
		return FILE_START_DELIMITER;
	}

	@Override
	public String getEndDelim() {
		return FILE_END_DELIMITER;
	}
}

最终效果

这样,我们要实现一份相对于当前30天过期的租户就非常简单了,只需要给一个随机时间定义,让它范围在60天之内随机即可,这里的数据创建时间和更新时间都是当前的时间:

<?xml version="1.0" encoding="UTF-8"?>
<!-- DBUnit flatXml DataFile -->
<!-- 测试数据文件,注意.此文件的指定ID必须>70000 -->
<dataset>
    <SYS_TENANT TENANT_ID="50001" TENANT_COMPANY="阿里巴巴集团" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="阿里巴巴集团" TENANT_SUBDOMAIN="demo50001" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业阿里巴巴集团" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50002" TENANT_COMPANY="腾讯科技有限公司" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="腾讯科技" TENANT_SUBDOMAIN="demo50002" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业腾讯科技有限公司" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50003" TENANT_COMPANY="百度公司" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="百度" TENANT_SUBDOMAIN="demo50003" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业百度公司" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50004" TENANT_COMPANY="华为技术有限公司" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="华为技术" TENANT_SUBDOMAIN="demo50004" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业华为技术有限公司" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50005" TENANT_COMPANY="字节跳动公司" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="字节跳动" TENANT_SUBDOMAIN="demo50005" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业字节跳动公司" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50006" TENANT_COMPANY="京东集团" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="京东集团" TENANT_SUBDOMAIN="demo50006" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业京东集团" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50007" TENANT_COMPANY="美团点评" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="美团点评" TENANT_SUBDOMAIN="demo50007" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业美团点评" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50008" TENANT_COMPANY="滴滴出行" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="滴滴出行" TENANT_SUBDOMAIN="demo50008" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业滴滴出行" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50009" TENANT_COMPANY="网易集团" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="网易集团" TENANT_SUBDOMAIN="demo50009" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业网易集团" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50010" TENANT_COMPANY="新浪公司" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="新浪" TENANT_SUBDOMAIN="demo50010" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业新浪公司" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50011" TENANT_COMPANY="中国石油天然气集团公司" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国石油天然气集团" TENANT_SUBDOMAIN="demo50011" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国石油天然气集团公司" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50012" TENANT_COMPANY="中国石化集团公司" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国石化集团" TENANT_SUBDOMAIN="demo50012" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国石化集团公司" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50013" TENANT_COMPANY="中国建筑股份有限公司" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国建筑" TENANT_SUBDOMAIN="demo50013" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国建筑股份有限公司" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50014" TENANT_COMPANY="中国工商银行" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国工商银行" TENANT_SUBDOMAIN="demo50014" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国工商银行" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50015" TENANT_COMPANY="中国农业银行" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国农业银行" TENANT_SUBDOMAIN="demo50015" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国农业银行" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50016" TENANT_COMPANY="中国银行" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国银行" TENANT_SUBDOMAIN="demo50016" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国银行" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50017" TENANT_COMPANY="中国建设银行" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国建设银行" TENANT_SUBDOMAIN="demo50017" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国建设银行" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50018" TENANT_COMPANY="中国交通银行" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国交通银行" TENANT_SUBDOMAIN="demo50018" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国交通银行" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50019" TENANT_COMPANY="中国人寿保险股份有限公司" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国人寿保险" TENANT_SUBDOMAIN="demo50019" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国人寿保险股份有限公司" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50020" TENANT_COMPANY="中国平安保险" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国平安保险" TENANT_SUBDOMAIN="demo50020" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国平安保险" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50021" TENANT_COMPANY="中国太平洋保险" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国太平洋保险" TENANT_SUBDOMAIN="demo50021" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国太平洋保险" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50022" TENANT_COMPANY="中国人民保险集团" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国人民保险集团" TENANT_SUBDOMAIN="demo50022" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国人民保险集团" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50023" TENANT_COMPANY="中国人民财产保险" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国人民财产保险" TENANT_SUBDOMAIN="demo50023" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国人民财产保险" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50024" TENANT_COMPANY="中国信达资产管理股份有限公司" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国信达资产管理" TENANT_SUBDOMAIN="demo50024" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国信达资产管理股份有限公司" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50025" TENANT_COMPANY="中国光大银行" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国光大银行" TENANT_SUBDOMAIN="demo50025" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国光大银行" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50026" TENANT_COMPANY="中国光大集团" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国光大集团" TENANT_SUBDOMAIN="demo50026" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国光大集团" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50027" TENANT_COMPANY="中国进出口银行" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国进出口银行" TENANT_SUBDOMAIN="demo50027" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国进出口银行" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50028" TENANT_COMPANY="中国国家开发银行" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国国家开发银行" TENANT_SUBDOMAIN="demo50028" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国国家开发银行" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50029" TENANT_COMPANY="中国农业发展银行" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国农业发展银行" TENANT_SUBDOMAIN="demo50029" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国农业发展银行" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50030" TENANT_COMPANY="中国银联股份有限公司" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国银联" TENANT_SUBDOMAIN="demo50030" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国银联股份有限公司" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50031" TENANT_COMPANY="中国邮政储蓄银行" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国邮政储蓄银行" TENANT_SUBDOMAIN="demo50031" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国邮政储蓄银行" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50032" TENANT_COMPANY="中国电信股份有限公司" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国电信" TENANT_SUBDOMAIN="demo50032" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国电信股份有限公司" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50033" TENANT_COMPANY="中国移动通信集团公司" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国移动通信集团" TENANT_SUBDOMAIN="demo50033" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国移动通信集团公司" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50034" TENANT_COMPANY="中国联合网络通信有限公司" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国联合网络通信" TENANT_SUBDOMAIN="demo50034" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国联合网络通信有限公司" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50035" TENANT_COMPANY="中国广播电影电视集团公司" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国广播电影电视集团" TENANT_SUBDOMAIN="demo50035" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国广播电影电视集团公司" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50036" TENANT_COMPANY="中国中央电视台" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国中央电视台" TENANT_SUBDOMAIN="demo50036" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国中央电视台" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50037" TENANT_COMPANY="中国移动" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国移动" TENANT_SUBDOMAIN="demo50037" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国移动" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50038" TENANT_COMPANY="中国电信" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国电信" TENANT_SUBDOMAIN="demo50038" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国电信" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50039" TENANT_COMPANY="中国联通" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国联通" TENANT_SUBDOMAIN="demo50039" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国联通" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50040" TENANT_COMPANY="中国航天科技集团公司" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国航天科技集团" TENANT_SUBDOMAIN="demo50040" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国航天科技集团公司" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50041" TENANT_COMPANY="中国航天科工集团公司" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国航天科工集团" TENANT_SUBDOMAIN="demo50041" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国航天科工集团公司" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50042" TENANT_COMPANY="中国航空工业集团公司" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国航空工业集团" TENANT_SUBDOMAIN="demo50042" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国航空工业集团公司" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50043" TENANT_COMPANY="中国船舶重工集团公司" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国船舶重工集团" TENANT_SUBDOMAIN="demo50043" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国船舶重工集团公司" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50044" TENANT_COMPANY="中国中车集团公司" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国中车集团" TENANT_SUBDOMAIN="demo50044" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国中车集团公司" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50045" TENANT_COMPANY="中国南车集团公司" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国南车集团" TENANT_SUBDOMAIN="demo50045" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国南车集团公司" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50046" TENANT_COMPANY="中国北车集团公司" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国北车集团" TENANT_SUBDOMAIN="demo50046" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国北车集团公司" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50047" TENANT_COMPANY="中国中铁股份有限公司" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国中铁" TENANT_SUBDOMAIN="demo50047" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国中铁股份有限公司" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50048" TENANT_COMPANY="中国铁路工程集团公司" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国铁路工程集团" TENANT_SUBDOMAIN="demo50048" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国铁路工程集团公司" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
    <SYS_TENANT TENANT_ID="50049" TENANT_COMPANY="中国铁路建设股份有限公司" TENANT_EXPIRE_DATE="$R{T60*}R$" TENANT_NAME="中国铁路建设" TENANT_SUBDOMAIN="demo50049" IF_VALID="Y" MANAGER_MOBILE="[null]" MANAGER="[null]" TENANT_COMPANY_ADDRESS="" REMARK="测试企业中国铁路建设股份有限公司" UPDATE_TIME="$R{T0*}R$" CREATE_TIME="$R{T0*}R$" CREATE_USER_ID="1" UPDATE_USER_ID="1"/>
</dataset>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/564398.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

用两种方式遍历Map集合

创建学生类对象 public class Student {private String name;public int age ;public Student() {}public Student(String name, int age) {this.name name;this.age age;}public String getName() {return name;}public void setName(String name) {this.name name;}publi…

LINUX核心配置文件md5监控

一、md5sum简介 md5sum 用于计算和校验文件的MD5值。 md5sum 常常被用来验证网络文件传输的完整性&#xff0c;防止文件被人篡改。在日常工作当中&#xff0c;我们可以用来判断系统中的重要文件是否被篡改。传文件给别人时确认是否一致。我们也还可使用 md5sum 生成文件或用户…

学习笔记:Vue2中级篇

Vue2 学习笔记&#xff1a;Vue2基础篇_ljtxy.love的博客-CSDN博客学习笔记&#xff1a;Vue2中级篇_ljtxy.love的博客-CSDN博客学习笔记&#xff1a;Vue2高级篇_ljtxy.love的博客-CSDN博客 Vue3 学习笔记&#xff1a;Vue3_ljtxy.love的博客&#xff09;-CSDN博客 文章目录 5.…

电脑监控软件员工会不会发现

电脑监控软件员工会不会发现 企业在安装电脑监控软件的时候都会问一个问题&#xff1a;会不会被员工发现&#xff1f;基本上是不会被发现的&#xff0c;因为监控软件都有隐藏功能&#xff0c;比如这款安企神。&#xff08;点击免费试用&#xff09; 它在终端安装的时候为静默安…

澳福一篇文章盘点持仓交易

什么是持仓交易&#xff0c;有什么优缺点&#xff0c;收益率是多少&#xff1f;今天澳福外汇一篇文章讲清楚。 持仓交易是长期策略。它基于波浪理论&#xff0c;根据该理论&#xff0c;市场以周期性方式发展:任何增长都伴随着衰退。交易者建立长期头寸&#xff0c;从价格上涨或…

【继承】复杂的菱形继承

博主首页&#xff1a; 有趣的中国人 专栏首页&#xff1a; C进阶 本篇文章主要讲解 菱形继承 的相关内容 目录 1. 继承与友元 2. 继承与静态成员 3. 复杂的菱形继承及菱形虚拟继承 3.1 继承分类 3.2 菱形继承导致的问题 3.3 虚拟继承解决数据冗余的原理 4. 继承和组…

揭秘链动3+1商业模式:打造未来商业新风潮

大家好&#xff0c;我是微三云周丽&#xff0c;今天给大家分析当下市场比较火爆的商业模式&#xff01; 小编今天跟大伙们分享什么是链动31模式&#xff1f; 在当今商业世界中&#xff0c;随着科技的飞速发展和消费者需求的不断升级&#xff0c;新的商业模式不断涌现。其中&a…

CAPL编程基础

1.程序结构 1.includes{} //头文件 2.variables{} //全局变量声明 3. on preStart{} //初始化 on start{} //工程运行 on preStop{} //工程预停止 on stopMeasurement{} //工程停止 4.int myFunction{} //自定义函数 2.事件 1.键盘事件 on key ‘a’ 2.报…

【漏洞复现】Linksys RE7000无线扩展器 命令注入漏洞(CVE-2024-25852)

0x01 产品简介 Linksys RE7000无线扩展器是一款功能强大、操作便捷的产品,旨在为用户提供无缝的网络覆盖和更快速、更稳定的网络连接体验。 0x02 漏洞概述 Linksys RE7000无线扩展器存在命令注入漏洞,未授权的攻击者可以通过该漏洞执行任意命令,控制服务器。 0x03 测绘语…

《论文阅读》对话推理的对比学习 EMNLP 2023

《论文阅读》对话推理的对比学习 前言名词简介CICERO 数据集方法损失函数实验结果前言 亲身阅读感受分享,细节画图解释,再也不用担心看不懂论文啦~ 无抄袭,无复制,纯手工敲击键盘~ 今天为大家带来的是《Contrastive Learning for Inference in Dialogue》 出版:EMNLP 时…

智能家居—ESP32开发环境搭建

相关文章 毕业设计——基于ESP32的智能家居系统(语音识别、APP控制) 智能家居—ESP32开发环境搭建 一、下载安装二、验证三、资料获取 一、下载安装 下载安装 vscode 安装插件 创建工程 二、验证 写一个简单的函数来验证一下功能 void setup() {// put your setup c…

8-云原生监控体系-PromQL-函数

Prometheus支持几个函数来操作数据。 文章目录 1. 函数语法解释2. count(v instant-vector)3. topk(n, v instant-vector)4. bottomk(n, v instant-vector)5. increase(v range-vector)6. rate(v range-vector)7. rate 和 increase8. irate(v range-vector)9. predict_linear(…

【Qt常用控件】—— 按钮类控件

目录 1.1 Push Button 1.2 Radio Buttion 1.3 Check Box 1.4 Tool Button 1.5 小结 1.1 Push Button 使⽤ QPushButton 表⽰⼀个按钮. 这也是当前我们最熟悉的⼀个控件了. QPushButton 继承⾃ QAbstractButton . 这个类是⼀个抽象类. 是其他按钮的⽗类. 在 Qt Desi…

项目体检(Health Check)升级上线

在快节奏的现代商业环境中&#xff0c;项目的健康与否直接关系到其最终的成功与否。为了满足这一需求&#xff0c;我们精心打造了项目体检工具&#xff08;Health Check&#xff09;。它不仅仅是一个工具&#xff0c;更是一种对项目健康状况的全面把控和智能诊断。 项目体检工具…

F-logic DataCube3 SQL注入漏洞复现(CVE-2024-31750)

0x01 产品简介 F-logic DataCube3是一款用于光伏发电系统的紧凑型终端测量系统。 0x02 漏洞概述 F-logic DataCube3 /admin/pr_monitor/getting_index_data.php 接口处存在SQL注入漏洞,未经身份验证的攻击者可通过该漏洞获取数据库敏感信息,深入利用可控制整个web服务器。 …

外显子测序wes

外显子是基因组中能够转录组出成熟RNA的部分。一个基因组中所有外显子的集合&#xff0c;即为外显子组。值得注意的是&#xff0c;通常所说的全外显子组测序&#xff0c;是指针对蛋白编码基因的外显子&#xff0c;很少涉及非编码基因。 基因(gene)是DNA中含有特定遗传信息的一…

MapReduce——ReudceTask并行度决定机制

MapReduce——ReudceTask并行度决定机制 1. Reduce任务的数量&#xff08;reduce task count&#xff09;&#xff1a; 这是最基本的决定因素之一。在作业启动时&#xff0c;用户可以指定Reduce任务的数量。更多的Reduce任务意味着更多的并行度&#xff0c;因为每个Reduce任务…

BeautifulSoup模块

【一】Beautifulsoup4初始 【前言】bs4模块 安装pip install beautifulsoup4 【1】什么是beautifulsoup: ​ 是一个可以从HTML或XML文件中提取数据的Python库。它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式。(官方) ​ beautifulsoup是一个解析器,…

贪吃蛇的简单实现(c语言)

前言&#xff1a;学完了C语言的基础语法&#xff0c;和一点数据结构的知识&#xff0c;拿贪吃蛇来练练手&#xff0c;并熟悉以前的知识。写完之后&#xff0c;有一种成就感&#xff0c;为以后的学习饱满激情。 注意这里的讲解是由部分到整体的思路。 目录 控制台不能是终端&am…

java可盈保险合同管理系统的设计与实现(springboot+mysql源码+文档)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的可盈保险合同管理系统。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 基于Spring Boot的…