Java后台开发规范
1.Java编程规范
1.1.命名风格
代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束。
类名使用 UpperCamelCase 风格,必须遵从驼峰形式,但以下情形例外:DO / BO / DTO / VO / AO
接口类中的方法和属性不要加任何修饰符号,保持代码的简洁性,并加上有效的 Javadoc 注释。尽量不要在接口里定义变量,如果一定要定义变量,肯定是与接口方法相关,并且是整个应用的基础常量。
-
Service/DAO 层方法命名规约
- 1) 获取单个对象的方法用 get 做前缀。
- 2) 获取多个对象的方法 list 命名。
- 3) 获取统计值的方法用 count 做前缀。
- 3) 分页的方法用 page 做后缀。
- 4) 插入的方法用 save 做前缀。
- 5) 删除的方法用 delete 做前缀。
- 6) 修改的方法用 update 做前缀。
-
领域模型命名规约
- 1) 数据传输对象:xxxDTO,xxx 为业务领域相关的名称。
- 2) 展示对象:xxxVO,xxx 一般为实体名称。
- 3) POJO 是 DO/DTO/BO/VO 的统称,禁止命名成 xxxPOJO
-
分层领域模型规约
- DO(Data Object):与数据库表结构一一对应,通过 DAO 层向上传输数据源对象。
- DTO(Data Transfer Object):数据传输对象,Service 或 Manager 向外传输的对象。
- BO(Business Object):业务对象。由 Service 层输出的封装业务逻辑的对象。
- AO(ApplicationObject):应用对象。在Web层与Service层之间抽象的复用对象模型,极为贴近展示层,复用度不高。
- VO(View Object):显示层对象,通常是 Web 向模板渲染引擎层传输的对象。
- Query:数据查询对象,各层接收上层的查询请求。注意超过 2 个参数的查询封装,禁止使用 Map 类来传输。
1.2.代码格式化规范
每次编辑完一个类后使用idea的格式化功能,格式化代码和去掉无用导入的包,win快捷键为 Ctrl+Alt+l 和 Ctrl+Alt+o,Mac为ctrl+option+o 和 option+command+l。
项目的代码格式统一为UTF-8。
1.3.API命名规范
GET(SELECT):从服务器取出资源(一项或多项)。
POST(CREATE):在服务器新建一个资源。
PUT(UPDATE):在服务器更新完整的资源(客户端提供改变后的完整资源)。
DELETE(DELETE):从服务器删除资源。
基本规范
- 使用'/'表示层级关系
- url 不能以'/'结尾
- url 中不能包含空格
- url 中不能以文件后缀结尾
- url 中字母小写,单词间加下划线
- 不要再url中添加CRUD
说明 | ActionName | HttpMapping | HttpRequestBody | HttpResponseBody |
---|---|---|---|---|
查询所有 | list | GET /v1/user/list?xx=xx | N/A | Resource* list |
获取单个资源 | query | GET /v1/user/1 | N/A | Resource* |
创建单个资源 | create | POST /v1/user/create | Resource | Resource* |
更新单个资源 | update | PUT /v1/user/update | Resource | Resource* |
删除单个资源 | delete | DELETE /v1/user/delete | N/ | Empty |
分页条件查询 | page | GET /v1/user/page?page=0&size=10 | N/A | Resource |
批量添加 | batchCreate | POST /batch_create | Resource* list | Resource IDS |
批量删除 | batchDelete | POST /batch_delete | Resource IDS | Empty |
更新用户的年龄 | updateAge | POST /v1/user/1/age?value=20 | N/A | {"key":"age","value":"20"} |
1.4.异常处理规范
异常不要用来做流程控制,条件控制,因为异常的处理效率比条件分支低。
对大段代码进行 try-catch,这是不负责任的表现。catch 时请分清稳定代码和非稳 定代码,稳定代码指的是无论如何不会出错的代码。对于非稳定代码的 catch 尽可能进行区分 异常类型,再做对应的异常处理。
捕获异常是为了处理它,不要捕获了却什么都不处理而抛弃之,如果不想处理它,请 将该异常抛给它的调用者。最外层的业务使用者,必须处理异常,将其转化为用户可以理解的 内容。
有 try 块放到了事务代码中,catch 异常后,如果需要回滚事务,一定要注意手动回 滚事务。
finally 块必须对资源对象、流对象进行关闭,有异常也要做 try-catch。
不能在 finally 块中使用 return,finally 块中的 return 返回后方法结束执行,不 会再执行 try 块中的 return 语句。
方法的返回值可以为 null,不强制返回空集合,或者空对象等,必须添加注释充分 说明什么情况下会返回 null 值。调用方需要进行 null 判断防止 NPE 问题。
1.5.模块化开发规范
模块化开发是指公司共有的基础模块的开发如:短信、权限、支付、公共工具、邮件等。
模块化开发的pom模版
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.domain.module</groupId>
<artifactId>domain-module</artifactId>
<version>1.0.0.RELEASE</version>
<dependencies>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
<distributionManagement>
<repository>
<id>releases</id>
<name>Nexus release Repository</name>
<url>http://192.168.0.110:8081/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>snapshots</id>
<name>Nexus snapshots Repository</name>
<url>http://192.168.0.110:8081/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
</project>
-
模块化定义 GAV 遵从以下规则:
- GroupID格式:com.{域名}.业务线.[子业务线],最多4级。
- ArtifactID格式:产品线名-模块名。语义不重复不遗漏,先到中央仓库去查证一下。
-
模块化命名方式:主版本号.次版本号.修订号
- 主版本号:产品方向改变,或者大规模API不兼容,或者架构不兼容升级。
- 次版本号:保持相对兼容性,增加主要功能特性,影响范围极小的API不兼容修改。 3) 修订号:保持完全兼容性,修复BUG、新增次要功能特性等。
2.前后端对接规范
- 后端返回格式统一为json格式数据。
{"code":20000,"message":"success","data":null}
后端返回的code字段,以4开头则为前端请求有误,以5开头则是后端接口问题。2开头则表示成功。
后端返回的message字段表示请求的信息,成功是success,错误则会提示相应的异常信息或返回error。
后端返回的data字段则是本次请求的数据,无数据则返回null。
后端返回的时间格式统一为时间戳
3.数据库设计规范
3.1.建表规约
表名、字段名必须使用小写字母或数字,禁止出现数字开头,禁止两个下划线中间只出现数字。数据库字段名的修改代价很大,因为无法进行预发布,所以字段名称需要慎重考虑。
表达是与否概念的字段,必须使用 is_xxx 的方式命名,数据类型是 tinyint (1表示是,0表示否)。
表名不使用复数名词。
禁用保留字,如 desc、range、match、delayed 等,请参考 MySQL 官方保留字。
主键索引名为 pk_字段名;唯一索引名为 uk_字段名;普通索引名则为 idx_字段名。
小数类型为 decimal,禁止使用 float 和 double。
如果存储的字符串长度几乎相等,使用 char 定长字符串类型。
varchar 是可变长字符串,不预先分配存储空间,长度不要超过 5000,如果存储长 度大于此值,定义字段类型为 text,独立出来一张表,用主键来对应,避免影响其它字段索 引效率。
表必备三字段:id, gmt_create, gmt_modified。
表的命名最好是加上"业务名称_表的作用"。
库名与应用名称尽量一致。
单表行数超过 500 万行或者单表容量超过 2GB,才推荐进行分库分表。
3.2.索引规约
业务上具有唯一特性的字段,即使是多个字段的组合,也必须建成唯一索引。
超过三个表禁止 join。需要 join 的字段,数据类型必须绝对一致;多表关联查询时,保证被关联的字段需要有索引。
在 varchar 字段上建立索引时,必须指定索引长度,没必要对全字段建立索引,根据实际文本区分度决定索引长度即可。
如果有 order by 的场景,请注意利用索引的有序性。order by 最后的字段是组合索引的一部分,并且放在索引组合顺序的最后,避免出现 file_sort 的情况,影响查询性能。
利用覆盖索引来进行查询操作,避免回表。
SQL 性能优化的目标:至少要达到 range 级别,要求是 ref 级别,如果可以是 consts 最好。
建组合索引的时候,区分度最高的在最左边。
3.3.SQL 语句
不要使用 count(列名)或 count(常量)来替代 count(),count()是 SQL92 定义的 标准统计行数的语法,跟数据库无关,跟 NULL 和非 NULL 无关。
count(distinct col) 计算该列除 NULL 之外的不重复行数,注意 count(distinct col1, col2) 如果其中一列全为NULL,那么即使另一列有不同的值,也返回为0。
当某一列的值全是 NULL 时,count(col)的返回结果为 0,但 sum(col)的返回结果为 NULL,因此使用 sum()时需注意 NPE 问题。
使用 ISNULL()来判断是否为 NULL 值。
在代码中写分页查询逻辑时,若 count 为 0 应直接返回,避免执行后面的分页语句。
不得使用外键与级联,一切外键概念必须在应用层解决。
禁止使用存储过程,存储过程难以调试和扩展,更没有移植性。
数据订正时,删除和修改记录时,要先 select,避免出现误删除,确认无误才能执行更新语句。
in 操作能避免则避免,若实在避免不了,需要仔细评估 in 后边的集合元素数量,控制在 1000 个之内
如果有全球化需要,所有的字符存储与表示,均以 utf-8 编码,注意字符统计函数的区别。
TRUNCATE TABLE 比 DELETE 速度快,且使用的系统和事务日志资源少,但 TRUNCATE 无事务且不触发 trigger,有可能造成事故,故不建议在开发代码中使用此语句。
3.4.ORM 映射
在表查询中,一律不要使用 * 作为查询的字段列表,需要哪些字段必须明确写明。
POJO 类的布尔属性不能加 is,而数据库字段必须加 is_,要求在 resultMap 中进行 字段与属性之间的映射。
不要用 resultClass 当返回参数,即使所有类属性名与数据库字段一一对应,也需 要定义;反过来,每一个表也必然有一个与之对应。
sql.xml 配置参数使用:#{},#param# 不要使用${} 此种方式容易出现 SQL 注入。
不允许直接拿 HashMap 与 Hashtable 作为查询结果集的输出。
更新数据表记录时,必须同时更新记录对应的 gmt_modified 字段值为当前时间。
不要写一个大而全的数据更新接口。传入为 POJO 类,不管是不是自己的目标更新字 段,都进行 update table set c1=value1,c2=value2,c3=value3; 这是不对的。执行 SQL 时,不要更新无改动的字段,一是易出错;二是效率低;三是增加 binlog 存储。
@Transactional 事务不要滥用。事务会影响数据库的 QPS,另外使用事务的地方需 要考虑各方面的回滚方案,包括缓存回滚、搜索引擎回滚、消息补偿、统计修正等。
4.服务部署规范
在线上生产环境,JVM的Xms和Xmx设置一样大小的内存容量,避免在GC 后调整堆 大小带来的压力。
给 JVM 设置-XX:+HeapDumpOnOutOfMemoryError 参数,让 JVM 碰到 OOM 场景时输出 dump 信息。
参考:阿里巴巴Java开发手册