




已阅读5页,还剩9页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
JAVA 编码最佳实践指南 未经许可 不可全部或部分发表 复制 使用于任何目的未经许可 不可全部或部分发表 复制 使用于任何目的 JAVA 编码最佳实践指南编码最佳实践指南 版本 V1 0 JAVA 编码最佳实践指南 未经许可 不可全部或部分发表 复制 使用于任何目的未经许可 不可全部或部分发表 复制 使用于任何目的 文档审批修订记录文档审批修订记录 当前版本 当前版本 作作 者 者 审审 核核 人 人 文件状态 草稿 正式发布 发布日期 发布日期 日期日期版本编号版本编号修订号修订号简要说明简要说明著者著者审核者审核者审核日期审核日期 1 说明 简要说明 主要是对修订原因和修订的内容进行简单说明 JAVA 编码最佳实践指南 未经许可 不可全部或部分发表 复制 使用于任何目的未经许可 不可全部或部分发表 复制 使用于任何目的 目录目录 1JAVA 代码相关代码相关 1 2HIBERNATE 相关相关 4 3SQL 数据库相关数据库相关 5 JAVA 编码最佳实践指南 1 14 1 Java 代码相关代码相关 1 打开文件 流之后应及时关闭 避免过多占用系统 IO 资源 2 避免在 for 循环中做 if 判断 便于编译优化 3 不要两次初始化变量 例如 String a new String String a some invoke 优化为 String a null String a some invoke 4 使用 final static 声明 log4j 对象 减少内存占用 例如 public class a private Log logger Log getLogger this class 优化为 public class a private final static logger Log getLogger a class 5 使用 StringBuffer 拼接字符串 例如 String a abcdefg hijklmno xyz 优化为 StringBuffer ab New StringBuffer append abcdefg append hijklmno append xyz String a ab toString 6 使用预编译语句 prepareStatement 代替 createStatement 并使用占位符生成 SQL 语句 传 递参数 例如 JAVA 编码最佳实践指南 2 14 String sql select from a where id id Statement st conn createStatement sql st executeQuery 优化为 String sql select from a where id PreparedStatement pstmt conn prepareStatement sql pstmt setString 1 id pstmt executeQuery sql 7 避免在循环中声明对象 操作数据库 打开文件等 例如 for int i 0 i n i String date ds getDate String sql update a set updateDate Where id ds update sql new Object date i 优化为 String date ds getDate String sql update a set updateDate Where id in int ids new int n for int i 0 i n i ids i I ds update sql new Object date ids 8 尽量避免使用递归调用 9 合理使用缓存 10 异常在需要抛出的地方抛出 try catch 能整合就整合 try some method1 Difficult for javac catch method1Exception e and the JVM runtime Handle exception 1 to optimize this JAVA 编码最佳实践指南 3 14 code try some method2 catch method2Exception e Handle exception 2 try some method3 catch method3Exception e Handle exception 3 以下代码 更容易被编译器优化 try some method1 Easier to optimize some method2 some method3 catch method1Exception e Handle exception 1 catch method2Exception e Handle exception 2 catch method3Exception e Handle exception 3 11 尽量不要将超过 100K 以上的大对象如数组 集合对象 List Map 放到 HttpSession 或其 他需要序列化的对象中 并注意及时清空 Session JAVA 编码最佳实践指南 4 14 2 Hibernate 相关相关 1 使用命名查询来代替在代码中执行 HQL 查询 JAVA 编码最佳实践指南 5 14 3 SQL 数据库相关数据库相关 为了让应用程序运行得更快 有时候我们需要把部分操作交数据库去操作 但是如果没有正确地进 行数据库操作 则应用程序中的 SQL 查询有可能不能按照预想的方式进行响应 要么不返回数据 要么 耗费的时间长得出奇 降低了应用程序的响应速度 用户必须等待的时间过长 这样便会影响到系统用 户的正常业务操作 此规范的定制目的就是为了规范 SQL 的使用 提高系统性能 以下是针对 Oracle 数据库 SQL 操作的一般性原则 其它数据库应根据特定数据库的情况加以调整 尽可能地减少大表全表搜索 最常见方法是增加索引 当全表搜索是最快方法时 考虑将小表放到缓存中 选择最有效率的表名顺序 在 FROM 子句中包含多个表的情况下 你必须选择记录条数最少的表 作为基础表 或称驱动表 如果有 3 个以上的表连接查询 那就需要选择交叉表 intersection table 作为基 础表 交叉表是指那个被其他表所引用的表 WHERE 子句中的连接顺序 ORACLE 采用自下而上的顺序解析 WHERE 子句 根据这个原理 表 之间的连接必须写在其他 WHERE 条件之前 那些可以过滤掉最大数量记录的条件必须写在 WHERE 子句 的末尾 SELECT 子句中避免使用 尽量多使用 COMMIT COMMIT 可以释放占用的资源 计算记录条数 尽量用索引列的计数来代替 count 用 Where 子句替换 HAVING 子句 HAVING 只会在检索出所有记录之后才对结果集进行过滤 这个处理需要排序 总计等操作 在含有子查询的 SQL 语句中 要特别注意减少对表的查询 操作符 IN 尽量不要使用 用 EXISTS 或连接进行替换 操作符 NOT IN 用 NOT EXISTS 或 外连接 判断为空 方案代替 操作符 不会使用索引 由其他操作符替换 操作符 IS NULL 或 IS NOT NULL 判断字段是否为空一般是不会应用索引的 因为 B 树索引 是不索引空值的 操作符 LIKE 如 LIKE 5400 这种查询不会引用索引 而 LIKE X5400 则会引用范 围索引 操作符 UNION UNION 在进行表链接后会筛选掉重复的记录 所以在表链接后会对所产生的 JAVA 编码最佳实践指南 6 14 结果集进行排序运算 删除重复的记录再返回结果 用 UNION ALL 替换 采用函数处理的字段不能利用索引 例如 1 substr hbs bh 1 4 5400 优化处理 hbs bh like 5400 2 trunc sk rq trunc sysdate 优化处理 sk rq trunc sysdate and sk rq50 优化处理 ss df 30 2 X hbs bh X5400021452 优化处理 hbs bh 5400021542 3 sk rq 5 sysdate 优化处理 sk rq sysdate 5 4 hbs bh 5401002554 优化处理 hbs bh 5401002554 注 假如 hbs bh 字段是字符型 那么 此条件对 hbs bh 进行隐式的 to number 转换 合理使用索引 索引是数据库中重要的数据结构 它的根本目的就是为了提高查询效率 索引的使用要恰到好处 其使用原则如下 在经常进行连接 但是没有指定为外键的列上建立索引 而不经常连接的字段则由优化器自动生 成索引 在频繁进行排序或分组 即进行 group by 或 order by 操作 的列上建立索引 在条件表达式中经常用到的不同值较多的列上建立检索 在不同值少的列上不要建立索引 比如在雇员表的 性别 列上只有 男 与 女 两个不同值 因此就无必要建立索引 如果建立 索引不但不会提高查询效率 反而会严重降低更新速度 如果待排序的列有多个 可以在这些列上建立复合索引 compound index SQL 操作规范性 1 慎用 循环操作数据库 对于需要通过循环操作进行赋值的 在循环中慎用数据库操作语句进行操作 如果是大循环或者循 环套循环的操作数据库 Hibernate 会带来与数据库的多次链接 影响了系统性能及数据库性能 对于大循 环 循环套循环进行数据库操作的 建议考虑通过 SQL 实现一次交互实现 对于批量更新 删除某一条件下的数据时 如业务目的已明确 建议采用 SQL 批量操作 JAVA 编码最佳实践指南 7 14 例如 要制某客户下的所有合同 或满足某一条件的合同 为终止状态 则没有必要先查找出一个列表的 数据然后再遍历这个列表一个一个对象去循环更新状态 建议通过 SQL 直接实现 再如需要删除某一业务下的所有明细 亦无必要通过业务编号先找出业务明细的列表再一条一条去 删除 建议通过 SQL 直接以业务编号为参数进行明细的删除 当然 这些操作需要根据相应场景进行相应的考虑 但无论如何 大循环大对象的操作一定要慎重 2 慎用 返回 VO 的方法调用 对于程序中需要调用自己或其他模块的数据时 如果调用的方法返回的是 VO 一定要慎重考虑 首 先要看该 VO 返回的是否都是简单属性 如果不是 则看自己需要的内容是否仅是其中之一 其它无关 信息的加载是否会产生大量的内存占用 如果是 则建议改用或新增方法实现数据的获取 3 限用 关键字段不加非空判断的多条件查询 目前系统中为了方便各种条件的数据查询 很多模块设置了 INFO 类的多条件查询 但是对于多条件 查询 一定要在调用前对非空字段进行判断 4 慎用 LEFT JOIN LEFT JOIN 将包含了两个关联查询的表中的第一个 左边 表中的全部记录 即使在第二个 右边 表中并没有相符值的记录 但由于 LEFT JOIN 比 INNER JOIN 消耗资源更多 所以如果可以重新编写 查询语句使得该查询不使用 LEFT JOIN 则可能会带来性能上的提高 但如果确实有需要使用 LEFT JOIN 进行数据库操作 则需要注意定义进行 LEFT JOIN 的字段不能为空 因为这样一来 LEFT JOIN 包含与 NULL 不存在 数据匹配的数据 消耗的资源非常多 因此在使用 LEFT JOIN 时必须在查询中调整数 据的形态不能存在 NULL 使之适应应用程序所要求 才能带来性能上的提升 5 限用 笛卡尔乘积 CROSS JOIN 在许多情况下 笛卡尔乘积 CROSS JOIN 消耗的资源太多 从而无法高效使用 CROSS JOIN 是简 单地 不加任何约束条件地把表组合 CROSS JOIN 后结果的行数是连接前两个表行数的乘积 如果对两 个分别有好几千行的表进行连接 则结果是不可想象的 如果需要为所有的可能性都返回数据 两表的 全表乘积 则笛卡尔乘积可能会非常有帮助 但是 在大多数方案中 INNER JOIN 的效率要高得多 建议通过 INNER JOIN 来实现 如果执行了 CROSS JOIN 然后使用 WHERE 子句 DISTINCT 或 GROUP BY 来筛选出大多数行 其对资源的消耗是非常大的 而对此如果通过使用 INNER JOIN 也可 以获得同样的结果 而且效率高得多 JAVA 编码最佳实践指南 8 14 6 建议 使用内连接代替 内嵌视图 EXISTS NOT EXISTS IN NOT IN 子句 用 IN 写出来的 SQL 的优点是比较容易写及清晰易懂 这比较适合现代软件开发的风格 但是用 IN 的 SQL 性能总是比较低的 从 ORACLE 执行的步骤来分析用 IN 的 SQL 与不用 IN 的 SQL 有以下区别 Oracle 系统在执行 IN 子查询时 首先执行子查询 并将获得的结果列表存放在在一个加了索引的临 时表中 在执行子查询之前 系统先将主查询挂起 待子查询执行完毕 存放在临时表中以后再执行主 查询 里面关系到 full table scan 和 range scan 这也就是使用 EXISTS 比使用 IN 通常查询速度快的原因 临时表会消耗一定资源 通过使用 EXIST Oracle 系统会首先检查主查询 然后运行子查询直到它找到 第一个匹配项 这相对于临时表节省了时间 但是如果通过内连接进行组装 SQL 进行查询 则效率会有 更大的提升 建议 在业务密集的 SQL 当中尽量不采用 IN 操作符 通过内连接来实现数据库查询操作在性能上 能有大的提升 7 带条件的查询 建议 将可过滤大量不满足条件的数据的条件放在最后 以往的数据库 SQL 执行情况是从后往往前执行 虽然现在数据库在数据库操作已可以忽略数据库操 作时查询条件的组装顺序 但是从良好的 SQL 语言编写习惯出发 建议 在执行带条件查询的语句时将 可过滤大量不满足条件的数据的条件放在 SQL 最尾部 8 慎用 IS NULL 与 IS NOT NULL 字段使用索引 不能用 null 作为索引 任何包含 null 值的列都不要被包含在索引中 即使索引有多列这样的情况下 只要这些列中有一列含有 null 该列就会从索引中排除 也就是说如果某列存在空值 即使对该列建索引 也不会提高性能 任何在 where 子句中使用 is null 或 is not null 的语句优化器必须慎用 应尽量避免在 where 子句中对字段进行 null 值判断 否则将导致引擎放弃使用索引而进行全表扫 描 如 Select id from t where num is null 9 慎用 NOT 我们在查询时经常在 where 子句使用一些逻辑表达式 如大于 小于 等于以及不等于等等 也可 以使用 and 与 or 或 以及 not 非 NOT 可用来对任何逻辑运算符号取反 例如 JAVA 编码最佳实践指南 9 14 下面是一个 NOT 子句的例子 where not status VALID 如果要使用 NOT 则应在取反的短语前面加上括号 并在短语前面加上 NOT 运算符 NOT 运算符 包含在另外一个逻辑运算符中 这就是不等于 运算符 换句话说 即使不在查询 where 子句中显式地加入 NOT 词 NOT 仍在运算符中 见下例 where status INVALID 再看下面这个例子 select from employee where salary3000 对这个查询 可以改写为不使用 NOT select from employee where salary3000 虽然这两种查询的结果一样 但是第二种查询方案会比第一种查询方案更快些 第二种查询允许 Oracle 对 salary 列使用索引 而第一种查询则不能使用索引 因此应尽量避免在 where 子句中使用 或操作符 否则将引擎放弃使用索引而进行全表扫描 10 慎用 比较不匹配的数据类型 比较不匹配的数据类型也是比较难于发现的性能问题之一 注意下面查询的例子 account number 是一个 VARCHAR2 类型 在 account number 字段上有索引 下面的语句将执行全表扫描 select bank name address city state zip from banks where account number 990354 Oracle 可以自动把 where 子句查询条件属性字段 account number 对应的数据库值进行转换变成 to number account number 990354 这样就限制了索引的使用 改成下面的查询 正确做法 就可以使用 索引 select bank name address city state zip from banks where account number 990354 特别注意 不匹配的数据类型之间比较会让 Oracle 自动限制索引的使用 即便对这个查询执行 Explain Plan 也不能让您明白为什么做了一 次 全表扫描 因此一定要慎用比较不匹配的数据类型 特别是我们系统中目前存在的对 VARCHAR2 型数据作为查 询条件时没有对条件值增加引号 经过测试 当 account numer 列中的值为字符类型或者查询条件中的值 account number 字符型 时 Oracle 会自动转换并使用索引 但是如果列中的值为数值类型时出现了全表扫描 JAVA 编码最佳实践指南 10 14 Select from corporation customer cc where cc party id 1 使用了索引 Select from corporation customer cc where cc party id 1 使用了索引 Select from corporation customer cc where cc customer num 1 使用了索引 Select from corporation customer cc where cc customer num 1 全表扫描 通过 Hibernate from CustomerBaseBO cc where cc customerNum 1 报 ORA 01722 错 Select from corporation customer cc where cc customer num W1 报 ORA 00904 错 Select from corporation customer cc where cc customer num 1E 报 ORA 00933 错 11 建议 尽量避
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 【含答案】天津市安全员B证模拟题
- 2025设备采购合同模板专业版(合同版本)
- 2025钢材购销合同样本
- 2025标准版医院医生劳动合同范本
- 2025股权赠与合同范本
- 安全知识考试题(食品安全应急物资使用)
- 2025版事业单位劳动合同
- 牙片室试题及答案
- 2025标准合同股权转让意向书
- 智能洗浴系统创新创业项目商业计划书
- DB65T 2283-2005新疆平原杨树人工林二元立木材积表
- 现场审核检查清单及内审检查表
- 消费者鸡蛋购买行为调查报告
- GB/T 42062-2022医疗器械风险管理对医疗器械的应用
- GB/T 30106-2013钟表防水手表
- 多模态语篇分析课件
- 《卫生检验与检疫学导论》教学大纲
- 前厅服务与管理课程标准
- 常见药物之间的配伍禁忌课件
- DB32-T 4357-2022 建筑工程施工机械安装质量检验规程
- 【外研社Unipus】新探索(基础级)读写U1课件-AE1
评论
0/150
提交评论