jbase实现通用码表

news2024/11/13 8:03:56

没有通用码表的体系是不完美的,当年我用C#能实现的通用码表,现在在java一样的实现了,通用码表对提高开发效率和降低开发成本的作用巨大,开发可以专注写业务,而不比被太多的维护界面束缚。进而体现在产品竞争力上面,别人还是画大量时间做维护界面,我们建表了就有码表维护界面,只需要做特殊的维护界面(还是基于代码生成的基础组装)

通用码表原理看这里

通用码表离不开自己实现ORM,通过ORM解析实体的外键参照信息组装带外键列的查询,这样子表界面参照的父表名称才能显示名称而不是主键。

FK实现实例,没有实体的外键特性和ORM的底层支持,码表都是无稽之谈

 /**
     * 码表查询,不分页
     *
     * @param modelName   实体名称
     * @param param       查询条件参数,数据列名和值的键对
     * @param orderField  排序字段,如RowID Desc
     * @param returnCount 是否输出数据总行数
     * @param fields      显示字段,为空显示所有列,字段名称以英文','隔开,如:RowID,Code,Name
     * @param joiner      连接符,为空或不给则查询条件以且连接,给的话长度比参数少1
     * @param operators   操作符,为空或不给的话条件以等来判断,给的话与参数长度一致。如!=,<,>
     * @return
     */
    @Override
    public String QueryAllWithFKByName(String modelName, List<ParamDto> param, String orderField, boolean returnCount, String fields, List<String> joiner, List<String> operators) throws Exception {
        return QueryAllWithFKByName(modelName, param, orderField, returnCount, -1, -1, fields, joiner, operators);
    }


    /**
     * 根据条件+字段查询,查询结果按指定的页面把数据按JSON返回;
     * 该方法会把外键关联的字段查出来,用来取缔试图的查询
     *
     * @param model       实体对象
     * @param param       查询条件参数,数据列名和值的键对
     * @param orderFields 排序字段,如RowID Desc
     * @param returnCount 是否输出数据总行数
     * @param pageSize    页大小。为-1,无条件查所有数据
     * @param pageIndex   第几页。为-1,无条件查询所有数据
     * @param fields      显示字段,为空显示所有列,字段名称以英文','隔开,如:RowID,Code,Name
     * @param joiner      连接符,为空或不给则查询条件以且连接,给的话长度比参数少1
     * @param operators   操作符,为空或不给的话条件以等来判断,给的话与参数长度一致。如!=,<,>
     * @param <T>         限定实体类型
     * @return 查询json串
     */
    @Override
    public <T> String QueryAllWithFK(T model, HashParam param, String orderFields, boolean returnCount, int pageSize, int pageIndex, String fields, List<String> joiner, List<String> operators) throws Exception {
        List<ParamDto> pdto = null;
        if (param != null) {
            pdto = param.GetParam();
        }
        return QueryAllWithFK(model, pdto, orderFields, returnCount, pageSize, pageIndex, fields, joiner, operators);
    }

    /**
     * 根据条件+字段查询,查询结果按指定的页面把数据按JSON返回;
     * 该方法会把外键关联的字段查出来,用来取缔试图的查询
     * 不分页
     *
     * @param model       实体对象
     * @param param       查询条件参数,数据列名和值的键对
     * @param orderFields 排序字段,如RowID Desc
     * @param returnCount 是否输出数据总行数
     * @param fields      显示字段,为空显示所有列,字段名称以英文','隔开,如:RowID,Code,Name
     * @param joiner      连接符,为空或不给则查询条件以且连接,给的话长度比参数少1
     * @param operators   操作符,为空或不给的话条件以等来判断,给的话与参数长度一致。如!=,<,>
     * @param <T>         限定实体类型
     * @return 查询json串
     */
    @Override
    public <T> String QueryAllWithFK(T model, HashParam param, String orderFields, boolean returnCount, String fields, List<String> joiner, List<String> operators) throws Exception {
        List<ParamDto> pdto = null;
        if (param != null) {
            pdto = param.GetParam();
        }
        return QueryAllWithFK(model, pdto, orderFields, returnCount, fields, joiner, operators);
    }

    /**
     * 根据条件+字段查询,查询结果按指定的页面把数据按JSON返回;
     * 该方法会把外键关联的字段查出来,用来取缔试图的查询
     * 不分页
     *
     * @param model       实体对象
     * @param param       查询条件参数,数据列名和值的键对
     * @param orderFields 排序字段,如RowID Desc
     * @param returnCount 是否输出数据总行数
     * @param fields      显示字段,为空显示所有列,字段名称以英文','隔开,如:RowID,Code,Name
     * @param joiner      连接符,为空或不给则查询条件以且连接,给的话长度比参数少1
     * @param operators   操作符,为空或不给的话条件以等来判断,给的话与参数长度一致。如!=,<,>
     * @param <T>         限定实体类型
     * @return 查询json串
     */
    @Override
    public <T> String QueryAllWithFK(T model, List<ParamDto> param, String orderFields, boolean returnCount, String fields, List<String> joiner, List<String> operators) throws Exception {
        return QueryAllWithFK(model, param, orderFields, returnCount, -1, -1, fields, joiner, operators);
    }

    /**
     * 根据条件+字段查询,查询结果按指定的页面把数据按JSON返回;
     * 该方法会把外键关联的字段查出来,用来取缔试图的查询
     *
     * @param model       实体对象
     * @param param       查询条件参数,数据列名和值的键对
     * @param orderFields 排序字段,如RowID Desc
     * @param returnCount 是否输出数据总行数
     * @param pageSize    页大小。为-1,无条件查所有数据
     * @param pageIndex   第几页。为-1,无条件查询所有数据
     * @param fields      显示字段,为空显示所有列,字段名称以英文','隔开,如:RowID,Code,Name
     * @param joiner      连接符,为空或不给则查询条件以且连接,给的话长度比参数少1
     * @param operators   操作符,为空或不给的话条件以等来判断,给的话与参数长度一致。如!=,<,>
     * @param <T>         限定实体类型
     * @return 查询json串
     */
    @Override
    public <T> String QueryAllWithFK(T model, List<ParamDto> param, String orderFields, boolean returnCount, int pageSize, int pageIndex, String fields, List<String> joiner, List<String> operators) throws Exception {
        //json数据组装容器
        StringBuilder jsonsb = new StringBuilder();
        //查询起始行数
        int fromRow = -1;
        //查询结束行数
        int toRow = -1;
        //是否查询全部数据
        boolean findAll = false;
        //记录总行数
        int rowCount = 0;
        if (fields != null && !fields.isEmpty()) {
            fields = "," + fields + ",";
        }
        //如果未传入分页数据其中一个未-1,则认为部分页而查询所有数据
        if (pageIndex == -1 || pageSize == -1) {
            findAll = true;
        }
        //计算查询起始和结束行数
        else {
            fromRow = (pageIndex - 1) * pageSize;
            toRow = pageIndex * pageSize;
        }
        PreparedStatement pstat = null;
        ResultSet rst = null;
        LIS.DAL.ORM.Common.TableInfo tableInfo = LIS.DAL.ORM.Common.ModelToSqlUtil.GetTypeInfo(model);

        //根据表信息将查询参数组装成Select SQL
        String sql = LIS.DAL.ORM.Common.ModelToSqlUtil.GetSelectSqlByTableInfo(Manager().GetIDbFactory(factoryName), tableInfo, param, operators, joiner, orderFields, true, -1);
        //写SQL日志
        LIS.Core.Util.LogUtils.WriteSqlLog("执行QueryAllWithFK返回String查询SQL:" + sql);
        //如果返回总行数,返回总行数写法
        if (returnCount) {
            jsonsb.append("{");
            jsonsb.append("\"rows\":[");
        }
        //否则采用普通数组写法
        else {
            jsonsb.append("[");
        }
        StringBuilder rowAllsb = new StringBuilder();
        try {
            pstat = Manager().Connection().prepareStatement(sql);
            String paraSql = DBParaUtil.SetDBPara(pstat, param);
            rst = pstat.executeQuery();
            LIS.Core.Util.LogUtils.WriteSqlLog("参数:" + paraSql);
            //标识是否第一行
            boolean isFirstRow = true;
            while (rst.next()) {
                rowCount++;     //总行数加一
                //查询全部,或者取分页范围内的记录
                if (findAll || (rowCount > fromRow && rowCount <= toRow)) {
                    ResultSetMetaData metaData = rst.getMetaData();
                    //获取列数
                    int colCount = metaData.getColumnCount();
                    //单行数据容器
                    StringBuilder rowsb = new StringBuilder();
                    rowsb.append("{");
                    //标识是否第一列
                    boolean isFirstCol = true;
                    for (int coli = 1; coli <= colCount; coli++) {
                        //获取列名
                        String colName = metaData.getColumnName(coli);
                        //获取列值
                        Object colValue = rst.getObject(coli);
                        if (colValue == null) colValue = "";
                        //如果传了显示的字段,过滤不包含的字段
                        if (fields != null && !fields.isEmpty() && fields.indexOf("," + colName + ",") < 0) {
                            continue;
                        }
                        if (isFirstCol) {
                            rowsb.append("\"" + colName + "\":");
                            rowsb.append("\"" + JsonHelper.DealForJsonString(colValue.toString()).toString() + "\"");
                            isFirstCol = false;
                        } else {
                            rowsb.append(",");
                            rowsb.append("\"" + colName + "\":");
                            rowsb.append("\"" + JsonHelper.DealForJsonString(colValue.toString()).toString() + "\"");
                        }
                    }
                    rowsb.append("}");
                    if (isFirstRow) {
                        rowAllsb.append(rowsb.toString());
                        isFirstRow = false;
                    } else {
                        rowAllsb.append(",");
                        rowAllsb.append(rowsb.toString());
                    }
                }
            }
        } catch (Exception ex) {
            //查询异常清空数据记录容器
            rowAllsb.delete(0, rowAllsb.length());
        }
        //操作结束释放资源,但是不断连接,不然没法连续做其他数据库操作了
        finally {
            if (rst != null) {
                rst.close();
            }
            if (pstat != null) {
                pstat.close();
            }
            //如果上层调用未开启事务,则调用结束释放数据库连接
            if (!Manager().Hastransaction) {
                manager.Close();
            }
        }
        //组装数据记录
        jsonsb.append(rowAllsb.toString());
        //补充数组结尾符
        jsonsb.append("]");
        if (returnCount) {
            jsonsb.append(",");
            jsonsb.append("\"total\":");
            jsonsb.append(rowCount);
            jsonsb.append("}");
        }
        return jsonsb.toString();
    }

