低代码开发平台搭建思考与实战

什么是低代码开发平台?

低代码开发平台是一种平台软件,人们能通过它提供的图形化配置功能,快速配置出满足各种特定业务需求的功能软件。
具有以下特点:

  • 提供可视化界面进行程序开发
  • 0代码或少量代码快速生成应用

什么是低代码产品唯一不可缺少的功能?

很多人认为是可视化编辑,那么非可视化编辑就是代码编辑。既然可视化编辑是低代码平台必不可少的功能,那可视化编辑就是低代码平台的必要条件。

生成代码的方案算不算低代码?

通过生成代码的方式实现的方案,可以和专业开发整合,因此灵活性强、可以使用原有的开发流程,本质上和专业开发一样。
缺点是:

  • 强依赖研发,上线的代码需要编译,无法给非专业人士用
  • 无法做到持续的可视化编辑
  • 无法生成过度复杂的代码
  • 绑定生成代码的框架,无法做到兼容

低代码平台不适合开发的应用有哪些?

  • 算法逻辑复杂的应用,比如LeetCode题、ACM比赛
  • 界面要求高的应用,比如游戏、抖音等
  • 头部互联网级应用,这些访问量巨大,性能优化要求高
  • 分析和智能化应用,这些应该用更专业的BI工具
  • 系统软件、科学计算等其他专业性很强的应用。

低代码平台能提高多快的开发效率?

用低代码做一些小系统确实挺快,但并没有分析机构给出可靠的评估,根据初步经验,提升1到2倍算是一个比较合理的预期。

既然低代码开发工具可以帮助开发者快速生成基础的代码结构,减少重复劳动,提高开发效率,那么我们现在开始尝试搭建一个低代码开发工具。

下面是一个基本的设计思路,分为几个主要部分来考虑:

一、 需求分析

(一)目标用户

明确你的低代码生成工具是为哪些人服务的,比如无计算机基础用户、前端开发者、后端开发者或全栈开发者。

作为开发者,注意我们现在开发的低代码工具不是给0专业知识的外行人士使用的,而是给自己用的,是面向具有计算机专业知识的开发者使用的,是为提高开发者效率的工具,生成的是代码,而不是拖拽直接生成功能。

面对开发者的话,对于小公司而言,一般全栈开发者较多,因此生成的代码会涉及到前后端的代码。

(二)应用场景

了解用户在什么场景下会使用这个工具,例如生成API接口、数据库表结构、简单的页面等。

在前后端分离的项目中,后端程序提供api接口完成各项功能,前端应用访问api接口获取数据并给用户展示各种界面。

作为即将开发的代码生成工具的使用者,我们在以下场景使用该工具:

  • 希望不编写SQL语句,直接通过界面设计数据库表
  • 通过已有模型一键生成各层后端代码,该代码包含简单的增删查改功能
  • 由于字段属性较多,编写比较繁琐,可以根据字段信息和模板直接生成页面文件
  • 若字段有增减,可以快速生成各层代码

(三)功能需求

根据目标用户和应用场景,列出需要实现的具体功能。

1.数据库表生成

  • 生成数据库表
  • 增减字段信息

2.后端代码生成

  • 生成api接口controller类
  • 生成服务service类
  • 生成entity实体
  • 生成mapper类

3.前端代码生成

  • 生成访问接口js文件
  • 生成页面文件(列表、详情)

4.自动注册

  • 注册页面菜单
  • 注册功能
  • 注册权限

二、 技术选型

框架:Spring Boot作为基础框架,提供快速开发的能力。
模板引擎:如Thymeleaf、Freemarker或Velocity等,用于生成代码模板。
数据库:如果需要存储配置信息,可以选择MySQL、PostgreSQL等关系型数据库,或者MongoDB等NoSQL数据库。
前端技术:React、Vue或Angular等现代前端框架,用于构建用户界面。

(一)关于前端代码的生成方案

