AbstractBase抽象基类


import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public abstract class AbstractBaseRecord {

    protected AbstractBaseRecord(){
        init();
    }

    public class CommonContracts {
        public static final String NULL_STR = "\\N";
        public static final char SPLIT_STR = '\u0001';

        public CommonContracts() {
        }
    }

    public class MyUtil {

        /**
         * 安全的toString,避免空指针
         * @param obj
         * @return
         */
        public  String safeToString(Object obj){
            if(null == obj){
                return "";
            }

            return obj.toString();
        }

        public  String currentTime() {
            return getDateTimeString(LocalDateTime.now());
        }

        public  String getDateTimeString(long timeStamp) {
            LocalDateTime dt = LocalDateTime.ofInstant(Instant.ofEpochMilli(timeStamp), ZoneId.systemDefault());
            return getDateTimeString(dt);
        }

        public  String getDateTimeString(LocalDateTime dt) {
            return DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(dt);
        }
    }

    /**
     * 在子类中,返回具体的数据类型(表名)
     * @return
     */
    protected abstract String getDataType();
    /**
     * 在子类种,返回具体的字段列表
     * @return
     */
    protected abstract List<FieldType> getFields();

    /**
     * 字段列表
     */
    private List<FieldType> fields = new ArrayList<>();

    /**
     * 字段名和序号的Map
     */
    private Map<String ,Integer> nameAndOrderMap = new HashMap<>();

//    /**
//     * 序号和字段名的Map
//     */
//    private Map<Integer ,String> orderAndNameMap = new HashMap<>();

    /**
     * 各字段数据值的列表
     */
    private String[] values;

    /**
     * 初始化
     */
    protected void init(){
        List<FieldType> fields = this.getFields();
        //设置字段列表
        this.fields = fields;
        nameAndOrderMap = new HashMap<>();
        for(FieldType f : this.fields){
            if(nameAndOrderMap.containsKey(f.getName())){
                throw new RuntimeException("字段名重复");
            }
            nameAndOrderMap.put(f.getName(), f.getOrder());
        }
        values = new String[fields.size()];
    }

    /**
     * 重置所有字段的值为空
     */
    public void clearValues(){
        values = new String[fields.size()];
    }

    /**
     * 检查字段值是否都已经设置
     */
    public void checkValues(){
        for(int i = 0; i < values.length; i++){
            if(null == values[i]){
                throw new RuntimeException("发现null字段值。index:" + i);
            }
        }
    }

    /**
     * 根据字段名,设置一个字段值
     */
    public void putValue(String fieldName, String fieldValue){
        putValue(nameAndOrderMap.get(fieldName) - 1, fieldValue);
    }

    /**
     * 根据字段Order,设置一个字段值(注意,order从1开始)
     */
    public void putValue(int fieldOrder, String fieldValue){
        values[fieldOrder - 1] = fieldValue;
    }
    public void putValue(int fieldOrder, int fieldValue){
        putValue(fieldOrder, String.valueOf(fieldValue));
    }
    public void putValue(int fieldOrder, long fieldValue){
        putValue(fieldOrder, String.valueOf(fieldValue));
    }
    public void putValue(int fieldOrder, double fieldValue){
        putValue(fieldOrder, String.valueOf(fieldValue));
    }
    public void putValue(int fieldOrder, LocalDateTime fieldValue){
        putValue(fieldOrder, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(fieldValue));
    }

    /**
     * 生成一个推送数据的数据行
     * @return
     */
    public String toDataLineString(){
//        数据格式:dataType\u0001数据字符串\u0001发送时间
//        其中:
//        1.dataType为数据类型,不同业务类型不同,统一取自契约定义枚举,枚举为:cmc.tohdfs.contracts.DataType
//        2.数据字符串(不同业务按照指定字段顺序,通过特定分隔符连接成字符串,一条记录一个字符串,如果数据字段为空,需要用"\\N"占位),分隔符及占位符统一取自契约定义常量
//        数据字符串中分隔符和占位符常量类:CommonContracts
//        数据示例:"mx_card_order\u00012001\u0001山东\u0001\\N\u00012018-11-14 17:17:00"
//        注意:分隔符\u0001定义为char类型!

        StringBuilder sb = new StringBuilder();

        //统一格式:表名放在首位
        sb.append(this.getDataType());
        //设置数据
        for(int i = 0; i < values.length; i++){
            sb.append(CommonContracts.SPLIT_STR);//分隔符
            sb.append(ifEmptyNullStr(values[i]));//数据值
        }
        //统一格式:最后设置sendTime
        sb.append(CommonContracts.SPLIT_STR).append(MyUtil.currentTime());
        return sb.toString();
    }

    /**
     * 生成一个推送数据的可读格式
     * @return
     */
    public String toFormatedString(){
        StringBuilder sb = new StringBuilder();
        for(FieldType f : fields){
            if(sb.length() > 0){
                sb.append(",");
            }
            sb.append(f.getName()).append(":").append(values[nameAndOrderMap.get(f.getName()) - 1]);
        }

        return sb.toString();
    }

    /**
     * 空数据生成占位符
     * @param obj
     * @return
     */
    protected String ifEmptyNullStr(String obj){
        if(null == obj || obj.length() < 1){
            return CommonContracts.NULL_STR;//占位符
        }
        return obj;
    }


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值