Chen Jian

AbstractWizardFormController中的command对象是如何进出session的

正常流程: Click "Next" all the way 1. 展现第一个表单时 — 系统会创建一个空的command对象并把它放入session中 2. 提交第一个表单时 — 系统会把command从session中取出,并立即把它从session中移除,然后再把request中的参数值塞到command中,在展现第二个表单之前,系统又会把这个对象塞回到session中 3. 提交第二个表单时 — 系统会把command从session中取出,并立即把它从session中移除,然后再把request中的参数值塞到command中。当展现最终的结果页面时,session中已没有command对象 正常流程: Click "Back" 1. 展现第一个表单时 — 系统会创建一个空的command对象并把它放入session中 2. 提交第一个表单时 — 系统会把command从session中取出,并立即把它从session中移除,然后再把request中的参数值塞到command中,在展现第二个表单时,系统又把这个对象塞回到session中 3. 在第二个表单点“Back”时 — 系统会把command从session中取出,并立即把它从session中移除,然后再把request中的参数值塞到command中。在展现第一个表单时,系统会把这个对象塞回到session中,并把对象丢到Model中,好让第一个表单展现它 异常流程: 1. 展现第一个表单时 — 系统会创建一个空的command对象并把它放入session中 2. 错误地提交第一个表单后 — 系统会把command从session中取出,并立即把它从session中移除,然后再把request中的参数值塞到command中;由于出错,所以会重现第一个表单,这时系统会把command塞回到session中 3. 这时如果按“F5” — 系统就会重走第2步 4. 正确地提交第一个表单和第二个表单,直到看到结果页面  — 到这里session中已无command 5. 如果这时用户按 "F5" 重复提交 — …

AbstractWizardFormController中的command对象是如何进出session的 Read More »

Oracle中 To_Date 函数 的用法

to_date(‘2003/07/09’, ‘yyyy/mm/dd’)  would return a date value of July 9, 2003. to_date(‘070903’, ‘MMDDYY’) would return a date value of July 9, 2003. to_date(‘20020315’, ‘yyyymmdd’) would return a date value of Mar 15, 2002. See `http://www.techonthenet.com/oracle/functions/to_date.php

倒底要不要使用Bind Variables

为了避免硬解析(即为了实现游标缓存),应该使用Bind Variables。这点大家都知道。 然而, Bind Variables如果出现在where子句中,它就会减弱查询优化器的某种能力:根据统计信息和SQL中的字面量选择最优的执行计划。  比如说,假定当前表里的age大都是50岁以下。如果SQL里指定了按 age<50 来查询,那优化器就会来一个全表扫描,快速返回相应数据; 如果SQL里使用的是 age < :age1,那优化器就不敢轻易走全表扫描了 (11g里部分地解决了这个问题,在此不表)。 那倒底要不要用Bind Variables呢? 《Troubleshooting Oracle Performance》给出的方案是:   1. 如果Bind Variable并没有出现where子句,那就没有理由不用它   2. 在小量数据查询环境下,如 OLTP中,硬解析的时间与执行时间相当甚至更大, 应该使用Bind Variable,避免硬解析   3. 在大量数据查询环境下,如 OLAP中,硬解析的时间与执行时间相比只是一个零头, 这时就应用直接用字面量,以免查询优化器选错了执行计划。

软解析、硬解析及其对性能的影响

SQL解析时要经历以下几个步骤:    1. VPD相关处理    2. 语法、语义、权限检查    3. 对SQL进行逻辑优化    4. 再进行物理优化 这其中会牵涉到游标的缓存读写: 看下缓存里有没有所需的游标,有就读出来直接用,没有就要创建一个出来用,用完后塞到缓存中。 如果缓存已存在,那就只需执行上面的步骤#1和步骤#2。 这就是软解析。 否则,就会执行所有步骤。这就是硬解析。 由于步骤#3和#4比较耗费CPU,而在缓存里创建新游标又比较耗内存,因此硬解析比软解析的开销要大很多,因此应该尽量避免硬解析。 要避免硬解析,就得尽量重用缓存中的游标。而游标是以SQL为Key的,要重用游标,就要尽量对同样的操作使用同样的SQL(大小写、空格都要一样),也就是说要用Bind Variables. ============================================================ 不过,软硬解析代价都其实都很高,因为它们都会产生对共享资源的竞争使用。 Oracle中,这些操作的并发性达到了“可串行化”级别,对性能的影响很大。

Notes on ‘Refactoring ‘ — 6.1 Replace Inheritance with Delegation

When?   You find that some of the superclass operations aren’t really true of the subclass. The code is saying the subclass has some interface that it doesn’t have. This is confusing. How to solve it?   1. The subclass doesn’t extend its superclass anymore   2. Instead, subclass should REFERENCE superclass to use it …

Notes on ‘Refactoring ‘ — 6.1 Replace Inheritance with Delegation Read More »

Notes on ‘Refactoring ‘ — 5.2 Replace Exception with Test

Before Refactoring try{ return list.get(index); }catch(IndexOutOfBoundsExceptione){ return null; } After Refactoring if(index >= list.size()){ return null; } return list.get(index); Benefits: Avoid too many exceptions since it is not so good to read and it should only be used for an exception flow.

Notes on ‘Refactoring ‘ — 5.1 Seperate Query from Modifier

Before Refactoring getPersonAndIncreaseCounter(){ counter ++; return person; } After Refactoring getPerson(){ return person; } increaseCounter{ counter ++; } Benefits     You can call getPerson() as often as you like. You have a lot less to worry about. Exception    It’s OK to change personCache in getPerson() method.

Notes on ‘Refactoring ‘ — 4.1 Decompose Conditional

Before Refactor if(age < 60 && age >= 50){ salary = age*10 + 100; }else{ salary = age*5; } After Refactor if(isMidAge(age)){ salary = midAgeSalary(age); }else{ salary = nonMidAgeSalary(age); } Benefits: You hightlight the condiction and make it clear what you are branching on.