前端的生成方案有很多开源架构可以利用,例如阿里的low-code。

但是目前暂定使用模板引擎生成。

(二)关于后端代码的生成方案

后端的生成方案也有很多开源架构可以利用,例如mybatis-plus-generator。

该工具是通过读取数据库表,也是利用了模板引擎技术,来帮我们生成一系列controller、service、serviceImpl、entity、mapper文件快速实现单表增删查改的功能。

由于我们现在是生成前后端代码,同时后端代码不一定是MVC分层架构,该工具自带的功能不够用,所以这里我们自行通过模板引擎技术实现。

在代码生成中需要面临一系列的问题,考虑以下几点:

1.选择什么数据库类型?

(1)方案1:直接使用关系型数据库

比如添加了一个字段,系统会自动生成表结构变更语句:

ALTER TABLE 'blog' ADD 'title' varchar(255) NULL;

该方案优点是:

  • 性能高、灵活性强
  • 支持直连外部数据库,对接已有的外部系统
    缺点是:
  • 需要账号有创建用户和DDL的权限。
  • 实现成本较高,需要实现「动态实体」功能,如果要支持不同数据库还得支持各种方言。

实现该方案的关键是「动态实体」,在专业开发中实体(Entity)定义都是静态的,以 Java 为例,它从 2006 年开始就有专门的 JPA 规范,但这个规范是定义基于 Java 代码注解,使得需要经过编译才能使用,毕竟它的定位是面向专业开发,只有写在代码里才能支持代码提示,提升开发体验,而低代码平台中需要将这个实体定义抽象成配置,在运行时动态生成实体,如果使用 JPA 就需要生成 Java 代码后进行编译,这很容易出错,不太适合低代码平台,所以使用这个方案需要实现「动态实体」功能,是整个方案最大难点。

(2)方案2:使用文档型数据库

不需要预先定义表结构,因此它很适合用来存储用户自定义数据,这个方案实现起来比较简单,例如 MongoDB 为例,可以这样做:用户创建一个自定义表的时候,系统就自动创建一个 collection,所有这个表的数据都存在这个 collection 里。

用户新增字段的时候,就随机分配一个 fileId,后续对这个字段的操作都自动映射到这个 fileId 上,用 fileId 的好处是用户重命名字段后还能查找之前的数据,因为所有数据查询底层都基于这个 fileId。

查询的时候先找到对应的 collection,再通过 meta 信息查询字段对应的 fileId,使用这个 fileId 来获取数据。

这个方案的优点是:实现简单,用户体验可以做得更好,是目前大部分零代码平台的选择

但这个方案也有显著缺点:

  • 无法支持外部数据库,数据是孤岛,外部数据接入只能通过导入的方式。
  • MongoDB 在国内发展缓慢,接受度依然很低,目前还没听说有哪家大公司里最重要的数据存在 MongoDB 里
  • 不支持高级 SQL 查询。
2.程序开发需要做什么?

假设我们要开发一个客户管理系统,暂时不考虑低代码开发平台,往常我们的工作应该包括:

  • 设计数据结构:比如描述一位客户的信息,包括姓名、性别、出生日期、证件类型、证件号、手机号和地址
  • 设计服务:比如客户的增删查改,身份证号长度的校验,出生日期是否一致
  • 设计数据库:数据库的多张表,每张表不同字段,对应于不同模型
  • 设计流程:修改客户信息可能需要经过一套流程,一个用户录入客户信息,下一个用户对录入的客户信息作审核
  • 设计界面,方便用户能够通过图形化界面操作系统
    在这里插入图片描述
3.程序开发有哪些痛点?

问题来了,现实的软件需求会频繁发生变化,例如,为客户数据结构增加一个属性或者字段,对应的服务、数据库结构、界面、流程都要做相应的修改,还要经过测试。因此,会有以下缺点:

  • 开发周期比较长,开发工作量将倍增。
  • 若多个用户的需求差异较大,那么几乎要为每一个用户重新开发一套系统。
  • 不同用户之间,例如,个人客户是对自然人的管理,企业客户是对企业法人的管理。它们的操作界面、数据库结构、服务和流程都是独立开发、互不相关的。实际上应该可以共用代码。

