基础九大字段改造,解除强依赖数据库设计

125 阅读5分钟

由于不能上传视频,跳转观看实现效果

一直以来,笔者对底层的九大基础字段并不是很满意,从数据写入至字段定义均有瑕疵。 此间,笔者决心改掉这一直以来的错误设计,将其精简为八大常用字段。

此前九大字段

此上为原有基础九大字段,笔者不满处有以下5处。

  • 创建人过长,精简为create_user
  • 缺少更新人,字段定义为update_user
  • is_edit,is_remove使用场景几乎无,欲剔除
  • 创建时间、更新时间过度依赖数据库,欲使用代码逻辑替换之
  • is_enable字段承接业务太少,欲使用state状态字段替换之

精简后的八大常用字段

image.png

基于这八大字段,为了实现在插入或更新数据时,自动带入创建用户、更新用户、创建时间、更新时间字段值,笔者欲定义接口规范,凡是实现此接口的对象,在使用笔者框架内部的插入或更新时,自动带入数据。

1、定义接口规范

package com.threeox.drivenlibrary.engine.entity.inter;

/**
 * 基础数据对象接口
 *
 * @author 赵屈犇
 * @version 1.0
 * @date 创建时间: 2022/8/31 20:26
 * @Copyright(C): 2022 by 赵屈犇
 */
public interface IDataInfo {

    /**
     * 初始化插入数据
     *
     * @return a
     * @author 赵屈犇
     * @date 创建时间: 2022/8/31 20:27
     * @version 1.0
     */
    void initInsert();

    /**
     * 初始化更新数据
     *
     * @return a
     * @author 赵屈犇
     * @date 创建时间: 2022/8/31 20:27
     * @version 1.0
     */
    void initUpdate();

}

此接口规范,提供初始化插入数据、更新数据实现方法,在子类继承时,实现其函数。

在此之上,笔者在框架内部实现一套实现类,提供给数据对象使用。

2、实现规范接口

package com.threeox.drivenlibrary.entity.base;

import com.threeox.dblibrary.annotation.create.Column;
import com.threeox.dblibrary.entity.base.BaseORM;
import com.threeox.dblibrary.enums.ColumnType;
import com.threeox.drivenlibrary.engine.annotation.function.form.FormFieldConfig;
import com.threeox.drivenlibrary.engine.constants.CommonConstants;
import com.threeox.drivenlibrary.engine.constants.DefaultFieldConstants;
import com.threeox.drivenlibrary.engine.constants.config.DrivenElementConstants;
import com.threeox.drivenlibrary.engine.entity.inter.IMessage;
import com.threeox.utillibrary.date.TimeUtils;

/**
 * 时间字段数据库
 *
 * @author 赵屈犇
 * @version 1.0
 * @date 创建时间: 2016-10-26 上午10:17:28
 */
public class BaseDateMessage extends BaseORM implements IMessage {

	/**
	 * 创建时间
	 */
	@FormFieldConfig(fieldCode = DefaultFieldConstants.CREATE_TIME, fieldName = "创建时间", elementCode = DrivenElementConstants.DATETIME_ELEMENT,
			tableColumnWidth = "180", tableColumnSort = 10, isPageEnable = false, fieldParentName = CommonConstants.DEFAULT_FIELD_PARENT_BASIC_MESSAGE_NAME,
			isDrivenBaseField = true)
	@Column(columnName = DefaultFieldConstants.CREATE_TIME, columnType = ColumnType.DATETIME, comment = "创建时间")
	private String createTime;
	/**
	 * 更新时间
	 */
	@FormFieldConfig(fieldCode = DefaultFieldConstants.UPDATE_TIME, fieldName = "更新时间", elementCode = DrivenElementConstants.DATETIME_ELEMENT,
			tableColumnWidth = "180", tableColumnSort = 10, isPageEnable = false, fieldParentName = CommonConstants.DEFAULT_FIELD_PARENT_BASIC_MESSAGE_NAME,
			isDrivenBaseField = true)
	@Column(columnName = DefaultFieldConstants.UPDATE_TIME, columnType = ColumnType.DATETIME, comment = "更新时间")
	private String updateTime;

	@Override
	public void initInsert() {
		super.initInsert();
		String nowTimeString = TimeUtils.getNowTimeString();
		setCreateTime(nowTimeString);
		setUpdateTime(nowTimeString);
	}

	@Override
	public void initUpdate() {
		super.initUpdate();
		String nowTimeString = TimeUtils.getNowTimeString();
		setUpdateTime(nowTimeString);
	}

	@Override
	public void initData() {
		
	}

	public String getCreateTime() {
		return createTime;
	}

	public void setCreateTime(String createTime) {
		this.createTime = createTime;
	}