然后反射得到实体jar包的所有实体类供码表管理器展示表

package LIS.DAL.ORM.DBUtility;

import LIS.DAL.ORM.Common.ModelInfo;
import LIS.DAL.ORM.Common.ModelToSqlUtil;
import LIS.DAL.ORM.Common.TableInfo;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;

/**
 * 给码表取实体信息工具类
 */
public class ModelInfoUtil {

    /**
     * 得到所有的实体信息
     * @return
     */
    public static String GetAllModelJson() throws Exception
    {
        List<ModelInfo> retList=new ArrayList<>();
        //得到实体的所有类
        List<Class> list=LIS.Core.Util.ReflectUtil.GetAllType("LIS.Model","LIS.Model.Entity");
        if(list!=null&&list.size()>0)
        {
            for(int i=0;i<list.size();i++)
            {
                Class c=list.get(i);
                Object m=c.getConstructor().newInstance();
                ModelInfo model=new ModelInfo();
                TableInfo tableInfo=ModelToSqlUtil.GetTypeInfo(m);
                model.Name=c.getSimpleName();
                if(tableInfo.TableInfo!=null)
                {
                    model.Remark=tableInfo.TableInfo.Remark();
                    model.TableName=tableInfo.TableInfo.Name();
                    model.PropNames=new ArrayList<>();
                    for(int j=0;j<tableInfo.ColList.size();j++)
                    {
                        model.PropNames.add(tableInfo.ColList.get(j).Name);
                    }
                }
                retList.add(model);
            }
        }
        return LIS.Core.Util.JsonUtil.Object2Json(retList);
    }

}