低代码开发平台由于是提高我们效率的开发工具,因此如果有哪些是出现重复的代码,应该做成模板文件,快速生成。若属性频繁变化,应该修改模型后快速生成来应对这种变化,工具应该具有很强的通用性。

三.、系统架构

前端界面:提供给用户的图形化操作界面,包括项目配置、模板选择、参数设置等功能。
后端服务:
API接口:供前端调用,处理业务逻辑。
代码生成器:核心模块,根据用户配置和模板生成代码。
配置管理:管理和持久化用户的配置信息。
数据模型:定义系统中使用的实体类,如项目、模板、配置等。

四、 功能实现

项目管理:创建、编辑、删除项目,项目信息的保存。
模板管理:内置多种模板供用户选择,支持自定义模板上传。
代码生成:基于用户选择的模板和输入的参数,动态生成代码。
预览与下载:生成的代码可以在线预览,并提供下载功能。

(一)生成数据库表结构

1.生成数据库表

(1)准备sql语句

要支持生成数据库表结构,因此代码中要提前写入sql语句支持生成数据库表。

public void createTableIfNotExists(String tableName, String showName) {
    String sql = "CREATE TABLE " + tableName + " ("
            + "id bigint auto_increment primary key, "
            + "version int NOT NULL, "
            + "del_flag bit default 0 NOT NULL, "
            + "create_time datetime(6) NOT NULL, "
            + "create_by varchar(255) NOT NULL, "
            + "update_time datetime(6), "
            + "update_by varchar(255) "
            + ") engine=innodb default charset=utf8mb4 comment '" + showName + "';";
    jdbcTemplate.execute(sql);
}

但是根据数据库类型的不同,如mysql、sqlserver、oracle等,准备的sql语句也不同。
在这里插入图片描述

(2)其它

除了生成数据库表,还应该支持删除数据库表、更改数据库表名称、创建视图、设置表权限、设置列索引等。
在这里插入图片描述
另外可以扩展通过excel表、文本文件导入创建数据库等。

这些都是细枝末节,可以通过准备的sql语句实现。

2.设置字段

(1)添加字段

类似地,通过准备sql语句接受表名、字段名、字段类型的参数,给数据库表添加字段。

public void addBillField(String tablename, String fieldName, String fieldDbType, String fieldLabel) {
    StringBuilder sb = new StringBuilder();
    sb.append("alter table ").append(tablename)
            .append(" add ")
            .append(fieldName)
            .append(" ")
            .append(fieldDbType)
            .append(" comment '")
            .append(fieldLabel).append("';");
    jdbcTemplate.execute(sb.toString());
}
(2)设置字段类型

字段类型有文本、整数、小数、日期时间等类型,页面上可以接受这些选项设置字段的类型。这些都好说。

但是有些字段是外键,关联了外部数据库表,属于引用类型。例如,订单表的某个字段是用户ID关联了用户表的信息。

本身字段类型应该属于整数,这没啥好说的,但是页面需要知道该字段属于外部哪个表单的信息,确保渲染该整数类型字段的时候可以转换为对应的名称信息。
在这里插入图片描述

(二)通过模板生成代码

1.模板引擎和模板文件

有多种模板引擎可以生成代码,这里我们使用Velocity模板引擎生成代码,引入maven依赖。

<!--Velocity模板引擎-->
<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity-engine-core</artifactId>
    <version>2.2</version>
</dependency>

如下代码所示,通过Velocity模板引擎,可以接受任意渲染的映射信息输出模板文件到某个目录上。

