亲身经历
最近接了个外包,和另外两个哥们一起开发。因为他们的时间更充裕,所以前期的代码都是他们来手写,我没有参与。等我空下来开始做我的部分时,两眼一抹黑,光看那一堆重复的 Controller、Service、DAO 就头大。
我不理解,但是大受震撼。
比如说:
java
复制下载
// 课程问卷相关的代码
CourseQuestionnaireController.java
CourseQuestionnaireService.java
CourseQuestionnaireServiceImpl.java
CourseQuestionnaireMapper.java
CourseQuestionnaireMapper.xml
// 问卷分发相关
QuestionnaireAssignmentController.java
...
// 每个模块都来一套,而且很多都是类似的增删改查
光看这些文件名能知道业务逻辑吗?难受啊兄弟们。
这让我深刻意识到了:哪怕是一些“高级开发”,也并不知道怎么去提升开发效率。还在用十年前的老方法,一个功能一个功能地手写,项目越做越累,bug 越改越多。
于是决定花点时间写一篇文章,和大家一起探讨如何更好的利用低代码来构建应用,告别无意义的重复劳动。
所有观点都是我结合多年的经验得来,不一定正确,如有错误之处欢迎大家指正。
低代码应用:第一眼就要知道是干什么的
1. 有意义的应用模块划分 + 清晰的数据模型
在传统开发中,我们通过表名来区分业务模块。在低代码开发中,我们通过应用模块和**数据模型(实体)**来组织业务。
❌ 不好的低代码组织方式
text
复制下载
- 应用1:问卷调查(里面一堆乱七八糟的表单和数据)
- 应用2:用户管理(又是类似的表单)
- 各种零散的页面,没有统一的数据模型
✅ 好的低代码组织方式(以 JNPF 为例)
-
创建业务应用:比如“在线教育后台”,所有相关功能都放在这个应用里。
-
建立清晰的数据模型(实体):
课程(Course)问卷(Questionnaire)学生(Student)问卷分发记录(QuestionnaireAssignment)问卷题目(QuestionnaireQuestion)
在 JNPF 低代码平台中,你可以可视化地创建这些数据模型,平台会自动生成对应的数据库表,并处理好关联关系。你完全不需要手动写建表语句,更不用为每个模型写一套增删改查。
区别在哪里?
-
不好的:东一个应用西一个页面,数据模型混乱,开发人员还得自己去维护数据库脚本。
-
好的:业务模块清晰,数据模型集中管理,平台负责底层实现,开发人员专注业务逻辑。
什么时候需要划分多个应用?
-
大型项目可以按子系统拆分(CRM、ERP、CMS 等),每个子系统作为一个独立的应用。
-
不同业务域可以分开(订单中心、用户中心、商品中心),便于权限管理和维护。
2. 用完整的英文单词而不是拼音来命名数据模型
❌ 不好的命名
text
复制下载
kecheng_wenjuan # 拼音
user_xinxi # 中英混合
订单_items # 中英混合
✅ 好的命名(在 JNPF 数据模型中)
text
复制下载
CourseQuestionnaire # 纯英文,语义清晰
UserProfile # 纯英文
OrderItem # 纯英文
原因
-
英文是编程的通用语言,团队成员更容易理解
-
避免编码问题
-
JNPF 平台生成的代码、API 接口都会基于这个命名,好的命名让前后端联调更顺畅
3. 数据模型要体现业务含义,不要只是技术实现
❌ 不好的命名
text
复制下载
DataTable001
TempStorage
MiddleTable
RelationMapping
✅ 好的命名(在 JNPF 中)
text
复制下载
StudentScore # 学生成绩
FileUploadRecord # 文件上传记录
CourseEnrollment # 课程报名
UserPreference # 用户偏好设置
除非是临时用来做数据处理的实体,否则一定要体现业务含义。
字段命名(在数据模型中):见名知意
在低代码平台中,虽然字段是可视化配置的,但良好的命名依然至关重要——因为生成的 API、前端组件绑定、甚至后续的代码扩展都会用到这些名字。
1. 布尔字段用 is_ 开头
❌ 不好的命名
text
复制下载
active # 是激活还是活跃?
delete # 删除状态还是删除动作?
flag # 什么标志?
✅ 好的命名(在 JNPF 字段配置中)
text
复制下载
is_active # 是否激活
is_deleted # 是否已删除
is_verified # 是否已验证
好处
-
一眼就能看出是布尔值,在 JNPF 的表单控件中可以直接绑定复选框。
-
避免歧义,生成的代码中
if (entity.getIsActive())清晰易懂。 -
团队协作时,不用猜字段含义。
2. 时间字段统一后缀
❌ 不好的命名
text
复制下载
create_time
update_date
delete_at
register_datetime
✅ 好的命名(在 JNPF 中)
text
复制下载
created_at # 创建时间
updated_at # 更新时间
deleted_at # 删除时间
registered_at # 注册时间
好处
-
一眼就能看出是时间字段,JNPF 的日期控件可以自动识别并展示。
-
避免团队内部命名混乱。
-
特别推荐用
deleted_at做逻辑删除字段,JNPF 内置数据回收站功能,支持软删除和历史追踪,比简单的is_deleted更强大。
3. 关联字段统一 _id 后缀
在低代码平台中,建立数据模型间的关系时,关联字段的名称也应该规范。
❌ 不好的命名
text
复制下载
user # 这是用户ID还是用户对象?
course # 课程ID?
teacher_key # 什么key?
✅ 好的命名(在 JNPF 关联关系中)
text
复制下载
user_id # 用户ID
course_id # 课程ID
teacher_id # 教师ID
在 JNPF 中,当你建立两个模型的关系时(如订单关联用户),平台会自动生成 user_id 字段,并且你可以直接配置关联表单、下拉框等组件,非常方便。
4. 额外的经验
除了上面这些基本的命名规范,还有一些实用的经验:
-
状态字段用枚举:在 JNPF 中,字段类型可以选择“枚举”,填写
pending、approved、rejected这样的值,代码可读性高,下拉框也自动支持。 -
金额字段用 decimal:JNPF 支持 decimal 类型,精度可以设置,避免浮点数误差。
-
密码字段要加密:在 JNPF 中,用户实体可以配置密码字段自动加密,平台内置了加密算法,你只需要勾选“加密存储”即可。
数据模型关系设计:关系清晰、适度冗余
1. 一对多关系:外键放在多的一边
让我们用用户和订单的业务关系来举例:
在 JNPF 中,我们创建两个数据模型:
-
用户模型 (User):字段有 id、用户名、邮箱等。
-
订单模型 (Order):字段有 id、订单号、总金额、状态,并建立一个关联字段指向用户(user_id)。
这样设计的好处:
-
通过 JNPF 的关联表单,在订单详情页可以直接显示用户信息。
-
需要查询某个用户的所有订单时,JNPF 的数据筛选器可以轻松搞定。
-
新增订单字段不会影响用户模型,耦合度低。
2. 多对多关系:中间实体命名要体现关系
多对多关系在低代码中可以通过创建中间实体来处理。命名要根据具体情况选择:
情况1:有业务含义的关系表比如学生和课程的关系,不只是简单关联,还有报名时间、状态等业务信息。
❌ 不好的命名
text
复制下载
student_course_rel # rel是什么关系?
sc_mapping # 缩写看不懂
middle_table # 完全不知道什么意思
✅ 好的命名(在 JNPF 中创建实体)
课程报名实体 (CourseEnrollment)
字段:
-
student_id(关联学生)
-
course_id(关联课程)
-
enrolled_at(报名时间)
-
status(报名状态)
这样设计后,在 JNPF 中你可以直接为这个实体创建表单,用来处理学生报名课程的完整流程,包括审批、支付等。
情况2:纯粹的关联关系如果只是单纯的多对多映射,没有额外的业务属性,用 mapping 也是可以的:
**用户角色关联实体 (UserRoleMapping)**字段只有 user_id 和 role_id。
如何选择命名?
-
有业务含义的关系:用具体的业务名词,如 Enrollment、Order、Friendship。
-
纯粹的映射关系:可以用 Mapping、Relation 或直接用 Entity1Entity2(如 UserRole)。
-
关键是保持团队内命名风格的统一。
3. 适当的字段冗余:提升查询效率
有时候为了避免复杂的关联查询,在低代码模型中适当冗余是非常有必要的。
最典型的就是冗余上级 ID:
订单详情实体 (OrderItem)
字段:
-
id
-
order_id
-
user_id(冗余) ← 关键冗余字段
-
product_id
-
quantity
-
price
为什么要冗余 user_id?
-
在 JNPF 中,如果你要展示某个用户的所有购买记录,直接查 OrderItem 并筛选 user_id 即可,无需通过 Order 再关联。
-
在报表统计时,直接基于 OrderItem 聚合用户维度数据,效率更高。
商品评论实体 (ProductReview)
字段:
-
id
-
product_id
-
category_id(冗余) ← 关键冗余字段
-
user_id
-
rating
-
content
为什么要冗余 category_id?
-
在 JNPF 的报表功能中,按分类统计评分时,直接使用 category_id 分组即可,不需要关联商品表。
-
查询某分类下的所有评论也更高效。
什么时候该冗余ID?
-
经常需要跨层级查询的场景
-
统计和报表查询频繁的字段
-
读多写少的关联关系
-
上级ID基本不会变动的情况
回到最初的案例
现在我们用 JNPF 低代码平台来重新设计开头的问卷系统。
❌ 原来的手工编码方式
-
手写一大堆 Controller、Service、Mapper
-
表名乱七八糟:
DC_COURSE_TESTPAPER、DC_COURSE_PAPER_HISTORY、DC_COURSE_PAPER_HISTORY_ALL -
每个功能都要写前端页面,还要处理权限、流程
✅ 用 JNPF 低代码重新设计
在 JNPF 中,我们创建一个应用“在线教育后台”,然后通过可视化方式建立以下数据模型:
-
课程问卷实体 (CourseQuestionnaire)
字段:id, course_id(关联课程), title, description, status, created_at
直接生成问卷表单,用于发布问卷
-
问卷分发记录实体 (QuestionnaireAssignment)
字段:id, questionnaire_id(关联问卷), student_id(关联学生), assigned_at, status
用于记录问卷下发给哪些学生
-
问卷题目实体 (QuestionnaireQuestion)
字段:id, questionnaire_id(关联问卷), content, question_type, sort_order
用于配置问卷包含哪些题目
在 JNPF 中,你可以:
-
拖拽生成表单:每个实体都可以一键生成增删改查页面。
-
配置流程:比如问卷需要审批发布,用 JNPF 流程引擎拖一拖就行。
-
设置权限:不同角色(管理员、老师、学生)看到不同的页面和数据。
-
生成 API:如果需要,JNPF 自动生成 RESTful API,前端直接调用。
现在再看:
-
CourseQuestionnaire- 一眼就知道是课程问卷 -
QuestionnaireAssignment- 问卷分发记录 -
QuestionnaireQuestion- 问卷题目
是不是瞬间清晰了?而且开发工作量从几周缩减到几天。
写在最后
应用构建方式是项目的重中之重。
好的低代码实践让整个团队开发起来更顺畅:
-
减少重复劳动:平台处理了 80% 的通用功能
-
降低沟通成本:可视化模型比代码更直观
-
维护更容易:修改模型配置即可,无需翻找代码
-
新人上手更快:看数据模型就能理解业务
投入时间去学习和使用低代码平台(比如 JNPF),绝对是值得的投资。
没有人愿意每天面对一堆重复的 Controller、Service、XML 文件,做着毫无技术含量的增删改查。
最后一句话:代码是给人看的,应用也是给人用的。用低代码,把人从繁琐的重复劳动中解放出来,去解决更有价值的问题。