反射得到所有实体

package LIS.Core.Util;

import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * 反射工具类
 */
public class ReflectUtil {
    /**
     * 设置对象指定属性名字的值
     * @param obj 对象
     * @param name 属性名称
     * @param val 属性值
     */
    public static void SetObjValue(Object obj,String name,Object val)
    {
        try {
            Class c = obj.getClass();
            //得到列信息
            Field declaredField = c.getDeclaredField(name);
            //布尔的处理
            if(declaredField.getType()==Boolean.class) {
                if(val.toString().equals("1"))
                {
                    val=Boolean.TRUE;
                }
                else if(val.toString().equals("0"))
                {
                    val=Boolean.FALSE;
                }
                else
                {
                    val=null;
                }
            }
            //布尔的处理
            else if(declaredField.getType()==boolean.class) {
                if(val.toString().equals("1"))
                {
                    val=true;
                }
                else if(val.toString().equals("0"))
                {
                    val=false;
                }
                else
                {
                    val=true;
                }
            }
            //int的处理
            else if(declaredField.getType()==int.class) {
                if(val==null)
                {
                    val=0;
                }
            }
            //数字的处理
            else if(declaredField.getType()==Integer.class||declaredField.getType()==Double.class||declaredField.getType()==Float.class) {
                if(val.toString().isEmpty())
                {
                    val=null;
                }
            }
            declaredField.set(obj, val);
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }
    }