	public String getUpdateTime() {
		return updateTime;
	}

	public void setUpdateTime(String updateTime) {
		this.updateTime = updateTime;
	}
}

以上为基础时间对象实现代码,基于此函数的子类“基础数据对象”也需自己实现特定代码逻辑。

package com.threeox.drivenlibrary.entity.base;


import com.threeox.biz.account.factory.UserFactory;
import com.threeox.dblibrary.annotation.create.Column;
import com.threeox.dblibrary.enums.ColumnType;
import com.threeox.drivenlibrary.engine.annotation.function.form.FormFieldConfig;
import com.threeox.drivenlibrary.engine.config.constants.dictionary.ConfigDictionaryConstants;
import com.threeox.drivenlibrary.engine.constants.CommonConstants;
import com.threeox.drivenlibrary.engine.constants.DefaultFieldConstants;
import com.threeox.drivenlibrary.engine.constants.SqlConstants;
import com.threeox.drivenlibrary.engine.constants.config.DrivenElementConstants;
import org.apache.commons.lang3.StringUtils;

/**
 * 基础字段数据库
 *
 * @author 赵屈犇
 * @version 1.0
 * @date 创建时间: 2016-10-26 上午10:17:28
 */
public class BaseDataMessage extends BaseDateMessage implements Cloneable {

    /**
     * 排序顺序
     */
    @FormFieldConfig(fieldCode = DefaultFieldConstants.SORT, fieldName = "排序顺序", fieldParentName = CommonConstants.DEFAULT_FIELD_PARENT_BASIC_MESSAGE_NAME,
        elementCode = DrivenElementConstants.INPUT_NUMBER_ELEMENT, pageDefaultValue = "0", pageFieldSort = 3, isDrivenBaseField = true)
    @Column(columnName = DefaultFieldConstants.SORT, columnType = ColumnType.INTEGER, length = 4, defaultValue = "0", comment = "排列顺序")
    private Integer sort;
    /**
     * 备注信息
     */
    @FormFieldConfig(fieldCode = DefaultFieldConstants.REMARK, fieldName = "备注信息", isTableEnable = false, elementCode = DrivenElementConstants.BIG_INPUT_ELEMENT,
            fieldParentName = CommonConstants.DEFAULT_FIELD_PARENT_BASIC_MESSAGE_NAME, pageFieldSort = 3, isEnable = false, isDrivenBaseField = true)
    @Column(columnName = DefaultFieldConstants.REMARK, columnType = ColumnType.VARCHAR, length = 500, isSelectUse = false, comment = "备注内容")
    private String remark;
    /**
     * 版本编号
     */
    @FormFieldConfig(fieldCode = DefaultFieldConstants.VERSION, fieldName = "版本编号", isEnable = false, fieldParentName = CommonConstants.DEFAULT_FIELD_PARENT_BASIC_MESSAGE_NAME,
            pageFieldSort = 3, isDrivenBaseField = true)
    @Column(columnName = DefaultFieldConstants.VERSION, columnType = ColumnType.FLOAT, length = 4, defaultValue = "1.0", comment = "版本编号")
    private float version;
    /**
     * 数据状态
     */
    @FormFieldConfig(fieldCode = DefaultFieldConstants.DATA_STATE, fieldName = "数据状态", elementCode = DrivenElementConstants.SELECT_ELEMENT,
            pageDefaultValue = ConfigDictionaryConstants.DataStateDict.NORMAL, fieldParentName = CommonConstants.DEFAULT_FIELD_PARENT_BASIC_MESSAGE_NAME,
            dictionaryCode = ConfigDictionaryConstants.DataStateDict.DICTIONARY_CODE, pageFieldSort = 3, tableColumnMinWidth = "120", isDrivenBaseField = true)
    @Column(columnName = DefaultFieldConstants.DATA_STATE, columnType = ColumnType.CHAR, defaultValue = ConfigDictionaryConstants.DataStateDict.NORMAL,
            length = SqlConstants.DICTIONARY_VALUE_SIZE, comment = "数据状态")
    private String dataState;
    /**
     * 创建用户主键
     */
    @FormFieldConfig(fieldCode = DefaultFieldConstants.CREATE_USER, fieldName = "创建用户", isEnable = false, isDrivenBaseField = true)
    @Column(columnName = DefaultFieldConstants.CREATE_USER, columnType = ColumnType.VARCHAR, length = SqlConstants.UUID_SIZE, comment = "创建用户主键", isSelectUse = false)
    private String createUser;
    /**
     * 更新用户主键
     */
    @FormFieldConfig(fieldCode = DefaultFieldConstants.UPDATE_USER, fieldName = "更新用户", isEnable = false, isDrivenBaseField = true)
    @Column(columnName = DefaultFieldConstants.UPDATE_USER, columnType = ColumnType.VARCHAR, length = SqlConstants.UUID_SIZE, comment = "更新用户主键", isSelectUse = false)
    private String updateUser;

