开发规范(部分开发规范的学习梳理)
数据库相关
- 统一用uuid,不用子增长id
- 尽量用char,不用varchar, uuid长度36,预留扩展空间。具体选择区分业务
- 枚举类型用tinyint
- mybatis尽量用Base_Column_List
- 大表的SQL变更及时与DBA沟通
- select sum() 需要判断值为null的情况
- char 表示定长,长度固定,varchar表示变长,即长度可变。char如果插入的长度小于定义长度时,则用空格填充;varchar小于定义长度时,还是按实际长度存储,插入多长就存多长。
因为其长度固定,char的存取速度还是要比varchar要快得多,方便程序的存储与查找;但是char也为此付出的是空间的代价,因为其长度固定,所以会占据多余的空间,可谓是以空间换取时间效率。varchar则刚好相反,以时间换空间。
区别之二,存储的容量不同
对 char 来说,最多能存放的字符个数 255,和编码无关。
而 varchar 呢,最多能存放 65532 个字符。varchar的最大有效长度由最大行大小和使用的字符集确定。整体最大长度是 65,532字节
DAO层
- 函数需要加@DataSource注解,master指主库,访问主库还是从由中间件决定
- 多数据源配置
- 数据库账号、密码加密解密
- 通过Spring AOP配置本地事务, application-orm.xml
Service层
需要暴露远程服务的定义interface,内部调用可以直接用
所有提交接口都不能进行重试业务操作
关于事物的建议点
- 事物封装
尽量不开大事务,把所有的insert封装到list里面,批量放到一个小方法里面,批量更新。 - 不循环插入
尽量不在循环里面坐insert,可以封装成LIST,外部插入,可以减少与数据库的交互。 - 不循环查询
可以在外面查询封装MAP,然后使用,根据具体业务场景设计 - 不依赖之前的ID
设计上尽量在每张表增加UUID字段,使用的时候用ID生成器生成,在下个插入的时候不使用上个插入的ID,而是依靠之前生成的UUID。 - 事务内请勿调用http接口、dubbo服务
- 事务内如果需要发送mq,请考虑mq、和事务的时效,建议在事务完成后发送mq
定义对象相关
- 内部类尽量不要持有外部类
switch语句
说明:一个switch块包含了一个或多个语句组。每组都以一个或多个标签开头(如case 0:或者default:),后面跟着一个或多个语句。
case贯穿:禁止case必须被终止(break、return和抛出异常)。不允许使用case贯穿,这种风格容易导致bug。如有实际需要的场景,应使用if-else来实现。
default每个switch中都要有default。default也必须被终止(break、return和抛出异常)。在default预期不可能被执行的时候,应执行抛出异常等可以有效发现bug的动作。
mq监听类的编写
1.每个mq监听者都需要定义一个Listener类,Listener类需要处理
a.打印接受消息
b.检查参数格式
c.异常处理
d.所有业务逻辑写在servcie层
task任务类的编写
1.所有定时请继承BaseSimpleJob
2.Job类已经自动处理了,日志和异常。doTask方法直接调用service即可
3.对于循环的任务,在for循环中需要进行try catch,防止一个错误,导致整个任务的失败
- Task内部逻辑封装再Service层
- 系统时间问题,零点启动的Task延后几分钟启动,避免计算时间错误
- 统一使用Elastic框架
- 需求:可重入、可以手动启动
- 使用时打印启动时间和结束时间
http 接口编写
1.每掉用一个系统,需在provider.api包下新建一个 “系统名+Api.java" 的文件。请继承JdbApi类
2.接口所需要的枚举,请定义在provider.api.constants包下
3.每个类有三个要素、appUrl、appKey、apiUrl(接口路径),请定义在头部
4.appUrl、appKey 为配置分离项目,需要op进行维护。apiUrl为rd自主维护
5.如果getSign方式特殊,请重写getSign方法。
6.返回不是标准类型,请重写parseRet方法
7.正常的访问和返回,已经打印了日志,异常的时候,请自行记录信息
8.没访问一个接口,请贴上apidoc,和注释。如果参数超过5个,请定义BO
9.返回请定义VO
启动顺序约定
在SpringContainer启动的时候,需要做什么初始化的操作,继承AbstractInit类自定义启动加载数据,凡是迁移dubbo的项目,需要定一套启动操作顺序规则:
加载框架需要的,如AOP,IoC实例等;
先加载业务需要的配置/cache/configuration…;
dubbo准备就绪,注册zk暴露服务【关键点】;
在第3步操作之前需要确保第2步已完成,否则咱们的服务容易产生毛刺现象or预热不足导致长耗时问题。基于此,对Initiator.onApplicationEvent函数的执行流程设定如下规则:
定义几个protected方法:init(), destroy()
重写的方法onApplicationEvent里,顺序执行:init()
当容器调用ConfigurableApplicationContext的Stop()方法停止容器时触发该事件destroy()