    /**
     * 用类型全名和程序集全名获得类型
     * @param typeName 类型全面
     * @param assemblyName 程序集名
     * @return 类型
     */
    public static Class GetType(String typeName, String assemblyName)
    {
        try {
            //得到根路径
            Class<?> clazz = ReflectUtil.class;
            ClassLoader classLoader = clazz.getClassLoader();
            URL resourceURL1 = classLoader.getResource("");
            String bashePath = resourceURL1.getFile();
            //组装成jar包路径
            String jarPath=bashePath+assemblyName+".jar";
            File file = new File(jarPath);
            if (!file.exists()) {
                throw new Exception("未能找到"+jarPath+"的文件");
            }
            //反射得到类型
            //自己生成jar包路径
            URL url = file.toURI().toURL();
            URL[] urls = new URL[]{url};
            //加载程序集
            URLClassLoader loader = new URLClassLoader(urls, ReflectUtil.class.getClassLoader());
            //加载类
            Class c = loader.loadClass(typeName);
            if(c!=null)
            {
                return  c;
            }
            else
            {
                throw new Exception("未能构建类型"+typeName);
            }
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }
        return  null;
    }

    /**
     * 得到jar包下所有类
     * @param assemblyName jar包名称
     * @param packageName 包名
     * @return
     */
    public static List<Class> GetAllType(String assemblyName,String packageName) throws Exception
    {
        List<Class> classes = new ArrayList<>();
        try {
            //得到根路径
            Class<?> clazz = ReflectUtil.class;
            ClassLoader classLoader = clazz.getClassLoader();
            URL resourceURL1 = classLoader.getResource("");
            String bashePath = resourceURL1.getFile();
            //组装成jar包路径
            String jarPath=bashePath+assemblyName+".jar";
            File file = new File(jarPath);
            if (!file.exists()) {
                throw new Exception("未能找到"+jarPath+"的文件");
            }
            //反射得到类型
            //自己生成jar包路径
            URL url = file.toURI().toURL();
            URL[] urls = new URL[]{url};
            //加载程序集
            URLClassLoader loader = new URLClassLoader(urls, ReflectUtil.class.getClassLoader());
            try (JarFile jarFile = new JarFile(jarPath)) {
                Enumeration<JarEntry> entries = jarFile.entries();
                while (entries.hasMoreElements()) {
                    JarEntry entry = entries.nextElement();
                    if (entry.getName().endsWith(".class")) {
                        String className = entry.getName().replace(".class", "").replace("/", ".");
                        Class c = loader.loadClass(className);
                        classes.add(c);
                    }
                }
            }
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }
        return  classes;
    }
}

码表后台实现,按传入的实体名称反射查询带外键的数据供界面展示
在这里插入图片描述

解析表的信息供前端渲染界面

package LIS.DAL.ORM.Common;
import LIS.Core.CustomAttributes.FrekeyAttribute;
import LIS.Core.CustomAttributes.IdAttribute;
import LIS.Core.CustomAttributes.NotNullAttribute;
import LIS.Core.CustomAttributes.UniqueAttribute;
import jdk.jshell.execution.Util;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;

/**
 * 通用码表的界面配置实体
 */
