后台管理系统很简单? 就是CRUD? 快进来看看你忽视了多少细节!

前言

今年下半年负责了一个前后端分离的管理系统, 用的是 Springboot + Spring data jpa + Vue + mysql, 个人负责的是后端接口开发, 这也算是我第一次从 0 到 1 完成的一个管理系统.

受制于平时看的视频教程, 亦或者是一些开源项目, 以及平时养成的坏习惯, 导致在真正上手去做这些 平时看不起 的管理系统时, 踩了很多坑, 忽略了很多细节, 希望这篇文章不仅能让自己得到反思, 也能帮助其他人一起脱坑!!!

正文

下面会通过管理系统几个必备的功能, 必要时还会给出 案例 来说明细节的重要性.

一、后端接口开发

永远不要想着你的接口只会提供给前端界面去使用, 从而导致你认为只要前后端约定好一切就万事大吉了, 只要产生了这个前提, 在你做测试的时候, 就会站在前端调用的角度去做接口测试, 有时甚至界面上的功能点一点就行了, 这样只能说明通过界面去使用你们的系统是 ok 的. 一旦接口暴漏给第三方开发者去使用, 你就会发现提供出去的接口服务完全经不起折腾.

例子 1: 有一张图片资源表, 表结构如下, 这张表是保存了所有用户的图片资源, 在管理界面上用户只能看到自己的图片列表.

id(主键) name user_id
1 图片1 11111

当我们做查询接口时, 往往能想到通过 user_id 去查询, 但是当通过做删除接口时, 因为能够通过主键 id 定位一条数据, 所以如果只提供 id 作为删除请求的参数, 此时通过界面去执行删除操作,完全看不出有什么问题, 因为用户只能看到用户自己的图片, 但是如果此接口提供给第三方开发去掉用, 他就很可能有意无意的把其他用户的图片 id 传递过来, 这不就坏事了嘛!!!

例子 2: 有一个用户编辑接口, 用户表有一条叫 zhangsan 的用户数据, 要求用户表的用户名不能重复, 因此在做唯一性校验时就自然而然产生了如下伪代码:

User user = getUserByName("zhangsan");
if(user != null ) {
	return "用户名已存在";
}
updateUser(updateUser);
return "更新成功";

同时前后端约定了当更新用户信息时, name 不是必填项, 另外对于非必填项, 前端传递 null 值. 此时站在前端的角度上, 确实不能看出这个接口有什么问题.

但是站在第三方开发者角度上, 你的 name 是可选的, 我在编辑 zhangsan 用户时, 我就想把 name=zhangsan 重新带过去, 此时再看一下上面的伪代码是不是就有问题了?!

二、 用户登录

站在 使用者 的角度上, 用户登录就是 “在登录页输入用户名和密码, 登录成功后, 进入主页.”

作为 开发者 来讲, 我们一般更关注的是前后端的一堆校验逻辑, 比如字段的长度限制, 数据库唯一性限制.

但是站在 产品设计 的角度上, 需要考虑到 使用者 的各种 “奇葩行为”, 比如:

  1. 用户在浏览器登录成功后, 进入主页, 然后打开一个新的标签页, 把主页网址复制到地址栏中, 你是希望用户 重新登录 还是不需要再登录
  2. 是否允许用户的同一账号在多个浏览器登录
  3. 如果用户长时间不操作, 怎么实现自动退出登录

如果要实现上述某一项需求, 作为开发者的你能否立马想到用哪些知识点可以解决.

三、用户权限

用户权限的入门级 “套路”, 就是 5 张表:

  1. 用户表
  2. 角色表
  3. 权限表
  4. 用户-角色关联表
  5. 角色-权限关联表.

再不然就是 3-4 张表, 通过在用户表中添加对应角色表的“虚拟外键”, 或者在角色表中添加对应权限表的“虚拟外键”, 来实现表之间的关联.

这样的套路足以应付绝大多数的系统权限设计, 并且一般的系统权限就是控制一下用户能够访问哪几个菜单栏就好了, 一旦产品需要你将权限粒度控制到一个按钮、甚至一行数据(数据权限), 你的套路就变成死路了.

四、查询数据

说起查询数据, “小年轻” 的内心 OS 就是“查询数据多简单啊, 一条 select 语句而已, 如果多表关联查询就用 join 、子查询之类的”.

no no no~~~ 千万不要这么想! 需要考虑的还有很多.

1. 提出2个问题:

  1. 你的模糊查询功能支持 百分号、下划线这种字符吗? 如果不支持, 你觉得这算是问题吗?

  2. 当你的 where 条件后面的跟的字段值允许为 null 时, 比如这条语句 select * from user where name!=123 , name 为 null 的数据能查出来吗?

2. 查询优化:

比如你用的 mysql 数据库中有一张日志表, 日志的搜索条件可以有很多, 比如根据日期范围, 模糊查询, 状态查询, 首先这几个功能肯定都不难, 我们通常的做法就是模拟几十条数据, 然后测试单个查询, 多条件查询, 当查询结果符合预期时, 我们就觉得完事儿了, 其实我们忽略了最重要的一点, 这可是日志表啊, 数据庞大起来可以达到十万级、百万、甚至千万啊, 你只用了几十条数据测了一下, 发现几十毫秒就返回了正确结果. 这种测试用例不足以证明功能完成了.

当然, 现在网上关于 mysql 查询优化的那几条准则,甚至一些实战优化文章到处都是, 但是你真的有实践过吗, 如果没有的话, 建议你用上面的日志表尝试一下单表优化.

这里再出多表查询优化的题目:

一个客户对应 N 多个标签, 一个标签对应 N 多个客户, 这样一个多对多关系, 你如何设计表? 如何做查询优化去优化用户体验?

当然也有的人会说我们用的是 Oracel 数据库, 甚至 Elastic Search 这种搜索引擎... 那就当我没说

五、 新增数据(提交表单)

前后端分离模式基本都是通过 json 格式的数据进行交互, 比如新增一个用户, 我们会传递类似这样的参数:

{
	"username": "zhangsan",
	"my_xxx": "我的 xxxx"
}

需要注意的是 my_xxx 这个字段, 有的人在遇到多个单词拼成的字段时, 喜欢用下划线分隔开, 这里也埋了一个坑.

目前为止, 上面的做法没什么问题, 如果此时产品要求新增用户支持上传头像, 并且是同步上传, 你该如何处理? 如果你采用 form/data 的方式去提交表单, 这时就不能用传递 json 数据了, 但是也不能让后端定义一个 my_xxx 的字段去接受你的参数, 这也违背了 java 编码规范啊, 如果你继续采用通过请求体去提交数据, 那只能将图片转为 base64 编码.

这里还要问一句, 你们的系统是用的同步上传文件, 还是异步上传文件, 如果是异步上传文件, 后台处理时出现异常, 怎么删除文件? 有考虑过吗?

最后要考虑的是如何防止重复提交表单数据? 你的功能需不需要防止?

六、更新数据

更新数据有两个细节需要注意, 当然这个是有前提条件**, 一个是当你更新的字段与同一张表中的另一个字段有关联时, 另一个是当你更新的数据与另一张表的字段有关联时.**

举两个不恰当的例子:

例子 1

有一张用户表, 有 N 多个字段, 其中包括如下三个字段, 可以看到 description 字段是由 name 字段和 age 字段,组合而来的, 格式: 他的名字是{name}, 今年 {age} 岁, 并且这个字段暂时不用在界面上展示, 因此不管是更新 name 字段还是 age 字段, 都是需要更新 description 字段的 .

name age description
zhangsan 18 他的名字是zhangsan, 今年 18 岁

这里强调了两点, 1. 这张表有 N 多个字段, 2. 这个字段暂时不用在界面上展示. 另外加上当你使用一些全自动 Dao 层框架时, 你做更新数据, 往往是调用框架的 API 去做的更新, 比如 userDao.update(user). 这就会导致你在测试的过程忘记去观察 description 字段的变化.

例子 2

早期你有一张角色表, 角色名字段为 name, 长度限制 50.

后期加了一张 xx 资源表, 同样有个 name 字段, 长度限制 100, 有一个需求是, 当你在资源表插入 name=哇哈哈 这样一条数据时, 需要在角色表中插入一条, name=哇哈哈管理员 的数据. 你在测试之前, 是否能否意识到两张表的长度不一致问题?

七、 删除数据

删除数据需要考虑如下问题:

  1. 先查询到, 再删除, 如果查询不到, 接口提示数据不存在
  2. 直接删除, 不管数据在不在, 都返回删除成功!
  3. 批量删除大量数据这种耗时操作应当如何处理?

八、数据导入与导出

2 道选择题: csv 还是 excel ? poi 还是 easyexcel?

1. 数据导入

数据导入时, 如何解决乱码问题? 判断文件编码你有做吗? 还是说提供给用户一个导入模版?

2. 数据导出

这里仍然牵扯到大数据量问题, 再说一句, 不要随便拿几条数据测测就完了, 当导出的数据超过上百万, 甚至千万, 如何处理? 怎么避免内存溢出的问题?

总结

本文突出的重点就是 细节, 一个简单的管理系统, 不管模块再多, 无非就是上面所说的八大功能, 每个功能都暗藏了许多细节.

这些细节被忽略的原因大致如下:

  1. 压根没有碰到类似的需求
  2. 测试不够仔细, 通常就是界面点点没问题就行了
  3. 觉得不重要, 不影响, 比如大数据量查询, 可能自身接触的系统没多少数据,不需要浪费时间优化
  4. 眼高手低, 觉得看看就会了, 思路被一些视频教程, 文章带着走, 完全没有自己的思考
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章