第一部分. JAVA编码规范
一. 编码操作规范
1. 代码格式化
为保持公司代码格式的一致性,在开发前,需导入统一代码格式化模板。
在每次代码提交之前进行代码Format操作(Ctrl+Shift+F).
除为了保代码风格一致性之外,避免在提交后在SVN上产生代码冲突、减少人工合并代码成本,以及防止因代码格式问题产生的BUG。
2. 代码及文档Encoding格式
项目、代码、配置文件、文档统一编码格式为gbk。
为防止文档及代码产生乱码,在创建文档及代码的时候,必须检查其编码格式,格式不符合禁止提交至SVN,更改完Encoding格式之后,需要检查更改过的文件,避免因编码差异造成乱码。
Eclipse中Encoding格式设置:
右键单击项目->Properties->Resource
3. 提交代码
任何文件在提交SVN之间,必须先从SVN中进行更新,以便发现本地文件与服务器文件之间不兼容的代码和变更冲突。
如果发生文件冲突,找相关人员确认,手工合并之后进行提交,禁止强制对文件进行冲突覆盖。
在提交代码之前,在Eclipse中检查是否有warning产生,需要对产生的warning进行处理。
只提交自己需要提交的代码
项目延期导致发布时间在其它版本的代码,开发人员一定要及时回滚掉自己的代码
单独执行的sql文件先在开发环境测试一遍,然后发送邮件告知在测试环境执行,再提交sql review,最后在发布前发送邮件告知sqlreview通过的版本
要修改的公共配置文件请发送邮件告知,邮件内容需要修改的公共配置文件名+修改点
4. 无用代码清理
在提交至SVN之前,需要对代码中没有用到的方法、变量、类、配置文件进行清理,对于注释掉的方法,理论上需要进行清除。
二. 日志打印规范
1. 日志打印通道
所有日志必须通过Logger打印,禁止通过System或者Throwable的printStackTrace的方式进行日志输出。
所有日志最好不要用中文。
对于trace\debug\info级别的日志打印,必须进行isDebugEnabled(),isTraceEnabled(),及isInfoEnable()进行条件过滤。
对于有堆栈信息的日志打印,需要对堆栈信息进行打印,以便对错误信息的定位。
业务日志:提供多维度的日志查询机制。在打印日志的过程中,需要进行多维度的日志打印机制,包括订单ID,用户ID等,方便线上日志的跟踪。
2. 敏感信息
敏感信息:对于身份证,手机号码等敏感信息的日志输出,需要进行中间位*处理,例如:138****6666。
敏感信息列表:
身份证 | 230104********2628 |
手机号码 | 138****3613 |
卡号 | 5268********0239 |
护照号 |
|
安全域信息不容许打印在日志当中,例如密码。
3. 日志级别选择
日志等级选择:Debug级别日志,只对开发过程中对步骤的跟踪,线上不配置该级别日志。Info级别,对于流程信息、接口调用信息、关键步骤信息等,需要打印Info级别的日志文件中。Warn级别日志,打印由于业务异常产生的日志信息,信息中,需要包含异常业务的业务数据,方便线上日志排查。Error日志级别,打印因为系统异常出现的异常情况,例如,接口调用超时、空指针异常等。该级别的日志,需要带有堆栈信息,以及业务数据,对日志的打印,通过logger.error(“错误信息”,e)方式打印,禁止通过logger.error(“错误信息”+e)的方式进行打印。
日志文件:不同的业务场景及功能下的日志,需要打印至不同的日志文件中。例如,系统信息,打印在system-error.log中,对于业务异常,保存在biz-xxx.log中.
三. 注释规范
1. Class类注释
注释级别:文档级别
类注释需要在doc中生成,采用类注释风格,快捷键:alt+shift+J。
包含内容:类标题、类说明(对该类作用的详细说明)、类作者、类版本。
注释示例:
package com.paic.test;
/**
* <h1>类说明<h1/>
* @author ZHANGGUOJING613
* @version $Id: TestCodeTemplate.java, v 0.1 2012-11-1下午04:58:06 ZHANGGUOJING613Exp $
*/
public class TestCodeTemplate {
}
2. 方法注释规范
注释级别:文档级别
除setter\getter方法外,其他的所有方法均需要进行方法代码注释。
注释内容:方法名,方法用途,传入参数、返回参数及抛出异常。
注释示例:
/**
* <h1>方法说明<h1/>
*
* @paramargs
*
*/
public TestCodeTemplate(String args){
}
3. 类变量注释
注释级别:文档级别
对类内部的声明的参数变量需要进行参数变量注释说明。
注释内容:变量说明
注释示例:
/**
* <h1>类说明<h1/>
*
* @authorZHANGGUOJING613
* @version$Id: TestCodeTemplate.java,v 0.1 2012-11-1下午04:58:06 ZHANGGUOJING613 Exp $
*/
public class TestCodeTemplate {
/*参数说明**/
private String userName="";
4. 类内部注释
注释级别:逻辑实现逻辑级别
类内部注释包含代码逻辑说明,内部变量声明,注释量的多少不做强制要求,但是对于关键代码,及逻辑较复杂的代码,需要进行说明。
注释规范:采用 /* */ 或者//的方式,根据注释量自行选择。但是禁止使用/***/的注释级别进行注释。
注释示例:
四. 命名规范
1. 接口命名规范
接口命名采用服务名+Service的模式进行命名。
如用户服务接口命名方式为CustomerService.java
对其实现类采用接口名+Impl模式,及用户服务实现为:CustomerServiceImpl.java
2. 类命名规范
类的命名,采用首字母大写,每个单词的首字母大写的方式组合,需要尽可能的通过命名表现出类的作用,命名中,禁止出现字符如”_”,”-”等,禁止采用拼音。
常量类 | 采用Constant作为后缀 | CustomerConstants.class |
工具类 | 采用Util作为后缀 | CustomerUtil.class |
枚举类 | 采用Enum作为后缀 | CustomerEmum.class |
请求处理类 | 采用Action作为后缀 | CustomerQueryAction.class |
3. 资源文件、配置文件命名规范
对资源文件、配置文件采用首字母小写,其余单词的首字母大写,搭配”-”的命名方式。如,对于spring的配置文件:applicationContext-customer.xml
4. 页面文件命名规范
页面,如jsp,vm等类型,采用首字母小写,其余单词首字母大写的方式进行命名,禁止出现“_”等字符。如用户查询页面:customerQuery.vm
五. 异常规范
1. 异常分类
java中的异常分为RuntimeException和普通的Exception。
通常情况下,希望上层业务对该异常进行恢复时,采用Exception的继承模式。作为中断的情况通常采用RuntimeException模式。
2. 异常捕获
在自定义的业务异常中,禁止不区分业务进行顶层Exception捕获,需要对单独业务异常进行捕获,区分业务异常情况,进行业务处理。如下图,禁止至捕获Exception异常。
对多条异常信息,由底层向顶层进行捕获,例如:
catch(BusinessException2be2){
…
}catch(BusinessExceptionbe)
{
…
}catch(Exceptione) {
…
}
3. 系统间接口异常处理
对系统间暴露的接口,必须在向外暴露服务时对本系统内做异常的总catch处理,禁止因为本系统异常造成调用系统异常。具体见系统间接口规范。
4. 异常情况下资源的释放
对文件、流的IO操作,资源的申请,在异常情况产生后必须在finally模块中进行处理,禁止直接放弃对资源释放的操作。
5. 异常情况日志记录
对所有产生的异常情况必须进行日志记录,不容许做抛弃处理,对业务异常进行warn级别日志打印,对于系统异常级别进行error级别日志打印。打印规则见日志打印。
六. 资源的申请及使用
1. 线程、线程池
系统内部,通过系统线上配置参数,会生成系统内部统一的线程池,对于线程的调用,系统内部禁止自行显示创建线程,必须由线程池中线程进行申请。对于执行完成的线程,需要进行线程释放处理。
线程安全:如果一条线程中需要对多个资源进行处理,且多个资源项目独立(执行成功互不相关),则必须对处理资源进行try catch处理,防止因为单条任务执行造成线程中断。
多线程处理:在多线程开发当中,必须注意并发的处理,以防止导致死锁或者导致资损。
l 线程上下文变量的设置与清除必须配对处理例如对于ThreadLocal的使用。
l 静态Util、单例必须是线程安全的。
l 在进行加锁的时候,需要保持一致的加锁顺序,否则可能导致死锁。
2. 网络连接、数据库连接
对网络连接、数据库连接,必须由框架提供,禁止应用中自行建立网络与数据库连接。
3. 对IO操作
对于文件、流的IO操作,必须通过try{}finally{}包裹,无论执行是否成功,必须在finally中进行资源的关闭。
七. 本地事务操作
系统采用spring框架作为基础框架,因此,采用spring的编程式事务作为标准事物编码规范。
1. 事务使用场景
l 对于业务逻辑上不允许并发访问的数据,例如全局唯一性的数据、涉及到总类的数据,该情况下,必须采用事务加锁的方式进行处理 。
l 对于业务逻辑上要求完整性的数据,例如同时操作的多个表,同时对一个表进行反复操作等,在该种情况下必须进行事务声明
l 对于数据的删除、更新、存储操作,必须采用事务进行包裹
2. 事务模板示例
编程式事务采用回调模式,分别为TransactionCallback接口及TransactionCallbackWithoutResult接口,分别对应有返回值和无返回值。
使用案例如下:
3. 事务传播属性选择
Spring 提供6中事务传播属性分别为:
PROPAGATION_REQUIRED
PROPAGATION_SUPPORTS
PROPAGATION_MANDATORY
PROPAGATION_REQUIRES_NEW
PROPAGATION_NOT_SUPPORTED
PROPAGATION_NEVER
PROPAGATION_NESTED
在系统设计阶段未做特殊说明的情况下,采用默认事务传播属性。
八. 数据库操作规范
1. 大数据量查询
禁止将库中所有数据一次性读出至内存中,如果需要此类操作,必须使用分页查询模式,并且在读取下一次之前,清除内存中的数据信息。
2. 批量数据写入、更新
如果对数据库中操作的数据量较大,为了系统性能考虑(防止数据库服务器及系统机宕机),禁止对每一条记录做一次事务提交,必须采用批量的方式进行刷新处理。
3. 所有保存到db的时间必须取服务端的时间。
4. 所有的校验在前端和后端做双层校验;
5. SQL拼写规范
对SQL拼写规范请参见SQL规范。
九. 变量及基本代码规范
1. 对于金额的操作
新建系统对于钱的操作,统一采用CPMoney类型,禁止使用浮点数,如double、float等直接进行处理。
数据库中所保存的金额,单位统一为分。
2. 常量定义
对于常量的定义,全站统一采用大写模式,并且声明为static 及final类型。并且需要有详细的注释。
代码示例:
/**
* <h1>类说明<h1/>
*
* @authorZHANGGUOJING613
* @version$Id: TestCodeTemplate.java,v 0.1 2012-11-1下午04:58:06 ZHANGGUOJING613 Exp $
*/
public class TestCodeTemplate {
/*参数说明**/
private String userName="";
/*示例常量**/
private String DEMO_CONSTANT="DEMO_CONSTANT";
3. 对于对象模型原有方法的复写
对象模型,最基本的需要对toString方法进行复写,复写示例如下:
十. Java新特性-泛型
1、 对于使用JDK1.5以上(含)的应用,在编码过程中,集合类等用泛型。示例如下:
/**
* <h1>类说明<h1/>
*
* @authorZHANGGUOJING613
* @version$Id: TestCodeTemplate.java,v 0.1 2012-11-1下午04:58:06 ZHANGGUOJING613 Exp $
*/
public class TestCodeTemplate {
/*参数说明**/
private List<String>userNames= new ArrayList<String>();
十一. 系统间交互规范
1. Java系统之间的交互
Java系统之间通过ws进行交互,传入和传出参数为Object对象,对该Object对象必须继承 serializable接口。
2. 非java系统之间的交互
非同语言开发的系统之间的交互,交互媒介采用XML格式进行交互。
第二部分 数据库开发规范
一. 表设计规范
1. 命名规范
1.1. 表的命名规范
l 表的命名总长度限制:26位
l 表名由下划线及英文字母构成,命名格式为系统名_功能名
l 临时表的命名方式:TEMP_表缩写_日期
1.2. 字段的命名
l 字段的命名必须是非Orcale的关键字(参看Orcale手册)
l 字段名称长度限制:15位
l 字段命名应表明当前字段的含义
1.3. 约束的命名
l 约束名的长度限制:30位
l 主键约束:表名_字段名_PK
l 唯一性约束:表名_字段名_U
l 检查性约束:表名_字段名_C
2. 表创建规范
l 表的设计必须遵循第一范式,尽量达到第二范式及第三范式。范式的规定如下:
第一范式:即数据库表的每一列都是不可分割的原子数据项,而不能是集合,数组,记录等非原子数据项。
第二范式:要求数据库表中的每个实例或记录必须可以被唯一地区分,实体的属性完全依赖于主关键字。
第三范式:要求一个关系中不包含已在其它关系已包含的非主关键字信息。
l 表和字段必须由comment中文注释
l 除了临时表外,其他表必须由GMT_CREATE和GMT_MODIFIED其类型为TIMESTAMP。在做数据添加的时候,需要将GMT_CREATE\GMT_MODIFIED写入SYSDATE。在做数据更新时,需要更新GMT_MODIFIED时间。
l 为了提高数据库的处理效率,不在表中添加外键的关联关系。其关联关系由应用进行保证。
l 不添加带默认值的字段,如果需要采用默认至,通过应用DAL实现。
二. SQL开发规范
1. DQL(数据库查询语言)编码规范
l 禁止使用SELECT *,对查询必须指明返回字段。
l 业务系统的查询SQL,关联查询的表限制为3张表。
l 数据量大于1万的表,禁止使用全表查询。
l 禁止在表的索引列上进行类型转换,使用参数,或者计算。如果需要,在应用层中进行处理,计算完成之后,再传入SQL。
l 前台系统禁止使用like全模糊查询。
l 尽量不使用NOT EXISTS、NOT IN。
3. DML编码规范
l UPDATE操作,必须更新GMT_MODIFIED字段,特殊情况,如业务功能对GMT_MODIFIED有依赖的时候,可不更新,但需要做特殊说明。
l 对大批量数据的更新,需要使用分批更新的方法进行更新,不允许做一次性
三. SEQUENCE开发规范
1.命名格式
l 在一个表仅有一个Sequence的情况下,采用seq_表名进行命名
l 在一个表有多个字段使用sequence的情况下,采用seq_表名_字段名 进行命名。
2. 创建Sequence
l 对于创建的sequence需要使用cache。Oracle默认的cache大小为200。采用缓存,主要是为了减少对产生Sequence值的等待。其cache的大小需要支持5分钟业务,计算方法如下:如高分值为100,则CACHE量为100*5*60,如果该表有多个sequence,则每个sequence的量为总量除以sequence的个数。
l Sequence的最大长度不能够超过字段最大长度
l 创建Sequence的时候,需要制定minvalue\maxvalue\startwith\increment by\cache的值,而maxvalue的值为了统一,全部为9的数字。
Sequence创建附录:
create sequence trade.seq_trade_base
minvalue 1
maxvalue 999999
start with 1
increment by 1
cache 200
nocycle;