public class ModelConfig
    {
        /**
         * 实体名称
         */
        public String ModelName;


        /**
         * 实体显示名称
         */
        public String ShowModelName;

        /**
         * 是否分页
         */
        public Boolean Pagination;

        /**
         * 页面显示行数
         */
        public int PageSize;

        /**
         * 是否适应屏幕显示
         */
        public Boolean fitColumns;

        /**
         * 是否显示行号
         */
        public Boolean rowNumber;

        /**
         * 实体属性
         */
        public List<ModelProperty> ModelPropertys;

        /**
         * 编辑窗口的宽度
         */
        public int Width;

        /**
         * 编辑窗口的高度
         */
        public int Height;

        /**
         * 编辑窗口的标签宽度
         */
        public int LabelWidth;

        /**
         * 最大行
         */
        public int MaxRowLen = 8;

        /**
         * 唯一列要求
         */
        public List<String> UniqueColumns;

        /**
         * 默认排序串
         * @return
         */
        public String SortNames()
        {
            String ret = "";
            for(int i=0;i<ModelPropertys.size();i++)
            {
                ModelProperty pro=ModelPropertys.get(i);
                if (pro.PropertyName == "Sequence" && ModelName != "BTHRStaff")
                {
                    ret = "Sequence";
                }
                else if (pro.PropertyName == "SeqNum" && ModelName != "BTHRStaff")
                {
                    ret = "SeqNum";
                }
            }
            if (ret == "")
            {
                ret = "RowID";
            }
            return ret;
        }

        /**
         * 停靠
         */
        public enum DisplayPosition
        {
            CENTER, LEFT, RIGHT
        }

        /**
         * 输入框类型
         */
        public enum InputType
        {
            TEXT, SELECT, FR_SELECT, DETAIL_TABLE
        }

        /**
         * 列的数据类型
         */
        public enum ColumnType
        {
            INT, STRING, BOOL, FLOAT, DOUBLE, OTHER
        };

        /**
         * 属性类
         */
        public class ModelProperty
        {
            /**
             * 属性名称
             */
            public String PropertyName;

            /**
             * 属性显示名称
             */
            public String ShowPropertyName;

            /**
             * 是否显示
             */
            public Boolean IsShow;

            /**
             * 显示宽度
             */
            public int ShowWidth;

            /**
             * 是否是表的详细列
             */
            public boolean IsDtTable = false;

            /**
             * 是否禁止选择
             */
            public boolean IsDisable = false;

            /**
             * 禁止选择的制定值
             */
            public String DisableVal;

            /**
             * 停靠CENTER, LEFT, RIGHT
             */
            public DisplayPosition DisplayPosition;

            /**
             * 显示位置
             */
            public DisplayPosition ShowPosition;

            /**
             * 输入框类型TEXT, SELECT, FR_SELECT, DETAIL_TABLE
             */
            public InputType InputType;

            /**
             * 编辑类型
             */
            public InputType EditType;

            /**
             * 编辑样式
             */
            public String EditStyle;

            /**
             * 数据类型
             */
            public ColumnType DataType;

            /**
             * 最大长度
             */
            public int MaxLength;

            /**
             * 限选数据,用于枚举
             */
            public Hashtable Selects;

            /**
             * 限选数据串
             */
            public String SelectsStr;

            /**
             * 序号
             */
            public int Sequence;

            /**
             * 是否为主键
             */
            public boolean IsId;

            /**
             * 是否为主键
             */
            public boolean IsFK;

            /**
             * 是否是系统强制要求必填
             */
            public boolean IsMustRequire;

            /**
             * 是否必填
             */
            public boolean IsRequire;

            /**
             * 是否关联外键
             */
            public ModelPropertyFK PropertyFK;

            /**
             * 外键内部类
             */
            public class ModelPropertyFK
            {
                /**
                 * 外键实体名称
                 */
                public String FkModelName;

                /**
                 * 外键关联字段
                 */
                public String FefColumnName;

                /**
                 * 外键拉取知道
                 */
                public String AssociaField;

                /**
                 * 外键选择数据,8.4废弃
                 */
                public Hashtable FkSelects;    //外键相关的所有数据

                /**
                 * 构造
                 */
                public ModelPropertyFK()
                {
                }

                /**
                 * 构造
                 * @param FkModelName 参照的表实体
                 * @param FefColumnName 参照列
                 * @param AssociaField 拉取列
                 */
                public ModelPropertyFK(String FkModelName, String FefColumnName, String AssociaField)
                {
                    this.FkModelName = FkModelName;
                    this.FefColumnName = FefColumnName;
                    this.AssociaField = AssociaField;
                }
            }


            /**
             * 构造
             */
            public ModelProperty()
            {
            }

            /**
             * 构造
             * @param pi
             */
            public ModelProperty(Field pi)
            {
                this.PropertyName = pi.getName();
                this.ShowPropertyName = pi.getName();
                this.IsShow = true;
                this.ShowWidth = 100;
                this.ShowPosition = DisplayPosition.CENTER;
                this.EditType = InputType.TEXT;
                this.EditStyle = "";
                this.MaxLength = 80;

                if (pi.getType() == int.class || pi.getType() == Integer.class)
                {
                    this.DataType = ColumnType.INT;
                }
                else if (pi.getType() == float.class || pi.getType() == Float.class)
                {
                    this.DataType = ColumnType.FLOAT;
                }
                else if (pi.getType() == double.class || pi.getType() == Double.class)
                {
                    this.DataType = ColumnType.DOUBLE;
                }
                else if (pi.getType() == boolean.class || pi.getType() == Boolean.class)
                {
                    this.DataType = ColumnType.BOOL;
                }
                else if (pi.getType() == String.class)
                {
                    this.DataType = ColumnType.STRING;
                }
                else
                {
                    this.DataType = ColumnType.OTHER;
                }
                if (pi.getName().endsWith("Date") || pi.getName().endsWith("Time"))
                {
                    //给定默认的宽度
                    this.EditStyle = "width:146px;";
                }
                this.Selects = new Hashtable();
                this.SelectsStr = LIS.Core.Util.JsonUtil.Object2Json(this.Selects);

                if (pi.getType() == boolean.class || pi.getType() == Boolean.class)
                {
                    this.EditType = InputType.SELECT;
                    this.EditStyle = "width:146px;";
                    this.DataType = ColumnType.BOOL;
                    this.Selects.put("1", "true");
                    this.Selects.put("0", "false");
                    this.SelectsStr = "{\"1\":\"true\",\"0\":\"false\"}";
                }

                //返回所有自定义特性
                Annotation[] propertyAttrs = pi.getAnnotations();
                //遍历所有自定义特性
                for (int i = 0; i < propertyAttrs.length; i++)
                {
                    //获取当前的自定义特性
                    Annotation propertyAttr = propertyAttrs[i];
                    //如果是主键特性
                    if (propertyAttr instanceof IdAttribute)
                    {
                        this.IsId = true;
                    }
                    //如果是外键特性
                    else if (propertyAttr instanceof FrekeyAttribute)
                    {
                        this.IsFK = true;
                        FrekeyAttribute fkAttr = (FrekeyAttribute)propertyAttr;
                        this.PropertyFK = new ModelPropertyFK(fkAttr.Name(), fkAttr.RefColumnName(), fkAttr.AssociaField());
                        //给定默认的宽度
                        this.EditStyle = "width:146px;";
                    }
                    //是否必填
                    else if (propertyAttr instanceof NotNullAttribute)
                    {
                        this.IsRequire = true;
                        this.IsMustRequire = true;
                    }
                }
            }

            //将字符串形式的选择数据转换为Map(hashtable)
            public void SetSelects()
            {
                this.Selects = (Hashtable) LIS.Core.Util.JsonUtil.Json2Object(this.SelectsStr,Hashtable.class);
            }

        }


        /**
         * 空构造函数
         */
        public ModelConfig()
        {
        }

        /**
         * 根据类型初始化配置文件
         * @param type
         */
        public ModelConfig(Class type)
        {
            this.ModelName = type.getSimpleName();
            this.ShowModelName = type.getSimpleName();
            this.Pagination = true;
            this.PageSize = 20;

            this.rowNumber = false;
            this.Width = 600;
            this.Height = 400;
            this.LabelWidth = 240;
            this.UniqueColumns = new ArrayList<>();
            this.ModelPropertys = new ArrayList<>();

            Field[] propertyInfos = type.getFields();
            if (propertyInfos.length > 10)
            {
                this.fitColumns = false;
            }
            else
            {
                this.fitColumns = true;
            }
            if (propertyInfos.length == 0)
            {
                return;
            }
            ModelProperty mp = null;
            for(int i=0;i<propertyInfos.length;i++)
            {
                Field pi=propertyInfos[i];
                mp = new ModelProperty(pi);
                this.ModelPropertys.add(mp);
            }
            //读取唯一组合键
            Annotation[] attrs = type.getAnnotations();
            for(int i=0;i<attrs.length;i++)
            {
                Annotation attr=attrs[i];
                if(attr instanceof UniqueAttribute)
                {
                    //as转换类型
                    UniqueAttribute attr_ = (UniqueAttribute)attr;
                    if (attr_.ColNames().toLowerCase().equals("RowID".toLowerCase()))
                    {
                        continue;
                    }
                    //得到w唯一组合键
                    this.UniqueColumns.add(attr_.ColNames().replace(',', '+'));
                }

            }
        }

    }

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