public class VelocityService {
    /**
     *
     * @param objectMap 渲染的映射信息
     * @param templatePath 模板文件位置
     * @param filename  文件名称
     * @param fileDir 文件所在目录
     */
    public static void outputFile(Map<String, Object> objectMap, String templatePath, String filename, String fileDir) {
        //1.设置velocity的资源加载类
        Properties prop = new Properties();
        prop.put("resource.loader.file.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
        //2.加载velocity引擎
        Velocity.init(prop);
        //3.加载velocity容器
        VelocityContext velocityContext = new VelocityContext();
        for (Map.Entry<String, Object> item : objectMap.entrySet()) {
            velocityContext.put(item.getKey(), item.getValue());
        }
        File directory = new File(fileDir);
        // 检查目录是否存在
        if (!directory.exists()) {
            // 如果目录不存在,则创建目录
            boolean created = directory.mkdirs();
            if (created) {
                System.out.println("目录已创建");
            } else {
                System.out.println("无法创建目录");
            }
        } else {
            System.out.println("目录已存在");
        }
        //4.加载velocity模板
        Template template = Velocity.getTemplate(templatePath, "utf-8");
        //5.合并数据
        try {
            System.out.println(templatePath);
            FileWriter fileWriter = new FileWriter(fileDir + "\\" + filename);
            System.out.println("到这一步");
            template.merge(velocityContext, fileWriter);
            fileWriter.close();
        } catch (IOException e) {
            Asserts.fail("IOException 异常:模板文件覆写失败!");
        }
    }
}

例如,以下是mybatis-generator模板文件中生成mapper文件的示例。

package ${package.Mapper};

import ${package.Entity}.${entity};
import ${superMapperClassPackage};
#if(${mapperAnnotation})
import org.apache.ibatis.annotations.Mapper;
#end

/**
 * <p>
 * $!{table.comment} Mapper 接口
 * </p>
 *
 * @author ${author}
 * @since ${date}
 */
#if(${mapperAnnotation})
@Mapper
#end
#if(${kotlin})
interface ${table.mapperName} : ${superMapperClass}<${entity}>
#else
public interface ${table.mapperName} extends ${superMapperClass}<${entity}> {

        }
#end

2.其它

虽然应该内置一些模板文件提供给用户使用,但是由于每个人编码习惯都不一样,我们应该支持用户上传自定义模板生成自己的代码。

(三)生成页面文件

1.页面生成和模板文件

在前面设计完成数据库表之后,我们应该可以根据数据库表生成默认的页面文件。

对于一个完整的页面功能,这时应该生成四个页面:列表页面、查看页面、添加页面和编辑页面。

但为了减少页面个数,增强页面复用度,可以 选择只生成两个页面——例如:员工表_列表页面,员工表_详情页面。

