Java编码最佳实践指南_第1页
Java编码最佳实践指南_第2页
Java编码最佳实践指南_第3页
Java编码最佳实践指南_第4页
Java编码最佳实践指南_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、 JAVA 编码最佳实践指南未经许可,不可全部或部分发表、复制、使用于任何目的未经许可,不可全部或部分发表、复制、使用于任何目的JAVA 编码最佳实践指南编码最佳实践指南版本:V1.0 JAVA 编码最佳实践指南未经许可,不可全部或部分发表、复制、使用于任何目的未经许可,不可全部或部分发表、复制、使用于任何目的文档审批修订记录文档审批修订记录当前版本:当前版本:作作 者:者:审审 核核 人:人:文件状态: 草稿 正式发布 发布日期:发布日期:日期日期版本编号版本编号修订号修订号简要说明简要说明著者著者审核者审核者审核日期审核日期1说明:“简要说明”主要是对修订原因和修订的内容进行简单说明。 J

2、AVA 编码最佳实践指南未经许可,不可全部或部分发表、复制、使用于任何目的未经许可,不可全部或部分发表、复制、使用于任何目的 目录目录1JAVA 代码相关代码相关.12HIBERNATE 相关相关.43SQL/数据库相关数据库相关.5 JAVA 编码最佳实践指南 1 / 141 Java 代码相关代码相关1、 打开文件、流之后应及时关闭,避免过多占用系统 IO 资源。2、 避免在 for 循环中做 if 判断,便于编译优化。3、 不要两次初始化变量。例如:String a=new String();String a=some.invoke();优化为:String a=null;String

3、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(“

4、abcdefg”).append(“hijklmno”).append(“xyz”);String a=ab.toString();6、 使用预编译语句 prepareStatement 代替 createStatement,并使用占位符生成 SQL 语句,传递参数。例如: JAVA 编码最佳实践指南 2 / 14String sql=”select * from a where id=”+id+”;Statement st=conn.createStatement(sql);st.executeQuery();优化为:String sql=”select * from a where id=

5、?”;PreparedStatement pstmt=conn.prepareStatement(sql);pstmt.setString(1,id);pstmt.executeQuery(sql);7、 避免在循环中声明对象、操作数据库、打开文件等。例如:for (int i=0;in;i+) String date=ds.getDate();String sql=”update a set updateDate=? Where id=?”;ds.update(sql,new Objectdate,i );优化为:String date=ds.getDate();String sql=”up

6、date a set updateDate=? Where id in ?”int ids=new intn;for (int i=0;in;i+) idsi=I;ds.update(sql,new Objectdate,ids);8、 尽量避免使用递归调用9、 合理使用缓存。10、 异常在需要抛出的地方抛出,try catch 能整合就整合try some.method1(); / Difficult for javac catch( method1Exception e ) / and the JVM runtime/ Handle exception 1 / to optimize th

7、is JAVA 编码最佳实践指南 3 / 14 / codetry some.method2(); catch( method2Exception e ) / Handle exception 2try some.method3(); catch( method3Exception e ) / Handle exception 3以下代码 更容易被编译器优化try some.method1(); / Easier to optimizesome.method2();some.method3(); catch( method1Exception e ) / Handle exception 1

8、catch( method2Exception e ) / Handle exception 2 catch( method3Exception e ) / Handle exception 311、 尽量不要将超过 100K 以上的大对象如数组、集合对象(List、Map)放到 HttpSession 或其他需要序列化的对象中,并注意及时清空 Session。 JAVA 编码最佳实践指南 4 / 142 Hibernate 相关相关1、 使用命名查询来代替在代码中执行 HQL 查询。 JAVA 编码最佳实践指南 5 / 143 SQL/数据库相关数据库相关为了让应用程序运行得更快,有时候我们

9、需要把部分操作交数据库去操作,但是如果没有正确地进行数据库操作,则应用程序中的 SQL 查询有可能不能按照预想的方式进行响应(要么不返回数据、要么耗费的时间长得出奇)降低了应用程序的响应速度,用户必须等待的时间过长,这样便会影响到系统用户的正常业务操作,此规范的定制目的就是为了规范 SQL 的使用,提高系统性能。以下是针对 Oracle 数据库 SQL 操作的一般性原则,其它数据库应根据特定数据库的情况加以调整:尽可能地减少大表全表搜索,最常见方法是增加索引;当全表搜索是最快方法时,考虑将小表放到缓存中;选择最有效率的表名顺序。在 FROM 子句中包含多个表的情况下,你必须选择记录条数最少的表