基于此,只要实力足够强劲,即可实现通用码表,我带来的独创设计。框架实现到检验目前同水准或者超越的时候,借助脚本化、码表、代码生成、打印导出、模板设计器、虚拟M脚本这些实现、足以搅局整个需求型软件行业,我熟悉的是医疗;效率和发布型的架构相比就是高很多。

框架计划
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Radiology 谈人工智能在放射学领域的10个预测方向 [文献阅读]

人工智能(AI)和信息学正在改变放射学。十年前&#xff0c;没有哪个专家会预测到今天放射人工智能行业的蓬勃发展&#xff0c;100多家人工智能公司和近400种放射人工智能算法得到了美国食品和药物管理局(FDA)的批准。 不到一年前&#xff0c;即使是最精明的预言家也不会相信这些…

Figma插件合集大放送,效果嘎嘎棒!

近日&#xff0c;Figma被Adobe收购的消息在设计领域引起了极大的轰动。作为海外知名的设计工具&#xff0c;Figma对设计圈的影响不容小觑。Figma插件是设计师选择Figma的重要原因。然而&#xff0c;设计软件是一个快速更新和迭代的行业。在关注海外设计软件的同时&#xff0c;也…

python中的字符串转字节码

res int.from_bytes(hello.encode(), byteorderlittle)res的结果为478560413032&#xff0c;这个结果怎么计算得到的呢&#xff1f; 将hello的每个字母的ascii码从右往左排列&#xff0c;拼接起来转成十进制就是res的结果。 拼接的结果为&#xff1a;011011110110110001101100…

