J2EE框架项目编程规范,是以架构组组件开发为基础的编程规范,JAVA基础编程规范是J2EE项目编程规范的基础。
一 命名规范
J2EE框架项目中,类、接口、方法、变量等的命名,除了要遵守JAVA基本命名规范外,还需要遵循一定的命名习惯。
1 目录命名
com.xxx.项目名.模块名
项目名和模块名需简写且能反映一定的业务含义
2 类命名
J2EE框架中,类的功能分多个层次,各层次类的命名有各自的特点。以下,包含了大多数常用的、基本类型的类的命名规则,但无法包罗所有类的情况。其他类的命名可以以此为参考。
1)实体层Entity
命名规则如下:
实体必须继承com.xxx.项目简称.entity.Entity
单表实体类 | 数据库对象类名+ Entity | CdeUsrEntity |
---|
2)持久层dao
如果持久层使用接口类和实现类,那么命名规则如下:
DAO层必须继承com.xxxb.项目简称.dao.AbstractDAO
DAOIMPL必须继承com.xxx.项目简称.dao.impl.AbstractDAOImpl
层次类型 | 规则 | 实例 |
---|---|---|
单表处理接口类 | 数据库对象类名+ DAO | UserInfoDAO |
单表处理实现类 | 数据库对象类名+ DAOImpl | UserInfoDAOImpl |
3)业务层(service)
业务层的类,不需要与持久层的类一一对应,可以按照模块和业务逻辑来划分。对于大的模块,可以根据业务逻辑进行适当的划分,防止实现类代码量太多。
Service必须继承com.xxx.项目简称.service.BaseService
ServiceImpl必须继承com.xxx.项目简称.service.impl.BaseServiceImpl,成员函数抛出ServiceException
如果业务层使用接口类和实现类,那么命名规则如下:
层次类型 | 规则 | 实例 |
---|---|---|
业务层接口类 | 业务逻辑名 + Service | UserService |
业务层实现类 | 业务逻辑名 + ServiceImpl | UserServiceImpl |
4)业务层页面请求处理层
Action/Controller层必须继承com.xxx.项目简称.action.BaseAction/controller.BaseController
页面请求处理层的类,可以按照页面逻辑进行划分,比如用户的新增、修改、删除、查询用一个类,用户组的新增、修改、删除、查询用一个类。
层次类型 | 规则 | 实例 |
---|---|---|
Action | 业务逻辑名 + Action | UserInfoAction |
Controller | 业务逻辑名 + Controller | UserInfoController |
5)其他类
层次类型 | 规则 | 实例 |
---|---|---|
工具类 | 工具描述 + Util | UserUtil |
全局常量类 | ConsConfigCode | ConsConfigCode |
模块专用常量类 | 模块名 + Constants | EnlConstants |
3 方法命名
1)持久层(dao)
持久层类的基本方法主要有以下这些(此部分可由代码自动生成工具处理):
功能描述 | 方法名 | 参数 | 返回值 |
---|---|---|---|
新增一个持久对象 | insert | 值对象 | void |
更新一个持久对象 | update | 持久对象 | void |
删除一个持久对象 | delete | 持久对象 | void |
删除一个持久对象 | deleteById | id | void |
获取一个持久对象 | load | id | 持久对象 |
获取单个对象或值 | getXxx | ||
获取对象集合 | queryXxx | List、Map等 | |
根据条件获取分页对象集 | queryXXXXXPage | 查询条件,页数,页长度 | Page |
2)业务层(service)
业务层类的基本方法主要有以下这些(此部分可由代码自动生成工具处理):
功能描述 | 方法名 | 参数 | 返回值 |
---|---|---|---|
新增对象 | addXxx | 值对象 | void |
修改对象 | updateXxx | 值对象 | void |
删除对象 | deleteXxx | 值对象 | void |
获取对象 | queryXxx | 查询对象 | List、Page、Map等 |
3)页面请求处理层(action/controller)
页面请求处理层类(也就是 Action或者controller)的基本方法主要有以下这些
每个成员函数对应method名称:
功能描述 | 方法名 | 参数 | 返回值 |
---|---|---|---|
进入新增页面 | toAddXxx | void | |
新增提交 | addXxx | 对象表单 | void |
进入修改页面 | toUpdateXxx | id | void |
修改提交 | updateXxx | 对象表单 | void |
删除提交 | deleteXxx | id | void |
查看详细信息 | getXxx | id | void |
查看列表 | queryXxx | 查询对象 | void |
4 页面文件命名
页面文件的命名,字母全部使用小写。页面文件的类型包括:
- html文件,如infodetail.html
- javascript的js文件,如validator_1.1.0.js
- css文件,如style.css
- 图片文件,如buttom_small.jpg
这里重点讲一下jsp的命名规则。对于jsp文件,命名规则如下:
功能描述 | 方法名 | 参数 |
---|---|---|
新增 | addXxx.jsp | |
修改 | updateXxx.jsp | 值对象 |
编辑(新增、修改的合并) | editXxx.jsp | 值对象 |
详细信息 | showXxx.jsp | 值对象 |
列表 | showxxxList.jsp | List 分页信息 |
二 各层代码分工
持久层、业务层、页面请求处理层、用户界面层和数据模型层,每个层面各施其职,但又相互合作。
1 用户界面层(JSP)
用户界面层直接与用户打交道,用户通过用户界面层使用应用系统,并进行数据输入输出操作。
用户界面层负责以下任务:
- 将页面请求处理层输出的数据展示在页面上
- 提供用户输入数据的界面
- 进行页面数据验证
- 向页面请求处理层发出数据处理请求
- 界面层一般只使用到entity/mode对象和工具类
用户界面层不执行以下操作:
- 不直接与业务层、持久层、数据库进行通信
- 不处理与应用程序相关的业务逻辑
- 不进行事务管理
- 复杂的逻辑,请交给工具类来处理
2 页面请求处理层(Controller)
页面请求处理层,接受用户通过用户界面层发出的数据处理请求,并调用业务层处理数据,然后将处理结果返回给用户界面层。
页面请求处理层负责以下任务:
- 管理用户界面层发出的请求,做出相应的响应
- 从页面取得相应的用户输入数据
- 将数据提供给业务层,委派调用业务逻辑和其它上层处理
- 统一处理异常,包括持久层和业务层抛出的异常
- 为页面显示提供数据模型
用户身份和操作权限验证页面请求处理层不执行以下操作,否则会带来高耦合和麻烦的维护:
- 不直接的与持久层、数据库进行通信
- 不处理与应用程序相关联的业务逻辑
- 不进行事务管理
3 业务层(Service)
业务层负责应用程序逻辑处理和事务管理。它由页面请求处理层调用,并调用相关持久层方法实现逻辑和事务处理。
业务层负责以下任务:
- 从页面请求处理层得到数据模型
- 处理应用程序的业务逻辑和业务校验
- 统一管理事务
- 在页面请求处理层和持久层之间增加了一个灵活的机制,使得他们不直接的联系在一起
- 管理程序的执行(从业务层到持久层)
业务层不执行以下操作:
- 不直接与数据库通信
- 不应该出现数据库查询语句SQL和HQL
- 不直接与JSP、Session等进行通信
4 持久层(DAO)
持久层直接与数据库进行通信,通过数据库查询和执行语句,存取数据库数据。由业务层进行调用。
持久层负责以下任务:
- 从业务层得到数据操作命令
- 对数据库进行数据存取
持久层不执行以下操作:
- 不处理业务逻辑
- 不直接与JSP、Session等进行通信
5 数据模型层(Entity/Mode)
数据模型是对象集合,它在不同层之间移动。开发者在这层,仅关注Business Object即可。例如,持久层允许你将数据库中的信息存放入对象,这样你可以在连接断开的情况下把这些数据显示到UI层。 而那些对象也可以返回给持久层,从而在数据库里更新。这个模型使得Java开发者能很自然运用OO,而不需要附加的编码。
数据模型层负责以下任务:
- 封装数据模型对象,提供get、set方法
数据模型层不执行以下任务:
- 不处理业务逻辑
- 不与数据库通信
- 不进行数据验证处理
6 配置(XML)
在src/config/sqlmap/模块名下添加各模块的Sql语句
在src/config/trans/模块名下添加各模块的bean配置
Bean配置的文件命名方式为:
trs_ + 模块名(子模块名) + .xml (action/controller层的配置文件)
模块名(子模块名) + “_service.xml” (service层的配置文件)
模块名(子模块名) + “_dao .xml” (dao层的配置文件)
三 字符集
- 将Eclipse或IDEA中的字符集设置为UTF-8(根据项目需要设置)
- web.xml文件中的filter“Set Character Encoding”中的字符集设置为UTF-8(根据项目需要设置)
- 所有jsp、html文件中的charset,设置为UTF-8(根据项目需要设置)。
使用NotePad创建的文件,默认字符集不是UTF-8(根据项目需要设置),需要进行转换。对于已经是UTF-8(根据项目需要设置)格式的文件,NotePad等编辑器可以自动辨认。
Eclipse中设置字符集的方式:
方式一:修改Eclipse默认的字符集:
在Eclipse的Windows à Preference à General à Workspace页面中,设置“Text file encoding”为UTF-8(根据项目需要设置)。这样,在Eclipse中建立的项目,如果项目没有特别指定字符集,就会使用Eclipse的默认字符集。
方式二:修改项目的字符集:
在项目名称的右键弹出菜单的Preference à Info页面中,选择“Text file encoding”为UTF-8(根据项目需要设置)。这样,该项目的字符集就是UTF-8(根据项目需要设置),而不管Eclipse默认的字符集是什么。
IntelliJ IDEA中设置字符集的方式:
在IDEA的Fileà Settingsà File encodings 页面中,设置“Global Encoding和Project Encoding”为UTF-8(根据项目需要设置)同时在Path路径下的项目后面Encoding选择UTF-8,最后将下面的Default encoding for properties files 设置为UTF-8。这样,在IDEA中建立的项目,如果项目没有特别指定字符集,就会使用UTF-8字符集。
四 业务参数管理
- 开发时需注意,针对有业务意义的参数,需要对其进行整合,在统一的类中管理,数据可存在类中,或者存在数据库中加载。一般使用CODEBOOK对业务参数进行管理。
举例说明:
有一业务参数为生效状态,包含01未生效,02已生效,03生效中,那么在CODEBOOK中定义一个生效状态的MAP变量,存放以上所有状态信息,包括code和name,信息可定义成静态变量,更好的方式是存储在DB管理,服务启动后直接加载入缓存。 - 业务参数定义后,各个模块都必须使用该参数,禁止自行定义,防止后期修改参数时漏掉。
五 系统参数管理
- 路径类参数:路径类的参数需要定义一个根目录,其他目录依据目录拼接而成,方便后期维护。
- 密码类参数:密码不允许明文存储,需要使用加密程序进行加密后,存储在参数文件中,编码时,用解密程序解密后使用。
- 自动化部署参数:开发时需要注意使用的自动化部署工具,并根据工具要求,设置不同环境下的参数及文件。
六 日志管理
- 分级:开发时需要按照项目要求,对日志进行分级处理,编码时根据信息类型不同,使用不同级别的日志输出方法。
- 路径:对日志的保存路径需要符合项目的要求,统一放置,以便查询。
- 清理:需要考虑日志清理策略。
- 日志规格:日志文件需要考虑根据工程、日期、大小、分级生成。
七 数据库访问(Mybatis)
- 参数使用##,禁止使用$$。
- 参数后跟上jdbcType,明确类型。
- 重复且功能相似的内容尽量使用sql块,方便维护调用。
- 注意区分union及union all 的使用。前者会去除重复项,后者则不会。
- 查询条件尽量使用索引项,并且将表字段放左边。
- 查询数据时要考虑查询条件的限制,避免查询大批数据。
- 尽量避免使用exist、not exist、in、not in。
- SQL尽量不要写的过于复杂,不利于优化器生成执行计划,进而影响性能。
- 编写动态SQL时,要注意条件的设置是否考虑全面,例如空和null,使用动态标签时,要考虑该段SQL存在或不存在时是否会导致语法错误。
- 对数据库操作时要考虑事务性,成功时,该提交的提交,失败时,该回滚的回滚,不能回滚的要更新会原有状态。
- SQL中禁止硬编码,需要通过参数传进来,而不是直接将参数写死在SQL中。
八 分布式开发
- 分布式往往会将功能分模块,每个模块专门负责业务管理紧密的多个功能,当模块间需要使用对方模块表数据时,尽量通过调用对方模块的方法去获取数据(dubbo架构中可让对方模块提供微服务供调用)。避免直接访问对方表,以确保模块化,也方便分库。
- 分布式开发时需要考虑交易是否具有事务性。有事务性处理时要注意出现异常时,需要根据业务进行合适的调整。
- 分布式系统,各个模块由于会部署在不同机器上,且各模块本身一般至少在两个机器上部署,所以开发时需要考虑一致性的问题,涉及到公共可变的内容,最好从数据库或者共享内存中获取,不可从缓存中直接获取。
- 分布式系统,会启动很多进程,当需要是使用缓存时,要注意数据同步的问题,保持一致性。