10、作为基础表(或称驱动表).如果有 3 个以上的表连接查询, 那就需要选择交叉表(intersection table)作为基础表, 交叉表是指那个被其他表所引用的表;WHERE 子句中的连接顺序ORACLE 采用自下而上的顺序解析 WHERE 子句,根据这个原理,表之间的连接必须写在其他 WHERE 条件之前, 那些可以过滤掉最大数量记录的条件必须写在 WHERE 子句的末尾; SELECT 子句中避免使用* ;尽量多使用 COMMIT,COMMIT 可以释放占用的资源;计算记录条数:尽量用索引列的计数来代替 count(*);用 Where 子句替换 HAVING 子句。HAVING 只会在

11、检索出所有记录之后才对结果集进行过滤,这个处理需要排序,总计等操作;在含有子查询的 SQL 语句中,要特别注意减少对表的查询;操作符 IN:尽量不要使用,用 EXISTS 或连接进行替换;操作符 NOT IN:用 NOT EXISTS 或(外连接+判断为空)方案代替操作符:不会使用索引,由其他操作符替换操作符 IS NULL 或 IS NOT NULL:判断字段是否为空一般是不会应用索引的,因为 B 树索引是不索引空值的。操作符 LIKE:如 LIKE %5400% 这种查询不会引用索引,而 LIKE X5400%则会引用范围索引操作符 UNION: UNION 在进行表链接后会筛选掉重复的记

12、录,所以在表链接后会对所产生的 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_df302) X|hbs_bhX5400021452 , 优化处理: hbs_bh5400021542 3)sk_rq+5=sysdate,优化处理:sk_rq=

13、sysdate-54)hbs_bh=5401002554,优化处理:hbs_bh= 5401002554 ,注:假如 hbs_bh 字段是字符型,那么此条件对 hbs_bh 进行隐式的 to_number 转换, 。合理使用索引:索引是数据库中重要的数据结构,它的根本目的就是为了提高查询效率。索引的使用要恰到好处,其使用原则如下: 在经常进行连接,但是没有指定为外键的列上建立索引,而不经常连接的字段则由优化器自动生成索引。在频繁进行排序或分组(即进行 group by 或 order by 操作)的列上建立索引。在条件表达式中经常用到的不同值较多的列上建立检索,在不同值少的列上不要建立索引。比

14、如在雇员表的“性别”列上只有“男”与“女”两个不同值,因此就无必要建立索引。如果建立索引不但不会提高查询效率,反而会严重降低更新速度。如果待排序的列有多个,可以在这些列上建立复合索引(compound index) 。SQL 操作规范性:1、 慎用 循环操作数据库对于需要通过循环操作进行赋值的,在循环中慎用数据库操作语句进行操作,如果是大循环或者循环套循环的操作数据库 Hibernate 会带来与数据库的多次链接,影响了系统性能及数据库性能。对于大循环、循环套循环进行数据库操作的,建议考虑通过 SQL 实现一次交互实现。对于批量更新、删除某一条件下的数据时,如业务目的已明确,建议采用 SQL

15、批量操作。 JAVA 编码最佳实践指南 7 / 14例如:要制某客户下的所有合同(或满足某一条件的合同)为终止状态,则没有必要先查找出一个列表的数据然后再遍历这个列表一个一个对象去循环更新状态,建议通过 SQL 直接实现。再如需要删除某一业务下的所有明细,亦无必要通过业务编号先找出业务明细的列表再一条一条去删除,建议通过 SQL 直接以业务编号为参数进行明细的删除。当然,这些操作需要根据相应场景进行相应的考虑,但无论如何,大循环大对象的操作一定要慎重。2、 慎用 返回 VO 的方法调用对于程序中需要调用自己或其他模块的数据时,如果调用的方法返回的是 VO,一定要慎重考虑,首先要看该 VO 返回

16、的是否都是简单属性,如果不是,则看自己需要的内容是否仅是其中之一,其它无关信息的加载是否会产生大量的内存占用?如果是,则建议改用或新增方法实现数据的获取。3、 限用 关键字段不加非空判断的多条件查询目前系统中为了方便各种条件的数据查询,很多模块设置了 INFO 类的多条件查询,但是对于多条件查询,一定要在调用前对非空字段进行判断。4、 慎用 LEFT JOINLEFT JOIN 将包含了两个关联查询的表中的第一个(左边)表中的全部记录,即使在第二个(右边)表中并没有相符值的记录。但由于 LEFT JOIN 比 INNER JOIN 消耗资源更多,所以如果可以重新编写查询语句使得该查询不使用 L

