java 类初始化顺序

 
我们大家都知道,对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序依次是(静态变量、静态初始化块)>(变量、初始化 块)>构造器。我们也可以通过下面的测试代码来验证这一点:
Java代码
  1. public class InitialOrderTest {  
  2.  
  3.     // 静态变量  
  4.     public static String staticField = " 静态变量";  
  5.     // 变量  
  6.     public String field = "变量";  
  7.  
  8.     // 静态初始化块  
  9.     static {  
  10.         System.out.println(staticField);  
  11.         System.out.println("静态初始化块");  
  12.     }  
  13.  
  14.     // 初始化块  
  15.     {  
  16.         System.out.println(field);  
  17.         System.out.println("初始 化块");  
  18.     }  
  19.  
  20.     // 构造器  
  21.     public InitialOrderTest() {  
  22.         System.out.println("构造 器");  
  23.     }  
  24.  
  25.     public static void main(String[] args) {  
  26.         new InitialOrderTest();  
  27.     }  

运行以上代码,我们会得到如下的输出结果:

  1. 静态变量
  2. 静态初始化块
  3. 变量
  4. 初始化块
  5. 构造器

这与上文中说的完全符合。那么对于继承情况下又会怎样呢?我们仍然以一段测试代码来获取最终结果:

Java代码 复制代码
  1. class Parent {  
  2.     // 静态变量  
  3.     public static String p_StaticField = "父类--静态变量";  
  4.     // 变量  
  5.     public String p_Field = "父类--变量";  
  6.  
  7.     // 静态初始化块  
  8.     static {  
  9.         System.out.println(p_StaticField);  
  10.         System.out.println("父类--静态初始化块");  
  11.     }  
  12.  
  13.     // 初始化块  
  14.     {  
  15.         System.out.println(p_Field);  
  16.         System.out.println("父类 --初始化块");  
  17.     }  
  18.  
  19.     // 构造器  
  20.     public Parent() {  
  21.         System.out.println("父类 --构造器");  
  22.     }  
  23. }  
  24.  
  25. public class SubClass extends Parent {  
  26.     // 静态变量  
  27.     public static String s_StaticField = "子类--静态变量";  
  28.     // 变量  
  29.     public String s_Field = "子类--变量";  
  30.     // 静态初始化块  
  31.     static {  
  32.         System.out.println(s_StaticField);  
  33.         System.out.println("子类--静态初始化块");  
  34.     }  
  35.     // 初始化块  
  36.     {  
  37.         System.out.println(s_Field);  
  38.         System.out.println("子类 --初始化块");  
  39.     }  
  40.  
  41.     // 构造器  
  42.     public SubClass() {  
  43.         System.out.println("子类 --构造器");  
  44.     }  
  45.  
  46.     // 程序入口  
  47.     public static void main(String[] args) {  
  48.         new SubClass();  
  49.     }  
  50. }  

运行一下上面的代码,结果马上呈现在我们的眼前:

  1. 父类--静态变量
  2. 父类--静态初始化块
  3. 子类--静态变量
  4. 子类--静态初始化块
  5. 父类--变量
  6. 父类--初始化块
  7. 父类--构造器
  8. 子类--变量
  9. 子类--初始化块
  10. 子类--构造器

现在,结果已经不言自明了。大家可能会注意到一点,那就是,并不是父类完全初始化完毕后才进行子类的初始化,实际上子类的静态变量和静态初始化块的初始化 是在父类的变量、初始化块和构造器初始化之前就完成了。

那么对于静态变量和静态初始化块之间、变量和初始化块之间的先后顺序又是怎样呢?是否静态变量总是先于静态初始化块,变量总是先于初始化块就被初始化了 呢?实际上这取决于它们在类中出现的先后顺序。我们以静态变量和静态初始化块为例来进行说明。

同样,我们还是写一个类来进行测试:

Java代码
  1. public class TestOrder {  
  2.     // 静态变量  
  3.     public static TestA a = new TestA();  
  4.       
  5.     // 静态初始化块  
  6.     static {  
  7.         System.out.println("静态 初始化块");  
  8.     }  
  9.       
  10.     // 静态变量  
  11.     public static TestB b = new TestB();  
  12.  
  13.     public static void main(String[] args) {  
  14.         new TestOrder();  
  15.     }  
  16. }  
  17.  
  18. class TestA {  
  19.     public TestA() {  
  20.         System.out.println("Test--A");  
  21.     }  
  22. }  
  23.  
  24. class TestB {  
  25.     public TestB() {  
  26.         System.out.println("Test--B");  
  27.     }  

运行上面的代码,会得到如下的结果:

  1. Test--A
  2. 静态初始化块
  3. Test--B

这也不要太纠结。
下面的写法会产生递归。
public class A
{
static{
a = new A("static block");
}
final static A a;
static A aa = new A("static init");
// A ma = new A("inner init");//这里在实例化变量时又实例自己的对象,递归
{
new A("inner block");//这里在实例化变量时又实例自己的对象,递归
}
public A()
{
// TODO Auto-generated constructor stub
}
public A(String i)
{
System.out.println(i);
}
public static void main(String[] args)
{

}
}

这里顺便温习一下构造函数的继承问题:

创建一个子类的对象实例的时候,必先调用父类的无参数的构造函数(默认构造函数),假如父类有带参数的构造函数,那么系统将不会给它创建无参数的构造函数,这时,子类在实例化的时候,因为找不到父类的默认构造函数,编译器将会报错,但如果在子类的构造函数中指定用父类的带参数的构造函数的时候,或者在父类中加一个无参数的构造函数,就不会报错。

Continue reading java 类初始化顺序

Extjs[ver<=3.1.0] enter键发送跨浏览器解决 等相关问题

聊天程序,enter键要发送同时清空编辑区:
Extjs textarea,
发现发送了后清空文本框后还是有个回车:
在chat里面的原因是截获事件后没有取消事件冒泡,导致先清空文本,最后残留的回车应该是事件冒泡产生的。
在ie里面设置event.keyCode = 8;[退格]即可
在火狐里面使用Ext包装的eventObject.preventDefault即可

==============================================
一下直接看源码可以分析出:
Ext panel要让它可拖动,可用draggable属性,但是如果没有设置panel的floating=true,则拖动后结束后还是会归原,可将 panel样式设置position:absolute即可.[这是wcsa里面出现的情况],另一种是没有header(没有设置title),
见下注释:

extDialog = new Ext.Panel({
style : 'z-index:' + (Ext.WindowMgr.zseed - 20),
width : 760,
height : 532,
layout : 'border',
tbar : _tbar,//toolbar作为伪header,没有设置header
floating : true,//
renderTo : Ext.getBody(),
x : x,
y : y,
items : [_rightpnl, chatpanel, southpnl]
});

extDialog.on('show', function() {//由于要取toolbar的el属性,故在render之后才可以
extDialog.dd = new Ext.Panel.DD(extDialog, {//draggleble是普通的配置文档上的copy
insertProxy : false,

onDrag : function(e) {
var pel = this.proxy.getEl();
this.x = pel.getLeft(true);
this.y = pel.getTop(true);
},

endDrag : function(e) {
this.panel.setPosition(this.x, this.y);
}
});
extDialog.body.setStyle('cursor', '');//由于没有header,将body的cursor设置为了move,所以还原
_tbar.el.setStyle('cursor', 'move');//设置toolbar的cursor为move
extDialog.dd.setHandleElId(_tbar.el.dom.id);//这个是必要的,chat里面遇到的问题是利民的textarea得不到焦点(鼠标点击没反应),就是因为默认DD没有header,将整个body设置成了handler
});

这个解决方案在ie6下有问题,整个Extjs层无法点击,最后还是改用window来做就没问题。

=======================
chat里面遇到,右侧要写html dialog,发现火狐下再展开原来collapse的panel会导致原来写好的iframe 里面的html是空的,跟踪dom发现这个收缩的panel整个被remove了,再展开时extjs试图还原,对一般的这个没问题,对
嵌入iframe则有问题,查看源码估计是展开收缩动画造成的原因,将Panel animCollapse的设置为false就可以了.

floatable:false,则可以让折叠的panel必须要点按钮才可以展开[borderlayout.region]

extjs3.1.0之前

Continue reading Extjs[ver<=3.1.0] enter键发送跨浏览器解决 等相关问题

净现值、折现率、内部收益率、投资利润

NPV:净现值 (Net Present Value )

      投资项目投入使用后的净现金流量,按资本成本或企业要求达到的报酬率折算为现值,减去初始投资以后的余额,叫净现值(net present value,NPV)。(净现值 = 未来报酬的 总现值初始投资)     

 

      未来报酬的总现值计算 方法:

            1、计算每年的营业净现金流量。

       2、计算未来报酬的总现值。

             (1)将每年的营业净现金流量折算成现值。

                          如果每年的NCF相等,则按年金法折成现值;

                          如果每年的NCF不相等,则先对每年的NCF进行折现,然后加以合计。

             (2)将终结现金流量折算成现值。

             (3)计算未来报酬的总现值。

 

      也就是说净现值大于零则方案可行,且净现值越大,方案越优,投资效益越好。

      简单的例子说明:  说白了就是未来可以净赚多少钱。初始投资10块,预计将来赚 12块,则2块就是净现值。

      现值 就是资金当前的价值,也就是说现在手上的这些钱他值多少钱。

      如果存到银行的话,净现值就是利息,现值就是本金+利息。

 

净现值=未来报酬总现值-建设投资总额

NPV=\sum^{n}_{t=1}\frac{C_t}{(1+r)^t}-C_0

式中:NPV—净现值

Co—初始投资额

Ct —t年现金流量

r—贴现率

n—投资项目的寿命周期

如果将初始投资额看做第0年的现金流量,同时考虑到(1 + r)o = 1,则上式可以变换为:

NPV=\sum^{n}_{t=0}\frac{C_t}{(1+r)^t}

净现值指标的决策标准是:如果投资项目的净现值大于零,接受该项目;如果投资项目的净现值小于零,放弃该项目;如果有多个互斥的投资项 目相互竞争,选取净现值最大的投资项目。

项目A、B的净现值均大于零,表明这两个项目均可取。如果二者只能取一个,则应选取项目A。

如果投资项目除初始投资额外各期现金流量均相等,则可利用年金现值系数表计算,使计算过程简化.

净现值指标考虑了投资项目资金流量的时间价值,较合理地反映了投资项目的真正的经济价值,是一个比较好的投资决策指标。

DR : 折现率[考试中往往由下面的折现系数求得,一般折现率由银行决定]

        折现率是指将未来有限期预期收益折算成现 值的比率。可以这样简单的理解:由于资金是有时间价值的,今天的一块钱和一年后的块钱在价值是是不能等同的。如何把一年后的一块钱和今 天的一块钱在价值上进行比较呢,那就要把一年后的一块钱折成今天的价值,这叫折现。公式是:PV = C/(1+r)^t   其中:PV = 现值(present value),C=期末金额,r=折现率,t=投资期数。

        举例:
        一年后一块钱在今天的价值=一年后的一块钱/(1+折现率) 
        二年后一块 钱在今天的价值=二年后的一块钱/(1+折现率)^2(注:平方) 
        三年后一块钱在今天的价值=三年后的一块钱/(1+折现 率)^3(注:立方)
依次类推。 在进行折现 时,折现率一般采用当前的市场利率,如同样期限的贷款利率等;或用资金的实际成本作为折现率。

        再举例来说,您的投资机会是把钱存银行,存款利率为10%,那么一年以后收到的1元,对您来说其现值为0.909(=1/1.1);而两年后的1元对您来 说其现值为0.826(=1/1.1^2)。也就是说,现在给您0.909元和1年后给您1元,您认为是相同的,因为您可以把0.909元存入银行,1年 后获得1元;同理,现在给您0.826元,和2年后给您1元并没有什么不同。 
 

折现系数

【折现系数】
又称一次偿付现值因素或复利现值系数,英文为discount factor,指根据折现率和年数计算出来的一个货币单位在不同时间的现值。在折现率不变的情况下,一个货币单位在n年的折现系数为:
R=1/(1+i)n   (注:此处n为(1+i)的上标)
式中:
R——折现系数;
i——折现率;
n——年数。

IRR : 内部收益率

        简单的说就是:NPV=0的时候的DR,一般我们比较的是行业的IRR。意思就是刚收回成本的时候的折 现率。说得通俗点,内部收益率越高,说明你投入的成本相对地少,但获得的收益却相对地多。

        比如A、 B两项投资,成本都是10万,经营期都是5年,A每年可获净现金流量3万,B可获4万,通过计算,可以得出A的内部收益率约等于15%,B的约等于 28%,这些,其实通过年金现值系数表就可以看得出来的。

 

ROI: 投资利润

      年投资利润率=年净利润/投资总额 *100%

      1、第一年投资利润率:
      第一年投资利润=1100-220-270-160=450
      第一年投资利润率=450/200*100%=225%

      2、第二年投资利润率:
      第二年投资利润=2450-530-650-300=970
      第二年投资利润率=970/200*100%=485%

      3、第三年投资利润率:
      第三年投资利润=5500-900-975-400=3225
      第三年投资利润率=3225/200*100%=1612.5%

Continue reading 净现值、折现率、内部收益率、投资利润

【转】笑着学习笔记iBatis入门

根据官网上的开发指南,按照个人使用习惯,频度等整理的,没啥特别的东西。

笑着--胖胖兰学iBatis

一,       iBatis简介

iBatis是一种数据库持续层的ORM框架。使用简单的XML配置文件将Java Bean映射成PreparedStatement的输入参数和ResultSet结果集

 

在不是很复杂的情况下,我们 甚至可以使用HashMap而不是Java Bean来映射PreparedStatement的输入参 数和ResultSet结果集,从而节省开发时间与成本。 或者,我们可以使用一些辅助工具来帮助我们通过XML配置生成对应的Java Bean.

 

 

 

 

 

 

 

 

 

二,       iBatis工作原理,流程

iBatis使用简单的XML描述文件将Java BeanMap实现和基本数据类型的包装类(StringInteger等)映射成JDBCPreparedStatement的输入参数 和ResultSet结果集。具体工作流程如下:

 

1.在sqlMapConfigXML配置文件中进行数据库连接的配 置,XML配置文件名称任意,比如sql-map-config.xml

2sqlMapConfigXML配置文件中引用sqlMapXML配置文件

<sqlMap resource="examples/sqlmap/maps/Person1.xml" />

<sqlMap url="file:///c:/config/Customer.xml " />

3.在sqlMapXML配置文件中进行SQL文的配置,文件名称任意, 比如Person1.xml

4.通过SqlMapClientBuilder生成具体的操作sqlMap配置文件中SQL文的 IBATIS对象SqlMapClient

String resource = "config/ibatis/sql-map-config.xml";                  

Reader reader = Resources.getResourceAsReader (resource);                      

SqlMapClient sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);

5SqlMapClient对象提供函数,函数的参数 对应替换sqlMap配置文件中的id,parameter等等属性,完成SQL文的执 行。具体参照iBatisAPI

public List queryForList(String statementName, Object parameterObject,

int skipResults, int maxResults)

statement:sqlMap配置中id属性,parameterObject:sqlMap配置中parameterXXX属性

 

 

iBatis的工作重点在于配置文件的 做成上,尤其sqlMap配置文件的做成是我们需要重点学习的。

 

 

 

 

 

 

 

 

三,       SqlMapConfig.xml

配置例子如下,各个标签的说 明参考官方文档。比较容易理解,这里不做整理

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE sqlMapConfig

PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"

"http://www.ibatis.com/dtd/sql-map-config-2.dtd">

<sqlMapConfig>

<properties resource=" examples/sqlmap/maps/SqlMapConfigExample.properties " />

<settings

cacheModelsEnabled="true"

enhancementEnabled="true"

lazyLoadingEnabled="true"

maxRequests="32"

maxSessions="10"

maxTransactions="5"

useStatementNamespaces="false"

/>

<typeAlias alias="order" type="testdomain.Order"/>

<transactionManager type="JDBC" >

<dataSource type="SIMPLE">

<property name="JDBC.Driver" value="${driver}"/>

<property name="JDBC.ConnectionURL" value="${url}"/>

<property name="JDBC.Username" value="${username}"/>

<property name="JDBC.Password" value="${password}"/>

<property name="JDBC.DefaultAutoCommit" value="true" />

<property name="Pool.MaximumActiveConnections" value="10"/><property name="Pool.MaximumIdleConnections" value="5"/>

<property name="Pool.MaximumCheckoutTime" value="120000"/>

<property name="Pool.TimeToWait" value="500"/>

<property name="Pool.PingQuery" value="select 1 from ACCOUNT"/>

<property name="Pool.PingEnabled" value="false"/>

<property name="Pool.PingConnectionsOlderThan" value="1"/>

<property name="Pool.PingConnectionsNotUsedFor" value="1"/>

</dataSource>

</transactionManager>

<sqlMap resource="examples/sqlmap/maps/Person.xml" />

<sqlMap url="file:///c:/config/Customer.xml " />

</sqlMapConfig>

 

以上,主要注意DB连接情报的配置方法,采用 了Java的标准Properties文件。

<properties resource=" examples/sqlmap/maps/SqlMapConfigExample.properties " />

       然后在XML中引用properties文 件中的定义。

           <property name="JDBC.Driver" value="${driver}"/>

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

四,       SqlMap.xml总体印象

较复杂的例子:

<sqlMap id=”Product”>

<cacheModel id=”productCache” type=”LRU”>

<flushInterval hours=”24”/>

<property name=”size” value=”1000” />

</cacheModel>

<typeAlias alias=”product” type=”com.ibatis.example.Product” />

<parameterMap id=”productParam” class=”product”>

<parameter property=”id”/>

</parameterMap>

<resultMap id=”productResult” class=”product”>

<result property=”id” column=”PRD_ID”/>

<result property=”description” column=”PRD_DESCRIPTION”/>

</resultMap>

<select id=”getProduct” parameterMap=”productParam”

resultMap=”productResult” cacheModel=”product-cache”>

select * from PRODUCT where PRD_ID = ?

</select>

</sqlMap>

 

      以上例子简化版:

<sqlMap id=”Product”>

<select id=”getProduct” parameterClass=” com.ibatis.example.Product”

resultClass=”com.ibatis.example.Product”>

Select

PRD_ID as id,

PRD_DESCRIPTION as description

From PRODUCT

Where PRD_ID = #id#

</select>

</sqlMap>

 

五,       Statement语法,类型,及其属性和特点

1.语法

<statement

 id=”statementName”

[parameterClass=”some.class.Name”]

[resultClass=”some.class.Name”]

[parameterMap=”nameOfParameterMap”]

[resultMap=”nameOfResultMap”]

[cacheModel=”nameOfCache”]

>

select * from PRODUCT where PRD_ID = [?|#propertyName#] order by [$simpleDynamic$]

</statement>

 

[]内 为可选项,不是必须存在的。

 

2.Statement类型,属性,特点

六,       关于映射时输入值的匹配问题

1.     SqlMapClient如何从SqlMap的配置文件中找到对应的SQL

通过类函数的参数statementName与配置文件中statement配置的id相匹配

 

2.     bean中的数据如何映射给SQL文中对应的输入参数

a.     通过参数变量名称与bean中对应属性名称相匹配

<statement id=”statementName” parameterClass=” examples.domain.Product”>

insert into PRODUCT values (#id#, #description#, #price#)

</statement>

 

b.     通过参数变量的出现顺序相 匹配

<parameterMap id=”insert-product-param” class=”com.domain.Product”>

<parameter property=”id”/>

<parameter property=”description”/>

</parameterMap>

<statement id=”insertProduct” parameterMap=”insert-product-param”>

insert into PRODUCT (PRD_ID, PRD_DESCRIPTION) values (?,?);

</statement>

 

3.     map中的数据如何映射给SQL文中对应的输入参数

a.     通过参数变量名称与map中对应key相匹配

<statement id=”statementName” parameterClass=” java.util.Map”>

insert into PRODUCT values (#id#, #description#, #price#)

</statement>

 

HashMap hm = new HashMap();

hm.put(“id”,”value”);

hm.put(“description”,”value”);

hm.put(“price”,”value”);

sqlMapClient.queryForList(“statementName”, hm,…………);

 

 

 

4.     基本数据类型的数据如何映 射给SQL文中对应的输入参数

基本数据类型与参数11,没啥匹配的问题。不过官 方的开发指南中强调参数要写成#value#这种写法,原因不明。

<statement id=”insertProduct” parameter=”java.lang.Integer”>

select * from PRODUCT where PRD_ID = #value#

</statement>

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

七,       关于映射时返回值的匹配问题

1.     查询结果如何映射给bean中的对应属性

a.     通过查询结果的字段名称与bean中对应属性名称相匹配

<statement id=”getProduct” resultClass=”com.ibatis.example.Product”>

select

PRD_ID as id,

PRD_DESCRIPTION as description

from PRODUCT

where PRD_ID = #value#

</statement>

 

官 方的开发指南中说这种写法叫做隐式ResultMap

 

b.     指定查询结果的字段名称与bean中对应属性名称的映射关系

<resultMap id=”get-product-result” class=”com.ibatis.example.Product”>

<result property=”id” column=”PRD_ID”/>

<result property=”description” column=”PRD_DESCRIPTION”/>

<result property=”subCode” column=”PRD_SUB_CODE” nullValue=”-999”/>

</resultMap>

 

以上,数据类型通过反射与对 应的属性类型自动匹配,极少数时候可能需要通过resultMapjavaType属性进行设定,参考后面关于Result Map外部形式中各个参数的说明

 

2.     查询结果如何设定给Map

a.     通过查询结果的字段名称与map中对应key相匹配

<resultMap id=”get-product-result” class=”java.util.HashMap”>

<result property=”id” column=”PRD_ID”/>

<result property=”code” column=”PRD_CODE”/>

<result property=”description” column=”PRD_DESCRIPTION”/>

<result property=”suggestedPrice” column=”PRD_SUGGESTED_PRICE”/>

</resultMap>

 

<statement id=”getProductCount” resultClass=”java.util.HashMap”>

select * from PRODUCT

</statement>

 

b.     指定查询结果的字段名称与bean中对应属性名称的映射关系

bean基本相同,参考使用bean作为返回结果的写法

 

3.     查询结果如何映射给基本数 据类型

只能指定一个返回值,名字可 以随便,一般采用value,val

<resultMap id=”get-product-result” class=”java.lang.String”>

<result property=”value” column=”PRD_DESCRIPTION”/>

</resultMap>

 

或 者

<statement id=”getProductCount” resultClass=”java.lang.Integer”>

select count(1) as value

from PRODUCT

</statement>

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

八,       关于Parameter Map外部形式中各个参数的说明

<parameterMap id=”parameterMapName” [class=”com.domain.Product”]>

<parameter

property =”propertyName”

[jdbcType=”VARCHAR”]

[javaType=”string”]

[nullValue=”NUMERIC”]

[null=”-9999999”]/>

<parameter …… />

<parameter …… />

</parameterMap>

1.JdbcType

属 性jdbcType用于显式地指定给本属性(property) 赋值的数据库字段的数据类型。对于某些特定的操作,如果不指定字段的数据类型,某些JDBC Driver无 法识别字段的数据类型。

 

正 常情况下,只有当字段可以为NULL时才需要jdbcType属 性。另一需要指定jdbcType属性的情况是字段类型为日期时间类型的情况。因为Java只 有一个Date类型(java.util.Date), 而大多数SQL数据库有多个-通常至少有3种。因此,需要指定字段类型是DATE还是DATETIME。

 

注意!当使用Oracle Driver时,如果没有给可以为NULL的字段指定jdbcType属性,当试图给这些字段赋 值NULL时,会出现“Invalid column type”错误。

 

2.javaType

属 性javaType用于显式地指定被赋值参数Java属 性的类名。正常情况下,这可以通过反射从Java Bean的 属性获得

 

3.nullValue, null

   用 于指定NULL的替换值。就是说,当Java Bean的属性值等于指定值时,相应的字段将赋值NULL。 这个特性允许在应用中给不支持null的数据类型(即intdoublefloat等) 赋值null。当这些数据类型的属性值匹配null值 (即匹配-9999)时,NULL将 代替null值写入数据库。

      一个完整的例子

<parameterMap id=”insert-product-param” class=”com.domain.Product”>

<parameter

property=”id”

jdbcType=”NUMERIC”

javaType=”int”

nullValue=”-9999999”/>

<parameter

property=”description”

jdbcType=”VARCHAR”

nullValue=”NO_ENTRY”/>

</parameterMap>

 

<statement id=”insertProduct” parameterMap=”insert-product-param”>

insert into PRODUCT (PRD_ID, PRD_DESCRIPTION) values (?,?);

</statement>

 

      简化写法

<statement id=”insertProduct” parameterClass=”com.domain.Product”>

insert into PRODUCT (PRD_ID, PRD_DESCRIPTION)

values (#id:NUMERIC#, #description:VARCHAR#);

</statement>

 

或者:

 

<statement id=”insertProduct” parameterClass=”com.domain.Product”>

insert into PRODUCT (PRD_ID, PRD_DESCRIPTION)

values (#id:NUMERIC:-999999#, #description:VARCHAR:NO_ENTRY#);

</statement>

 

 

 

 

九,       Result Map外部形式中各个参数的说明

<resultMap id=”resultMapName” class=”some.domain.Class” [extends=”parent-resultMap”]>

<result property=”propertyName” column=”COLUMN_NAME”

[columnIndex=”1”]

[javaType=”int”]

[jdbcType=”NUMERIC”]

[nullValue=”-999999”]

[select=”someOtherStatement”]

/>

<result ……/>

<result ……/>

<result ……/>

</resultMap>

1. columnIndex

属性columnIndex是可选的,用于改善性能。 属性columnIndex的值是ResultSet中用于赋值Java Bean属性的字段次序号。在99%的应用中,不太可能需要牺牲可读性来换取性能。使用columnIndex,某些JDBC Driver可以大幅提高性能,某些则没有任何效果。

 

2.javaType

属性javaType用于显式地指定被赋值的Java Bean属性的类型。正常情况下,这可以通过反射从Java Bean的属性获得,但对于某些映射 (例如MapXML document),框架不能通过这种方法来 获知。如果没有设置javaType, 同时框架也不能获知类型信息,类型将被假定为Object

 

3.jdbcType,nullValue, null

   Parameter Map

4.select

属 性select用于描述对象之间的关系,并自动地装入复杂类型(即用户定义的类型)属性的数 据。属性select的值必须是另外一个mapped statement元素的名称。在同一个result元 素中定义的数据库字段(column属性)以及property属 性,将被传给相关的mapped statement作为参数。因此,字段的数据类型必须是SQL Map支持的简单数据类型。关于简单数据类型和复杂类型之间映射/关 系的信息,参照后面章节更详细的讨论。

 

具 体参考稍后关于复杂类型属性的例子

十,       复杂类型属性说明

1.关于复杂类型属性的例子

<resultMap id=”get-product-result” class=”com.ibatis.example.Product”>

<result property=”id” column=”PRD_ID”/>

<result property=”description” column=”PRD_DESCRIPTION”/>

<result property=”category” column=”PRD_CAT_IDselect=”getCategory”/>

</resultMap>

<resultMap id=”get-category-result” class=”com.ibatis.example.Category”>

<result property=”id” column=”CAT_ID”/>

<result property=”description” column=”CAT_DESCRIPTION”/>

</resultMap>

<statement id=”getProduct” parameterClass=”int” resultMap=”get-product-result”>

select * from PRODUCT where PRD_ID = #value#

</statement>

<statement id=”getCategory” parameterClass=”int” resultMap=”get-category-result”>

select * from CATEGORY where CAT_ID = #value#

</statement>

 

         避 免N1 Select1:1  

<resultMap id=”get-product-result” class=”com.ibatis.example.Product”>

<result property=”id” column=”PRD_ID”/>

<result property=”description” column=”PRD_DESCRIPTION”/>

<result property=”category.id” column=”CAT_ID” />

<result property=”category.description” column=”CAT_DESCRIPTION” />

</resultMap>

<statement id=”getProduct” parameterClass=”int” resultMap=”get-product-result”>

select *

from PRODUCT, CATEGORY

where PRD_CAT_ID=CAT_ID

and PRD_ID = #value#

</statement>

 

 

2.关于复杂类型级和属性的例子

<resultMap id=”get-category-result” class=”com.ibatis.example.Category”>

<result property=”id” column=”CAT_ID”/>

<result property=”description” column=”CAT_DESCRIPTION”/>

<result property=”productList” column=”CAT_ID” select=” getProductsByCatId”/>

</resultMap>

<resultMap id=”get-product-result” class=”com.ibatis.example.Product”>

<result property=”id” column=”PRD_ID”/>

<result property=”description” column=”PRD_DESCRIPTION”/>

</resultMap>

<statement id=”getCategory” parameterClass=”int” resultMap=”get-category-result”>

select * from CATEGORY where CAT_ID = #value#

</statement>

<statement id=”getProductsByCatId” parameterClass=”int” resultMap=”get-product-result”>

select * from PRODUCT where PRD_CAT_ID = #value#

</statement>

 

         避 免N1 Select1:1  

暂 时无解,在新版本中可能会对应

 

3.组合键值或多个复杂参数属性

<resultMap id=”get-order-result” class=”com.ibatis.example.Order”>

<result property=”id” column=”ORD_ID”/>

<result property=”customerId” column=”ORD_CST_ID”/>

<result property=”payments” column=”{itemId=ORD_ID, custId=ORD_CST_ID}

select=” getOrderPayments”/>

</resultMap>

<statement id=”getOrderPayments” resultMap=”get-payment-result”>

select * from PAYMENT

where PAY_ORD_ID = #itemId#

and PAY_CST_ID = #custId#

</statement>

十一,   在查询statement中指定cacheModel属性

<cacheModel id="product-cache" type ="LRU" readOnly=”true” serialize=”false”>

<flushInterval hours="24"/>

<flushOnExecute statement="insertProduct"/>

<flushOnExecute statement="updateProduct"/>

<flushOnExecute statement="deleteProduct"/>

<property name=”cache-size” value=”1000” />

</cacheModel>

 

<statement id=”getProductList” cacheModel=”product-cache”>

select * from PRODUCT where PRD_CAT_ID = #value#

</statement>

 

1Serializable可读写缓存

正 如您所知道的,只对当前Session有效的缓存对整体应用性能的提高作用有限。Serializable可读写缓存可以提高整体应用(而不仅仅是每个Session)的性能。这种缓存为每一个Session返回缓存对象不同的实例(复本)。因此每一个Session都可以安全修改返回的对象。不同之处在于,通常您希望从缓存中得到同一个对象,但这种情况下得到的是不同的对象。还有,每一个 缓冲在Serializable缓 存的对象都必须是Serializable的。 这意味着不能同时使用Serializable缓存和延迟加载,因为延迟加载代理不是Serializable的。想知道如何把Serializable缓存,延迟加载和联合查询结合起来使用,最好的方法是尝试。要使用Serializable缓 存,设置readOnly=falseserialize=true。缺省情况下,缓存是只读模式,不使用Serializable缓存。只读缓存不需要Serializable

 

 

 

 

 

 

 

 

 

2Type

    a.type=MEMORY

MEMORY cache实现只认识一个<property>元素。这个名为reference-type属性的值必须是STRONGSOFTWEAK三者其一。这三个值分别对应于JVM不同的内存reference类型。

<property name=”reference-type” value=”WEAK” />

 

 

    b.type=LRU

LRU Cache实现用近期最少使用原则来确定如何从Cache中清除对象。

       <property name=”cache-size” value=”1000” />

 

    c.type=FIFO

       FIFO Cache实 现用先进先出原则来确定如何从Cache中清除对象。

<property name=”size” value=”1000” />

 

d.type= OSCACHE  没 用过,没研究过。这个不太懂,哈

OSCACHE Cache实现是OSCache2.0缓存引擎的一个Plugin。它具有高度的可配置性,分布式,高度的灵活性。

 

OSCACHE实现不使用property元素,而是在类路径的根路径中使用标准的oscache.properties文件进行配置。在oscache.properties文件中,您可以配置Cache的算法(和上面讨论的算法很类似),Cache的大小,持久化方法(内存,文件等)和集群方法。

要获得更详细的信息,请参考OSCache文档。OSCache及其文档可以从OpenSymphony网站上获取:

http://www.opensymphony.com/oscache/

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

十二,   动态Mapped Statement

<select id="dynamicGetAccountList"

cacheModel="account-cache"

resultMap="account-result"

>

select * from ACCOUNT

<isGreaterThan prepend="and" property="id" compareValue="0">

where ACC_ID = #id#

</isGreaterThan>

order by ACC_LAST_NAME

</select>

上 面的例子中,根据参数beanid属性的不同情况,可创建两个可能的语句。如果参数id大于0,将创建下面的语句:

select * from ACCOUNT where ACC_ID = ?

或 者,如果id参数小于等于0,将创建下面的语句:

select * from ACCOUNT

 

1.二元条件元素

二 元条件元素将一个属性值和一个静态值或另一个属性值比较,如果条件为,元素体的内容将被包括在查询SQL语句中。

 

二元条件元素的属性:

prepend - 可被覆盖的SQL语句组成部分,添加在语句的前面(可选)

property - 被比较的属性(必选)

compareProperty - 另一个用于和前者比较的属性(必选或选择compareValue

compareValue - 用于比较的值(必选或选择compareProperty

<isEqual>

比较属性值和静态值或另一个属性值是否相等。

<isNotEqual>

比较属性值和静态值或另一个属性值是否不相等。

<isGreaterThan>

比较属性值是否大于静态值或另一个属性值。

<isGreaterEqual>

比较属性值是否大于等于静态值或另一个属性值。

<isLessThan>

比较属性值是否小于静态值或另一个属性值。

<isLessEqual>

比较属性值是否小于等于静态值或另一个属性值。

例子:

<isLessEqual prepend=”AND” property=”age” compareValue=”18”>

ADOLESCENT = ‘TRUE’

</isLessEqual>

 

2.一元条件元素

一 元条件元素检查属性的状态是否符合特定的条件。

一元条件元素的属性:

prepend - 可被覆盖的SQL语句组成部分,添加在语句 的前面(可选)

property - 被比较的属性(必选)

<isPropertyAvailable>

检查是否存在该属性(存在parameter bean的属性)。

<isNotPropertyAvailable>

检查是否不存在该属性(不存在parameter bean的属性)。

<isNull>

检查属性是否为null

<isNotNull>

检查属性是否不为null

<isEmpty>

检查Collection.size()的值,属性的StringString.valueOf(),是否为null或空(“”size() < 1)。

<isNotEmpty>

检查Collection.size()的值,属性的StringString.valueOf(),是否不为null或 不为空(“”size() > 0)。

例子:

<isNotEmpty prepend=”AND” property=”firstName” >

FIRST_NAME=#firstName#

</isNotEmpty>

 

3其他元素

Parameter Present:这些元素检查参数对象 是否存在。

Parameter Present的属性:

prepend - 可被覆盖的SQL语句组成部分,添加在语 句的前面(可选)

<isParameterPresent>

检 查是否存在参数对象(不为null)。

<isNotParameterPresent>

检 查是否不存在参数对象(参数对象为null)。

例子:

<isNotParameterPresent prepend=”AND”>

EMPLOYEE_TYPE = ‘DEFAULT’

</isNotParameterPresent>

 

4Iterate:这属性遍历整个集合,并为List集 合中的元素重复元素体的内容。

Iterate的属性:

prepend - 可被覆盖的SQL语句组成部分,添加在语句的前面(可选)

property - 类型为java.util.List的用于遍历的元素(必选)

open - 整个遍历内容体开始的字符串,用于定义括号(可选)

close -整个遍历内容体结束的字符串,用于定义括号(可选)

conjunction - 每次遍历内容之间的字符串,用于定义ANDOR(可选)

<iterate>

遍历类型为java.util.List的元素。

例子:

<iterate prepend=”AND” property=”userNameList”

open=”(” close=”)” conjunction=”OR”>

username=#userNameList[]#

</iterate>

注意:使用<iterate>时,在List元素名后面包括方括号[]非常重要,方括号[]将对象标记为List,以防解析器简单地将List输出成String

 

一,       注 意事项

1.关于特殊字符

因为SQL语句是嵌在XML文档中的, 因此有些特殊的字符不能直接使用,例如大于号和小于号(<>)。幸运的 是,解决的办法很简单,只需将包含特殊字符的SQL语句放在XMLCDATA区里面就可 以了。例 如:


<statement id="getPersonsByAge" parameterClass=”int” resultClass="examples.domain.Person">

<![CDATA[

SELECT *

FROM PERSON

WHERE AGE > #value#

]]>

</statement>

 

 

 

2.关于多个SqlMap.xml 中id冲突问题

问题描述:

sql-map-config中引用多个sqlmap.xml,多个sqlmap.xml中存在相同的statementname的时候,ibatis如何判断当前我准备使用哪 一个sqlmap.xml中的statementname对应的sql语句

      

       解决方法:

SqlMapConfig.xml中的settings标签中存在一个属性useStatementNamespaces当这个设定 为true的时候,那 么iBatis通过SqlMap.xmlnamespace.id来查找对应 的sqlid,从而避免 这个问题。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

二,       其他

1.自动生成的主健

<insert id="insertProduct-ORACLE" parameterClass="com.domain.Product">

<selectKey resultClass="int" keyProperty="id" >

SELECT STOCKIDSEQUENCE.NEXTVAL AS ID FROM DUAL

</selectKey>

insert into PRODUCT (PRD_ID,PRD_DESCRIPTION)

values (#id#,#description#)

</insert>

 

<!— Microsoft SQL Server IDENTITY Column Example -->

<insert id="insertProduct-MS-SQL" parameterClass="com.domain.Product">

insert into PRODUCT (PRD_DESCRIPTION)

values (#description#)

<selectKey resultClass="int" keyProperty="id" >

SELECT @@IDENTITY AS ID

</selectKey>

</insert>

 

2.调用存储过程

<parameterMap id="swapParameters" class="map" >

<parameter property="email1" jdbcType="VARCHAR" javaType="java.lang.String" mode="INOUT"/>

<parameter property="email2" jdbcType="VARCHAR" javaType="java.lang.String" mode="INOUT"/>

</parameterMap>

<procedure id="swapEmailAddresses" parameterMap="swapParameters" >

{call swap_email_address (?, ?)}

</procedure> SELECT @@IDENTITY AS ID

 

十五,   Sample

1.java类,生成iBatis数据库操作对象

public class MyAppSqlConfig {

private static final SqlMapClient sqlMap;

static {

try {

String resource = “com/ibatis/example/sql-map-config.xml”;

Reader reader = Resources.getResourceAsReader (resource);

sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);

} catch (Exception e) {

e.printStackTrace();

throw new RuntimeException (“”);

}

}

public static getSqlMapInstance () {

return sqlMap;

}

}

 

2.配置文件:

Continue reading 【转】笑着学习笔记iBatis入门

【转】Instruction about how to load “.csv” file into MySQL

1.       Change the configuration file of MySQL. (MySQL can’t identify some incorrect strings of the .csv file we want to load, so that we have to change the setting of MySQL)


l         Open your "my.ini" file within the MySQL installation directory, and look for the text "sql-mode". Find:


l         Add the following code to “my.ini” file



2.       Download the .csv files and unzip it:


File NameDownload Link
1. GeoIPCountryCSV.zip (It contains one database file)http://www.maxmind.com/app/geoip_country
2. GeoLiteCity_20100601.zip (It contains two database files)http://www.maxmind.com/app/geolitecity



Note: Actually, there is one database named GeoLiteRegion, which doesn’t have free version right now. So we didn’t choose to use it.




3.       Use MySQL Workbench to load the unzipped .csv files to database


l         According to the number of columns of the .csv file, we need to create the corresponding table and give a name to each column.

l         After the table has been established, we can use the following command to automatically load the data :


If you guys are still confusing about the code above, you check the following websites out:

http://forums.mysql.com/read.php?79,219901,219901
http://www.tech-recipes.com/rx/2345/import_csv_file_directly_into_mysql/

建议使用dat文件读取。

Continue reading 【转】Instruction about how to load “.csv” file into MySQL

extjs grid使用总结

版本:3.2.1,主要使用在BannerAdmin上:

1:使用store要注意:
一般使用record.beginEdit, set,endEdit,---(update event)-->commit/reject的步骤来更新/还原数据,直接修改record的data的值不会触发update等事件,估计这样的话reject也不会起作用。
2:EditGrid的默认selmode是CellSelectModel.CheckColumn是在ux包里面的。发现直接修改CheckColumn绑定的record.data后,会反映在CheckColumn上。
3:EditGrid要支持拖拽的话,还要改代码:[见cm.js]
Ext.override(Ext.grid.GridPanel, {
               getDragDropText : function() {
                   var sm = this.selModel;

                   var count;
                   if (sm instanceof Ext.grid.CellSelectionModel) {
                       count = 1;
                   } else {
                       count = sm.getCount();
                   }
                   return String.format(this.ddText, count, count == 1
                                   ? ''
                                   : 's');
               }
           });
   Ext.override(Ext.grid.GridDragZone, {
               getDragData : function(e) {
                   var t = Ext.lib.Event.getTarget(e);
                   var rowIndex = this.view.findRowIndex(t);
                   var cellIndex = this.view.findCellIndex(t);

                   if (rowIndex !== false) {
                       var sm = this.grid.selModel;

                       // RowSelectionModel
                       if (sm instanceof Ext.grid.RowSelectionModel) {
                           if (!sm.isSelected(rowIndex) || e.hasModifier()) {
                               sm.handleMouseDown(this.grid, rowIndex, e);
                           }
                           return {
                               grid : this.grid,
                               ddel : this.ddel,
                               rowIndex : rowIndex,
                               selections : sm.getSelections()
                           };
                       }

                       // CellSelectionModel
                       if (sm instanceof Ext.grid.CellSelectionModel) {
                           sel = sm.getSelectedCell();

                           rowAlreadySelected = sel && sel[0] == rowIndex;

                           if (!rowAlreadySelected || e.hasModifier()) {
                               sm.handleMouseDown(this.grid, rowIndex,
                                       cellIndex, e);
                           }

                           store = this.grid.getStore();
                           sel = sm.getSelectedCell();
                           if (sel)
                               return {
                                   grid : this.grid,
                                   ddel : this.ddel,
                                   rowIndex : rowIndex,
                                   selections : [store.getAt(sel[0])]
                               };
                           else
                               return {
                                   grid : this.grid,
                                   ddel : this.ddel,
                                   rowIndex : rowIndex,
                                   selections : []
                               };
                       }
                   }
                   return false;

               }
           });

Continue reading extjs grid使用总结

Pagination


Total views.

© 2013 - 2024. All rights reserved.

Powered by Hydejack v6.6.1