    @Override
    public void initInsert() {
        super.initInsert();
        // 获取用户主键
        String accountId = UserFactory.builder().getAccountId();
        if (StringUtils.isNotEmpty(accountId)) {
            setCreateUser(accountId);
            setUpdateUser(accountId);
        }
    }

    @Override
    public void initUpdate() {
        super.initUpdate();
        // 获取用户主键
        String accountId = UserFactory.builder().getAccountId();
        if (StringUtils.isNotEmpty(accountId)) {
            setUpdateUser(accountId);
        }
    }

    public Integer getSort() {
        return sort;
    }

    public void setSort(Integer sort) {
        this.sort = sort;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    public float getVersion() {
        return version;
    }

    public void setVersion(float version) {
        this.version = version;
    }

    public String getDataState() {
        return dataState;
    }

    public void setDataState(String dataState) {
        this.dataState = dataState;
    }

    public String getCreateUser() {
        return createUser;
    }

    public void setCreateUser(String createUser) {
        this.createUser = createUser;
    }

    public String getUpdateUser() {
        return updateUser;
    }

    public void setUpdateUser(String updateUser) {
        this.updateUser = updateUser;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

}

在此内部,实现了动态赋值创建用户或更新用户信息,至于表中的主键框架内部会根据标志自动生成。至此,业已完成基础设计,以下,就可具体改造执行脚本代码,并修改相应逻辑实现。

3、自动注入嵌入

此框架使用自有操作数据库方式,笔者仅需要再SqlBuilder中实现相关代码。

    @Override
    protected <T> T getResult() throws Exception {
        if (requestInfo != null) {
            SqlRequestMessage requestInfo = (SqlRequestMessage) this.requestInfo;
            String sqlType = requestInfo.getSqlType();
            // 获取请求参数
            Object requestData = this.requestParam.getRequestParam();
            // 新增Sql语句
            if (ConfigDictionaryConstants.SqlDictionary.SQL_INSERT_TYPE_CODE.equals(sqlType)) {
                if (requestData != null) {
                    // 初始化对象
                    if (requestData instanceof IDataInfo) {
                        ((IDataInfo) requestData).initInsert();
                        // 在此处兼容map形式初始化
                    } else if (requestData instanceof Map) {
                        initInsert((Map) requestData);
                    }
                }
                // 更新sql语句
            } else if (ConfigDictionaryConstants.SqlDictionary.SQL_UPDATE_TYPE_CODE.equals(sqlType)) {
                // 初始化对象
                if (requestData instanceof IDataInfo) {
                    ((IDataInfo) requestData).initUpdate();
                    // 在此处兼容map形式初始化
                } else if (requestData instanceof Map) {
                    initUpdate((Map) requestData);
                }
            }
            return executeSqlFactory.execSql(requestInfo, requestParam, getExecutor(requestInfo.getExecutorClass()));
        }
        return null;
    }

为兼容请求参数,可能为map的形式,笔者在此类实现map的方式实现。

    /**
     * 初始化插入数据
     *
     * @param params
     * @return a
     * @author 赵屈犇
     * @date 创建时间: 2022/9/4 20:57
     * @version 1.0
     */
    protected void initInsert(Map params) {
        // 获取用户主键
        String accountId = UserFactory.builder().getAccountId();
        if (StringUtils.isNotEmpty(accountId)) {
            params.put("createUser", accountId);
            params.put("updateUser", accountId);
        }
        if (EmptyUtils.isKeyEmpty(params, "dataState")) {
            params.put("dataState", ConfigDictionaryConstants.DataStateDict.NORMAL);
        }
        // 初始化时间
        String nowTimeString = TimeUtils.getNowTimeString();
        params.put("createTime", nowTimeString);
        params.put("updateTime", nowTimeString);
    }

    /**
     * 初始化更新数据
     *
     * @param params
     * @return a
     * @author 赵屈犇
     * date 创建时间: 2022/9/4 21:00
     * @version 1.0
     */
    protected void initUpdate(Map params) {
        // 获取用户主键
        String accountId = UserFactory.builder().getAccountId();
        if (StringUtils.isNotEmpty(accountId)) {
            params.put("updateUser", accountId);
        }
        String nowTimeString = TimeUtils.getNowTimeString();
        params.put("updateTime", nowTimeString);
    }

至此,九大字段改造业已完成,后期也会基于八大字段进行做一下逻辑查询、更新、删除封装的操作,为了兼容绝大数场景,笔者还需细细思量良久。 此篇,就此结束。