17、EFT JOIN 则可能会带来性能上的提高。但如果确实有需要使用 LEFT JOIN进行数据库操作,则需要注意定义进行 LEFT JOIN 的字段不能为空,因为这样一来 LEFT JOIN 包含与 NULL(不存在)数据匹配的数据,消耗的资源非常多。因此在使用 LEFT JOIN 时必须在查询中调整数据的形态不能存在 NULL,使之适应应用程序所要求,才能带来性能上的提升。5、 限用 笛卡尔乘积(CROSS JOIN)在许多情况下,笛卡尔乘积 (CROSS JOIN)消耗的资源太多,从而无法高效使用。CROSS JOIN 是简单地、不加任何约束条件地把表组合。CROSS JOIN 后结果的行数

18、是连接前两个表行数的乘积。如果对两个分别有好几千行的表进行连接,则结果是不可想象的。如果需要为所有的可能性都返回数据(两表的全表乘积) ,则笛卡尔乘积可能会非常有帮助。但是,在大多数方案中 INNER JOIN 的效率要高得多,建议通过 INNER JOIN 来实现。如果执行了 CROSS JOIN,然后使用 WHERE 子句、DISTINCT 或 GROUP BY 来筛选出大多数行,其对资源的消耗是非常大的。而对此如果通过使用 INNER JOIN 也可以获得同样的结果,而且效率高得多。 JAVA 编码最佳实践指南 8 / 146、 建议 使用内连接代替 内嵌视图、EXISTS (NOT E

19、XISTS)、IN(NOT IN)子句用 IN 写出来的 SQL 的优点是比较容易写及清晰易懂,这比较适合现代软件开发的风格。但是用 IN 的 SQL 性能总是比较低的,从 ORACLE 执行的步骤来分析用 IN 的 SQL 与不用 IN 的SQL 有以下区别:Oracle 系统在执行 IN 子查询时,首先执行子查询,并将获得的结果列表存放在在一个加了索引的临时表中。在执行子查询之前,系统先将主查询挂起,待子查询执行完毕,存放在临时表中以后再执行主查询。里面关系到 full table scan 和 range scan,这也就是使用 EXISTS 比使用 IN 通常查询速度快的原因。临时表会

20、消耗一定资源,通过使用 EXIST,Oracle 系统会首先检查主查询,然后运行子查询直到它找到第一个匹配项,这相对于临时表节省了时间。但是如果通过内连接进行组装 SQL 进行查询,则效率会有更大的提升。建议:在业务密集的 SQL 当中尽量不采用 IN 操作符,通过内连接来实现数据库查询操作在性能上能有大的提升。7、 带条件的查询 建议 将可过滤大量不满足条件的数据的条件放在最后以往的数据库 SQL 执行情况是从后往往前执行,虽然现在数据库在数据库操作已可以忽略数据库操作时查询条件的组装顺序,但是从良好的 SQL 语言编写习惯出发,建议:在执行带条件查询的语句时将可过滤大量不满足条件的数据的条

21、件放在 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 null9、 慎用 NO

22、T我们在查询时经常在 where 子句使用一些逻辑表达式,如大于、小于、等于以及不等于等等,也可以使用 and(与) 、or(或)以及 not(非) 。NOT 可用来对任何逻辑运算符号取反。例如: JAVA 编码最佳实践指南 9 / 14下面是一个 NOT 子句的例子,. where not (status =VALID) 如果要使用 NOT,则应在取反的短语前面加上括号,并在短语前面加上 NOT 运算符。NOT 运算符包含在另外一个逻辑运算符中,这就是不等于()运算符。换句话说,即使不在查询 where 子句中显式地加入 NOT 词,NOT 仍在运算符中,见下例:. where status

23、 INVALID 再看下面这个例子:select * from employee where salary3000; 对这个查询,可以改写为不使用 NOT:select * from employee where salary3000; 虽然这两种查询的结果一样,但是第二种查询方案会比第一种查询方案更快些。第二种查询允许Oracle 对 salary 列使用索引,而第一种查询则不能使用索引。因此应尽量避免在 where 子句中使用!=或操作符,否则将引擎放弃使用索引而进行全表扫描。10、慎用 比较不匹配的数据类型比较不匹配的数据类型也是比较难于发现的性能问题之一。注意下面查询的例子,accou

24、nt_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,st

25、ate,zip from banks where account_number =990354;特别注意:不匹配的数据类型之间比较会让 Oracle 自动限制索引的使用,即便对这个查询执行Explain Plan 也不能让您明白为什么做了一 次“全表扫描” 。因此一定要慎用比较不匹配的数据类型,特别是我们系统中目前存在的对 VARCHAR2 型数据作为查询条件时没有对条件值增加引号。 (经过测试,当 account_numer 列中的值为字符类型或者查询条件中的值“account_number =字符型”时,Oracle 会自动转换并使用索引,但是如果列中的值为数值类型时出现了全表扫描: JA

26、VA 编码最佳实践指南 10 / 14Select * 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

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论