JWT登录认证(1登录)

JwtUtil package com.lin.springboot01.utils; import com.auth0.jwt.JWT; import com.auth0.jwt.algorithms.Algorithm; import java.util.Date; import java.util.Map;public class JwtUtil {private static final String KEY "liner2332";//接受业务数据&#xf…

【Mycat2实战】二、Mycat安装部署

1. Mycat下载 Mycat官网下载地址&#xff0c;点击直接前往&#xff1a;http://www.mycat.org.cn/ Mycat 有提供编译好的安装包&#xff0c;支持 windows、Linux、Mac、 Solaris 等系统上安装与运行。 本文及后续系列的文章都是使用Linux的系统进行操作。 这里我们选择使用文…

Leetcode周赛371补题(3 / 3)

目录 1、找出强数对的最大异或值 - 暴力 2、高访问员工 - 哈希表 模拟 3、最大化数组末位元素的最少操作次数 - 思维 贪心 1、找出强数对的最大异或值 - 暴力 找出强数对的最大异或值 I class Solution {public int maximumStrongPairXor(int[] a) {int na.length,max0;…

Linux 小程序-进度条

1.进度条准备知识 1.1回车与换行 以前的键盘会有一个这样的按键 &#xff0c;这个键就是回车与换行。 回车&#xff1a;从当前行回退到当前行的起始位置。 换行&#xff1a;从当前行切换到下一行的该位置。 有了以上的认识我们可以写出一个简单的倒计时代码&#xff1a; 注意&a…

如何掌握项目管理的5个阶段?

项目管理协会&#xff08;PMI&#xff09;创建了一个五步项目管理流程&#xff0c;即从启动、规划、执行、监控到结束&#xff0c;为项目经理更好地管理项目提供了现成的基础。如果你正为范围蔓延、返工或项目总体混乱而苦恼&#xff0c;那么遵循项目管理的五个阶段&#xff0c…

【装包拆包----泛型】

文章目录 装箱和拆箱泛型创建一个泛型数组泛型的上界泛型方法 装箱和拆箱 装箱&#xff1a; 把基本数据类型给到引用数据类型 public static void main(String[] args) {//自动装包//第一种装包Integer c 12;//第二种装包int a 7;Integer b a;//显示装包Integer aa Intege…

什么是自动化测试框架?

无论是在自动化测试实践&#xff0c;还是日常交流中&#xff0c;经常听到一个词&#xff1a;框架。之前学习自动化测试的过程中&#xff0c;一直对“框架”这个词知其然不知其所以然。 最近看了很多自动化相关的资料&#xff0c;加上自己的一些实践&#xff0c;算是对“框架”…

应用协议安全:Rsync-common 未授权访问.

应用协议安全&#xff1a;Rsync-common 未授权访问. Rsync 是 Linux 下一款数据备份工具&#xff0c;支持通过 rsync 协议、ssh 协议进行远程文件传输。其中 rsync 协议默认监听 873 端口&#xff0c;如果目标开启了 rsync 服务&#xff0c;并且没有配置 ACL 或访问密码&#…

Node.js 安装配置

文章目录 安装检测Node是否可用 安装 首先我们需要从官网下载Node安装包:Node.Js中文网,下载后双击安装没有什么特殊的地方&#xff0c;安装路径默认是C盘&#xff0c;不想安装C盘的话可以选择一下其他的盘符。安装完成以后可以不用配置环境变量&#xff0c;Node安装已经自动给…

【算法总结】归并排序专题(刷题有感)

思考 一定要注意归并排序的含义&#xff0c;思考归并的意义。 主要分为两个步骤&#xff1a; 拆分 每次对半分(mid l r >> 1)输入&#xff1a;raw整块&#xff0c;输出&#xff1a;raw左块 raw右块 合并 每次都要对raw左块、 raw右块按照某种规则进行合并输入&#xf…

计算机基础知识53

模板之过滤器 # HTML被直接硬编码在 Python代码之中&#xff0c;Django的 模板系统(Template System) # 过滤器给我们提供的有六十多个&#xff0c;但是我们只需要掌握10个以内即可 过滤器名称就是函数名 # 语法&#xff1a;{{ obj|filter__name:param }} 变量名字…

多个Obj模型合并

MergeObj&#xff08;合并Obj模型&#xff09; 1 概述 由于项目原因&#xff0c;需要下载谷歌地图上的模型&#xff0c;关于谷歌模型下载的&#xff0c;见我的CSDN博客. 由于下载谷歌地图上的数据&#xff0c;会分多个模块下载。下载完成后&#xff0c;怎么合并&#xff0c;在…

电脑检测温度软件有哪些?

环境&#xff1a; Win10 专业版 问题描述&#xff1a; 电脑检测温度软件有哪些&#xff1f; 解决方案&#xff1a; 有很多电脑检测温度的软件可供选择&#xff0c;以下是一些常用的电脑温度监测工具&#xff1a; HWMonitor&#xff1a;一款免费的硬件监控软件&#xff0…

快速生成力扣链表题的链表,实现快速调试

关于力扣链表题需要本地调试创建链表的情况 我们在练习链表题&#xff0c;力扣官方需要会员&#xff0c;我们又不想开会员&#xff0c;想在本地调试给你们提供的代码 声明&#xff1a;本人也是参考的别人的代码&#xff0c;给你们提供不同语言生成链表 参考链接&#xff1a; 参…

正则表达式入门教程

一、本文目标 让你明白正则表达式是什么&#xff0c;并对它有一些基本的了解&#xff0c;让你可以在自己的程序或网页里使用它。 二、如何使用本教程 文本格式约定&#xff1a;专业术语 元字符/语法格式 正则表达式 正则表达式中的一部分(用于分析) 对其进行匹配的源字符串 …

01背包 D. Make Them Equal

Problem - D - Codeforces 输出值不超过k次操作后的最大值。 看b数组的大小&#xff0c;b数组元素是小于1000的正整数。从1到bi如果可以&#xff0c;那么最多是大概10次的&#xff0c;因为是指数递增的&#xff0c;例如&#xff1a;1 -> 2 -> 4 -> 8 -> 16 -> …

12-使用vue2实现todolist待办事项

个人名片&#xff1a; &#x1f60a;作者简介&#xff1a;一名大二在校生 &#x1f921; 个人主页&#xff1a;坠入暮云间x &#x1f43c;座右铭&#xff1a;懒惰受到的惩罚不仅仅是自己的失败&#xff0c;还有别人的成功。 &#x1f385;**学习目标: 坚持每一次的学习打卡 文章…