  • 列表页面是一个表格列出所有数据表中的数据。列表页面中包含添加记录、更改、删除的超链接。
  • 详情页面显示每条数据的详细信息。

在这里插入图片描述

也是根据页面的模板文件生成页面,列表页面和详情页面的模板文件由用户自行提供或由系统内置。

<template>
    <!-- 数据表 -->
      <a-table ref="${table.name}Table" :data-source="${table}.list">
        #foreach( ${item} in ${table.fields} )
          <a-table-column key="${item.propertyName}" title="${item.fieldLabel}" data-index="${item.propertyName}" align="center" />
        #end
      </a-table>
</template>

2.业务数据关联页面

当创建好业务数据与页面后,需要将业务数据关联到页面上,即将数据表中的字段关联到页面上,这个过程称为数据绑定。

在这里插入图片描述

五、测试与部署

单元测试:确保每个功能模块的正确性。
集成测试:验证各模块之间的交互是否正常。
性能测试:确保系统能够应对高并发访问。
部署方案:考虑使用Docker容器化部署,提高部署效率和环境一致性。

其它功能待思考完善。。。

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

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

相关文章

React Native 基础

React 的核心概念 定义函数式组件 import组件 要定义一个Cat组件,第一步要使用 import 语句来引入React以及React Native的 Text 组件: import React from react; import { Text } from react-native; 定义函数作为组件 const CatApp = () => {}; 渲染Text组件

ftdi_sio应用学习笔记 3 - GPIO

目录 1. 查找gpiochip 2. 打开GPIO 2.1 libgpiod库方式 2.2 系统方式 3. 关闭GPIO 3.1 libgpiod库方式 3.2 系统方式 4. 设置方向 4.1 libgpiod库方式 4.2 系统方式 5. 设置GPIO电平 5.1 libgpiod库方式 5.2 系统方式 6. 读取GPIO电平 6.1 libgpiod库方式 6.2 …

微信小程序登录注册页面设计(小程序项目)

需求 在微信小程序设计并实现登录页面&#xff0c;并填写相关登录注册函数 实现效果 代码实现 html代码 <view class"top" style"border-bottom-style: none;background-color:#FF8C69;"><!-- <view class"back" bind:tap"…

神经网络(系统性学习三):多层感知机(MLP)

相关文章&#xff1a; 神经网络中常用的激活函数 神经网络&#xff08;系统性学习一&#xff09;&#xff1a;入门篇 神经网络&#xff08;系统性学习二&#xff09;&#xff1a;单层神经网络&#xff08;感知机&#xff09; 多层感知机&#xff08;MLP&#xff09; 多层感…

Android 14 screenrecord录制视频失败的原因分析

文章目录 1. 权限问题2. 存储空间不足3. 命令被中断4. 目标路径问题5. Android 14 的新限制6. 文件系统同步问题7. 录制失败检查步骤总结&#xff1a; 在 Android 14 系统上&#xff0c;使用 screenrecord 命令录制视频后&#xff0c;生成的文件大小为 0&#xff0c;可能的原因…

Uniapp 简单配置鸿蒙

Uniapp 简单配置鸿蒙 前言下载并配置鸿蒙IDEHbuilder X 配置基本的信息生成相关证书登录官网获取证书IDE配置证书添加调试设备可能出现的问题前言 如今鸿蒙的盛起,作为多端开发的代表也是开始兼容鸿蒙应用的开发,接下来我将介绍如何在uniapp中配置鸿蒙。 注意:hbuilder X的…

git使用(一)

git使用&#xff08;一&#xff09; 为什么学习git?两种版本控制系统在github上创建一个仓库&#xff08;repository&#xff09;windows上配置git环境在Linux上配置git环境 为什么学习git? 代码写了好久不小心删了&#xff0c;可以使用git防止&#xff0c;每写一部分代码通…

C# 数据结构之【树】C#树

以二叉树为例进行演示。二叉树每个节点最多有两个子节点。 1. 新建二叉树节点模型 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace DataStructure {class TreeNode{public int Data { get;…

HarmonyOs鸿蒙开发实战(20)=>一文学会基础使用组件导航Navigation

敲黑板&#xff0c;以下是重点技巧。文章末尾有实战项目效果截图及代码截图可参考 1.概要 Navigation是路由导航的根视图容器Navigation组件主要包含​导航页&#xff08;NavBar&#xff09;和子页&#xff08;NavDestination&#xff09;&#xff0c;导航页不存在页面栈中&am…

python从入门到精通:pyspark实战分析

前言 spark&#xff1a;Apache Spark是用于大规模数据&#xff08;large-scala data&#xff09;处理的统一&#xff08;unified&#xff09;分析引擎。简单来说&#xff0c;Spark是一款分布式的计算框架&#xff0c;用于调度成本上千的服务器集群&#xff0c;计算TB、PB乃至E…

Ubuntu从入门到精通(二)远程和镜像源配置齐全

Ubuntu从入门到精通(二) 1 常见操作配置 1.1 英文语言配置 1.1.1 打开设置 1.1.2 设置语言为英文 1.1.3 重启生效 1.1.4 再次进入,选择更新名字 1.1.5 再次进入,发现已经变成了英文 1.2 输入法配置 1.3 rustdesk安装 1.3.1 Windows系统配置 登陆:https://github.com…

HTML5拖拽API学习 托拽排序和可托拽课程表

文章目录 前言拖拽API核心概念拖拽式使用流程例子注意事项综合例子&#x1f330; 可拖拽课程表拖拽排序 前言 前端拖拽功能让网页元素可以通过鼠标或触摸操作移动。HTML5 提供了标准的拖拽API&#xff0c;简化了拖放操作的实现。以下是拖拽API的基本使用指南&#xff1a; 拖拽…

华为Ensp模拟器配置OSPF路由协议

目录 简介 实验步骤 Pc配置 路由器配置 OSPF配置 交换机配置 简介 开放式最短路径优先 (OSPF) 协议深度解析 简介 开放式最短路径优先&#xff08;Open Shortest Path First, OSPF&#xff09;是一种内部网关协议&#xff08;IGP&#xff09;&#xff0c;用于在自治系统…

【最新鸿蒙应用开发】——合理使用自定义弹框

自定义弹窗选型 合理选择不同的系统能力实现弹窗&#xff0c;有利于提升应用开发效率&#xff0c;实现更好的功能需求&#xff0c;因此了解自定义弹窗的选型和差异非常重要。在应用开发中&#xff0c;为了选择出合适的弹窗选型&#xff0c;从使用场景上&#xff0c;需要重点关…

自动化爬虫Selenium

自动化爬虫Selenium 这篇文章, 我们将要学习自动化爬虫的知识啦。 目录 1.Selenium的基本操作 2.用Selenuim获取数据 3.当当网数据获取 4.实战 一、Selenium的基本操作 首先, 我们在使用Selenium之前, 需要做两件事情。第一件事情, 就是安装第三方库, 第二件事情, 就是…

开源可视化工具对比:JimuReport VS DataEase

在当今数据驱动的时代&#xff0c;高效的数据可视化工具成为企业洞察业务、做出决策的关键利器。那对于企业来讲如何选择BI产品呢&#xff1f; 在开源可视化工具的领域中&#xff0c;JimuReport和DataEase 以其独特的优势脱颖而出&#xff0c;究竟谁更胜一筹呢&#xff1f;让我…

Jenkins的环境部署

day22 回顾 Jenkins 简介 官网Jenkins Jenkins Build great things at any scale The leading open source automation server, Jenkins provides hundreds of plugins to support building, deploying and automating any project. 用来构建一切 其实就是用Java写的一个项目…

Ubuntu22.04配置强化学习环境及运行相关Demo

什么是强化学习 强化学习&#xff08;Reinforcement Learning&#xff0c;简称 RL&#xff09;是机器学习中的一个重要分支&#xff0c;属于一种基于试错机制的学习方法。它通过让智能体&#xff08;Agent&#xff09;与环境&#xff08;Environment&#xff09;进行交互&…

AI 写作(一):开启创作新纪元(1/10)

一、AI 写作&#xff1a;重塑创作格局 在当今数字化高速发展的时代&#xff0c;AI 写作正以惊人的速度重塑着创作格局。AI 写作在现代社会中占据着举足轻重的地位&#xff0c;发挥着不可替代的作用。 随着信息的爆炸式增长&#xff0c;人们对于内容的需求日益旺盛。AI 写作能够…

丹摩征文活动 | AI创新之路,DAMODEL助你一臂之力GPU

目录 前言—— DAMODEL&#xff08;丹摩智算&#xff09; 算力服务 直观的感受算力提供商的强大​ 平台功能介绍​ 镜像选择 云磁盘创建 总结 前言—— 只需轻点鼠标,开发者便可拥有属于自己的AI计算王国 - 从丰富的GPU实例选择,到高性能的云磁盘,再到预配置的深度学习…