??xml version="1.0" encoding="utf-8" standalone="yes"?> ?/p>
在线演示地址Q?http://www.balsamiq.com/products/mockups 试用|址Q?http://www.balsamiq.com/demos/mockups/Mockups.html 整体截图Q?/p>
功能和亮点:(x) To get a free license key, you can do one of the following:
q里不想讨论JDO和JPA的区别,也不讨论JDO的规范,单只是从JDO的用和与应用的集成角度来概q?br />
1. 下蝲JDO规范的实现开源包。目前主的JDO实现有:(x)
*.TJDO http://tjdo.sf.net
*.Speedo http://speedo.objectweb.org
*.JORM http://jorm.objectweb.org
*.XORM http://xorm.sourceforge.net
*.JPOX http://jpox.sourceforge.net
*.OJB http://db.apache.org/ojb/
*.DataNucleus http://www.datanucleus.org/
2. q里选择DataNucleus为JDO的实玎ͼ因ؓ(f)个h认ؓ(f)datanucleus大有一lO/R Mapping天下的架ѝ前端支持JDO/JPA规范Q后面能接多U数据存储^?RDBMS, ODBMS, Map-based, Web-based, documents, etc) . q且直接可与bigtable、hbase{分布式数据库集成。实在强大?br />
* 下蝲DataNucleusE序?br />
* 下蝲DataNucleus在eclipse下的扩展插g
3. 如果使用dataNucleusq接DBMS数据?Mysql)需要加入以下几个jar包:(x)
datanucleus-enhancer-3.0.0-m4.jar jdo-api-3.1-SNAPSHOT-20110319.jar datanucleus-api-jdo-3.0.0-m4.jar datanucleus-jdo-query-3.0.0-m2.jar asm.jar
mysql-connector-java-5.0.4-bin.jar datanucleus-cache-3.0.0-m2.jar datanucleus-management-1.0.2.jar datanucleus-core-3.0.0-m4.jar datanucleus-rdbms-3.0.0-m4.jar
4. 创徏一个entity class q|映文?如下Q?br />
entity class :
@PersistenceCapable
public class Person {
@PrimaryKey
private String name ;
private int age ;
private String mail ;
.......
}
mapping xml
<jdo>
<package name="com.jdo.data.nucleus.model">
<class name="Person">
<field name="name" persistence-modifier="persistent">
<column length="100" />
</field>
<field name="age" persistence-modifier="persistent"/>
<field name="mail" persistence-modifier="persistent"/>
</class>
</package>
</jdo>
5.创徏JDO操作c:(x)
Map<String,String> JDOConfig = new HashMap<String,String>();
JDOConfig.put( "javax.jdo.PersistenceManagerFactoryClass" ,"org.datanucleus.api.jdo.JDOPersistenceManagerFactory" );
JDOConfig.put("javax.jdo.option.ConnectionURL", "jdbc:mysql://localhost/acegi" );
JDOConfig.put( "javax.jdo.option.ConnectionDriverName" , "com.mysql.jdbc.Driver" );
JDOConfig.put( "javax.jdo.option.ConnectionUserName" , "root");
JDOConfig.put( "javax.jdo.option.ConnectionPassword" , "root");
JDOConfig.put( "javax.jdo.option.NontransactionalRead" , "true");
JDOConfig.put( "javax.jdo.option.NontransactionalWrite" , "true");
JDOConfig.put( "datanucleus.autoCreateSchema" , "true" );
PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory(JDOConfig);
PersistenceManager pm = pmf.getPersistenceManager();
Person person = null;
System. out.println("Insert iterm into DB. " );
//insert
person = new Person("wenhao" ,123,"wenhao@gmail.com");
pm.makePersistent(person);
//select
getPersonsFromDB(pm);
//update
person.setMail( "wenhao@sina.com.cn");
pm.close();
person.setAge(1000);
System. out.println("instance level : " + person.getAge());
pmf = JDOHelper. getPersistenceManagerFactory(JDOConfig);
pm = pmf.getPersistenceManager();
List<Person> updatePersons = getPersonsFromDB(pm);
if(updatePersons != null && updatePersons.size() > 0) {
for(Person updatePerson : updatePersons)
//delete
pm.deletePersistent(updatePerson);
System. out.println("Delete iterms from DB." );
}
pm.close();
//select
Query q = pm.newQuery( "SELECT FROM " + Person.class.getName() + " WHERE name == 'wenhao'" );
List<Person> updatePersons = (List)q.execute();
6. q行JDO操作c,q时直接q行?x)报如下的错误?x)
This means that it either hasnt been enhanced, or that the enhanced version of the file is not in the CLASSPATH (or is hidden by an unenhanced version), or the Meta-Data/annotations for the class are not found
q个错误的是因ؓ(f)没有对Entity classq行jdo的enhance来增强entity的二q制代码。故需要在project上增加datanucleus支持。ƈq行enhancer tool来enhance entity。运行后可通过反编译工h查看transform后的class。可发现多了一些属性和Ҏ(gu)。这些都是对JDO entity的扩展?br />
7.正常q行
?x)发现在person.setMail( "wenhao@sina.com.cn" );?x)更改到底层的数据库中,而person.setAge(1000);q不?x)更?gu)据库字段。其实很Ҏ(gu)理解。类似hibernate的entity的几个状态,自由?#183;持久?#183;游离态?当pm.close();后person处于自由态,修改的属性只有在instance内部有效。而在pm cloase或transaction.commit之前Ӟentity仍处理持久化状态,直接修改属性,?x)持久化到底层数据库中?br />
8.JDO对象的多对多关系实现。多对多和hibernate的配|类|主要q是在配|文件上做一些配|。配|文件如下:(x)
Person.jdo:
<jdo>
<package name="com.jdo.data.nucleus.model">
<class name="Person">
<field name="name" persistence-modifier="persistent">
<column length="100" jdbc-type="VARCHAR" />
</field>
<field name="age" persistence-modifier="persistent"/>
<field name="mail" persistence-modifier="persistent"/>
<field name="roles" persistence-modifier="persistent" table="PERSON_RULE">
<collection element-type="com.jdo.data.nucleus.model.Role" />
<join>
<column name="name" />
</join>
<element>
<column name="roleName" />
</element>
</field>
</class>
</package>
</jdo>
Role.jdo:
<jdo>
<package name="com.jdo.data.nucleus.model">
<class name="Role">
<field name="roleName" persistence-modifier="persistent">
<column length="100" jdbc-type="VARCHAR" />
</field>
<field name="roleDesc" persistence-modifier="persistent"/>
<field name="persons" persistence-modifier="persistent" table="PERSON_RULE">
<collection element-type="com.jdo.data.nucleus.model.Person" />
<join>
<column name="roleName" />
</join>
<element>
<column name="name" />
</element>
</field>
</class>
</package>
</jdo>
Person.java:
@PersistenceCapable
public class Person {
@PrimaryKey
private String name ;
private int age ;
private String mail ;
@Element
private Set<Role> roles ;
}
Role.java:
@PersistenceCapable
public class Role {
@PrimaryKey
private String roleName ;
private String roleDesc ;
@Element
private Set<Person> persons ;
}
以上配置可实现多对多的关pRƈ能够q行兌查询?br />
]]>
q么好的一ƾY件是不是免费的呢Q当然不是,但是软g的作者有N多种方式让你得到free license 的方法?br />
你做C上的M一条。你可以得到免费的许可证了?br />
嘿嘿Q终于暴露目的了…… 不过q么好的软gQ不推荐一下也实在说不q去?
]]>
通过多个廉L(fng)数据库实例组合到一个数据库阵列Q提供比单台数据库更好的性能和容错性?/span>
隐藏分布式数据库的复杂性,提供l数据库客户端一个独立的数据库?/span>
在RAIDb中,一个控制器在其他资源的前面。客户发送他们的h到RAIDb控制器,q个控制器将他们分发l一lRDBMS后端?/span>
有不同的RAIDbU别或数据分发方案可用,它提供不同的费用Q性能Q或者容错权衡?/span>
全分?RAIDb-0)
RAIDb-0 分割数据库表C个数据库后端节点集?/span>
注意Q?/span>
当前的实C支持分布式join。也是说如果你惛_表t1和t2间进行join操作Q你必须保t1和t2在同一台机器上?/span>
扩展性的提升取决于表的数目和各个表的负蝲情况Q?/span>
全复?(RAIDb-1)
RAIDb-1的扩展能力取决于控制器广播更新所有节点的能力。如果有大量后端数据库,使用复合RAIDb可以获得更好的扩展性?/span>
RAIDb-1提供了对L询的加速,因ؓ(f)他们可以被均衡到所有后端上。另一斚wQ它对写操作没有加速(update,insert,deletehQ,因ؓ(f)他们必须q播到所有节炏V写操作在所有的后端q行执行?/span>所以,在写的角度来看,RAIDb-1可能比不上一个单独的节点Q但是从ȝ角度来看Q性能?x)随着后端节点的增加而线性增ѝ?/span>
RAIDb-1有很好的定w性,因ؓ(f)pȝ即只有一个后端可用时也可以保持工作?/span>
不像RAIDb-0QRAIDb-1控制器不需要知道数据库的结构,因ؓ(f)所有的节点都有能力处理Mh。然后,RAIDb-1提供了一个缓存,它需要数据库l构来维护缓存的一致性?/span>
部分复制 (RAIDb-2)
RAIDb-2可以看作是RAIDb-0 ?RAIDb-1权衡下的一个中庸的解决Ҏ(gu)。它支持调整每个数据库表的部分复制程度,以获得一个做好的d性能?/span>
RAIDb-2:
下面是RAIDb-2的典型应用:(x)
没有或者只有少数几个节点运行整个数据库Q一l节点各自运行这数据库的一部分?/span>
下图中的例子昄了RAIDb-2的部分复Ӟ数据库包?个表Qx,y,和z.W一个后端包含整个数据库Q但是其他节炚w只包含一个或两个表。表x ?y?份拷?表z有两份拷贝。Q一节点p|Q仍然可以从其他的存?gu)z节点中扑ֈ数据?/span>
RAIDb-2对于异构数据库非常有用。一个已有的企业数据库用商业数据库Q但是要建立一个全拯无论是从存储上还是从增加许可的费用上来说Q都太贵了。有了RAIDb-2好办了Q你可以增加几个型开源数据库来各自运行整个数据库中的某些部分来代替整个数据库Q这样也可以获得更好的容错性?/span>
RAIDb-2定w性没有RAIDb-1好,但是它有效的改善了写操作的效率。跟RAIDb-0cMQRAIDb-2也要求控制器知道所有数据库的结构,以便请求定向到适当的节炏V?/span>
一、什么是Java虚拟?/span>
当你谈到Java虚拟机时Q你可能是指Q?/span>
1、抽象的Java虚拟?/span>
2、一个具体的Java虚拟机实?/span>
3、一个运行的Java虚拟机实?/span>
二?/span>Java虚拟机的生命周期
一个运行中?/span>Java虚拟机有着一个清晰的dQ执?/span>JavaE序。程序开始执行时他才q行Q程序结束时他就停止。你在同一台机器上q行三个E序Q就?x)有三个q行中的Java虚拟机?/span>
Java虚拟机L开始于一?/span>main()Ҏ(gu)Q这个方法必L公有、返?/span>void、直接受一个字W串数组。在E序执行Ӟ你必ȝJava虚拟机指明这个包?/span>main()Ҏ(gu)的类名?/span>
Main()Ҏ(gu)是程序的L(fng)Q他被执行的U程初始化ؓ(f)E序的初始线E。程序中其他的线E都׃来启动?/span>Java中的U程分ؓ(f)两种Q守护线E?/span> Q?/span>daemonQ和普通线E(non-daemonQ。守护线E是Java虚拟׃用的U程Q比如负责垃圾收集的U程是一个守护线E。当Ӟ你也?/span> 以把自己的程序设|ؓ(f)守护U程。包?/span>Main()Ҏ(gu)的初始线E不是守护线E?/span>
只要Java虚拟Zq有普通的U程在执行,Java虚拟机就不会(x)停止。如果有_的权限,你可以调?/span>exit()Ҏ(gu)l止E序?/span>
三?/span>Java虚拟机的体系l构
?/span>Java虚拟机的规范中定义了一pd的子pȝ、内存区域、数据类型和使用指南。这些组件构成了Java虚拟机的内部l构Q他们不仅仅?/span>Java虚拟机的实现提供了清晰的内部l构Q更是严D定了Java虚拟机实现的外部行ؓ(f)?/span>
每一?/span>Java虚拟机都׃个类加蝲器子pȝQ?/span>class loader subsystemQ,负责加蝲E序中的cdQ类和接口)Qƈ赋予唯一的名字。每一?/span>Java虚拟机都有一个执行引擎(execution engineQ负责执行被加蝲cM包含的指令?/span>
E序的执行需要一定的内存I间Q如字节码、被加蝲cȝ其他额外信息、程序中的对象、方法的参数、返回倹{本地变量、处理的中间变量{等?/span>Java虚拟机将 q些信息l统保存在数据区Q?/span>data areasQ中。虽然每?/span>Java虚拟机的实现中都包含数据区,但是Java虚拟范对数据区的规定却非常的抽象。许多结构上的细节部分都留给?/span> Java虚拟机实现者自己发挥。不?/span>Java虚拟机实C的内存结构千差万别。一部分实现可能占用很多内存Q而其他以下可能只占用很少的内存;一些实现可 能会(x)使用虚拟内存Q而其他的则不使用。这U比较精炼的Java虚拟机内存规U,可以使得Java虚拟机可以在q泛的^C被实现?/span>
数据Z的一部分是整个程序共有,其他部分被单独的U程控制。每一?/span>Java虚拟机都包含Ҏ(gu)区(method areaQ和堆(heapQ,他们都被整个E序׃n?/span>Java虚拟机加载ƈ解析一个类以后Q将从类文g中解析出来的信息保存与方法区中。程序执行时创徏?/span> 对象都保存在堆中?/span>
当一个线E被创徏Ӟ?x)被分配只属于他自己?/span>PC寄存?/span>“pc register”Q程序计数器Q和Java堆栈Q?/span>Java stackQ。当U程不掉用本地方法时Q?/span>PC寄存器中保存U程执行的下一条指令?/span>Java堆栈保存了一个线E调用方法时的状态,包括本地变量、调用方法的 参数、返回倹{处理的中间变量。调用本地方法时的状态保存在本地Ҏ(gu)堆栈中(native method stacksQ,可能再寄存器或者其他非q_独立的内存中?/span>
Java堆栈有堆栈块Q?/span>stack frames (or frames)Q组成。堆栈块包含JavaҎ(gu)调用的状态。当一个线E调用一个方法时Q?/span>Java虚拟Z(x)一个新的块压到Java堆栈中,当这个方法运行结束时Q?/span>Java虚拟Z(x)对应的块弹出ƈ抛弃?/span>
Java虚拟Z使用寄存器保存计的中间l果Q而是?/span>Java堆栈在存放中间结果。这是的Java虚拟机的指o(h)更紧凑,也更Ҏ(gu)在一个没有寄存器的设备上实现Java虚拟机?/span>
图中?/span>Java堆栈中向下增长的Q?/span>PC寄存器中U程三ؓ(f)灰色Q是因ؓ(f)它正在执行本地方法,他的下一条执行指令不保存?/span>PC寄存器中?/span>
四、数据类型(Data TypesQ?/span>
所?/span>Java虚拟Z使用的数据都有确定的数据cdQ数据类型和操作都在Java虚拟范中严格定义?/span>Java中的数据cd分ؓ(f)原始数据cd Q?/span>primitive typesQ和引用数据cdQ?/span>reference typeQ。引用类型依赖于实际的对象,但不是对象本w。原始数据类型不依赖于Q何东西,他们是本n表示的数据?/span>
所?/span>JavaE序语言中的原始 数据cdQ都?/span>Java虚拟机的原始数据cdQ除了布?yu)(dng)型Q?/span>booleanQ。当~译器将Java源代码编译ؓ(f)自己码时Q用整型(intQ或者字节型 Q?/span>byteQ去表示布尔型。在Java虚拟Z使用整数0表示布尔型的falseQ用非零整数表C布?yu)(dng)型?/span>trueQ布?yu)(dng)数l被表示为字节数l,虽然?/span> 们可能会(x)以字节数l或者字节块Q?/span>bit fieldsQ保存在堆中?/span>
除了布尔型,其他Java语言中的原始cd都是Java虚拟Z的数据类型。在Java中数据类型被分ؓ(f)Q整形的byteQ?/span>shortQ?/span>intQ?/span>longQ?/span>char和Q点型?/span>floatQ?/span>double?/span>Java语言中的数据cd在Q何主Z都有同样的范围?/span>
?/span>Java虚拟Zq存在一?/span>Java语言中不能用的原始数据cdq回值类型(returnValueQ。这U类型被用来实现JavaE序中的“finally clauses”Q具体的参见18章的“Finally Clauses”?/span>
引用cd可能被创Zؓ(f)Q类cdQ?/span>class typeQ,接口cdQ?/span>interface typeQ,数组cdQ?/span>array typeQ。他们都引用被动态创建的对象。当引用cd引用nullӞ说明没有引用M对象?/span>
Java虚拟范只定义了每一U数据类型表C的范围Q没有定义在存储时每U类型占用的I间。他们如?/span>存储?/span>Java虚拟机的实现者自己决定。关于Q点型更多信息参见14?/span>“Floating Point Arithmetic”?/span>
TypeRange
byte8-bit signed two's complement integer (-27 to 27 - 1, inclusive)
short16-bit signed two's complement integer (-215 to 215 - 1, inclusive)
int32-bit signed two's complement integer (-231 to 231 - 1, inclusive)
long64-bit signed two's complement integer (-263 to 263 - 1, inclusive)
char16-bit unsigned Unicode character (0 to 216 - 1, inclusive)
float32-bit IEEE 754 single-precision float
double64-bit IEEE 754 double-precision float
returnValueaddress of an opcode within the same method
referencereference to an object on the heap, or null
五、字节长?/span>
Java虚拟Z最的数据单元式字Q?/span>wordQ,其大由Java虚拟机的实现者定义。但是一个字的大必够容U?/span>byteQ?/span>shortQ?/span>intQ?/span> charQ?/span>floatQ?/span>returnValueQ?/span>referenceQ两个字必须_容纳longQ?/span>double。所以虚拟机的实现者至提供的字不能小 ?/span>31bits的字Q但是最好选择特定q_上最有效率的字长?/span>
在运行时Q?/span>JavaE序不能军_所q行机器的字ѝ字长也不会(x)影响E序的行为,他只是在Java虚拟Z的一U表现方式?/span>
六、类加蝲器子pȝ
Java虚拟Z的类加蝲器分ZU:(x)原始cd载器Q?/span>primordial class loaderQ和cd载器对象Q?/span>class loader objectsQ。原始类加蝲器是Java虚拟机实现的一部分Q类加蝲器对象是q行中的E序的一部分。不同类加蝲器加载的c被不同的命名空间所分割?/span>
cd载器调用了许?/span>Java虚拟Z其他的部分和java.lang包中的很多类。比如,cd载对象就?/span>java.lang.ClassLoader子类 的实例,ClassLoadercM的方法可以访问虚拟机中的cd载机Ӟ每一个被Java虚拟机加载的c都?x)被表示Z?/span> java.lang.Classcȝ实例。像其他对象一Pcd载器对象?/span>Class对象都保存在堆中Q被加蝲的信息被保存在方法区中?/span>
1、加载、连接、初始化Q?/span>Loading, Linking and InitializationQ?/span>
cd载子pȝ不仅仅负责定位ƈ加蝲cLӞ他按照以下严格的步骤作了很多其他的事情:(x)Q具体的信息参见W七章的“cȝ生命周期”Q?/span>
1Q、加载:(x)Lq导入指定类型(cd接口Q的二进制信?/span>
2Q、连接:(x)q行验证、准备和解析
?/span>验证Q确保导入类型的正确?/span>
?/span>准备Qؓ(f)cd分配内存q初始化为默认?/span>
?/span>解析Q将字符引用解析为直接饮?/span>
3Q、初始化Q调?/span>Java代码Q初始化cd量ؓ(f)合适的?/span>
2、原始类加蝲器(The Primordial Class LoaderQ?/span>
每个Java虚拟机都必须实现一个原始类加蝲器,他能够加载那些遵守类文g格式q且被信ȝcR但是,Java虚拟机的规范q没有定义如何加载类Q这?/span> Java虚拟机实现者自己决定。对于给定类型名的类型,原始莱加载器必须扑ֈ那个cd名加“.class”的文件ƈ加蝲入虚拟机中?/span>
3、类加蝲器对?/span>
虽然cd载器对象?/span>JavaE序的一部分Q但?/span>ClassLoadercM的三个方法可以访?/span>Java虚拟Z的类加蝲子系l?/span>
1Q?/span>protected final Class defineClass(…)Q用这个方法可以出入一个字节数l,定义一个新的类型?/span>
2Q?/span>protected Class findSystemClass(String name)Q加载指定的c,如果已经加蝲Q就直接q回?/span>
3Q?/span>protected final void resolveClass(Class c)Q?/span>defineClass()Ҏ(gu)只是加蝲一个类Q这个方法负责后l的动态连接和初始化?/span>
具体的信息,参见W八?/span>“q接模型”Q?/span> The Linking ModelQ?/span>
4、命名空?/span>
当多个类加蝲器加载了同一个类ӞZ保证他们名字的唯一性,需要在cd前加上加载该cȝcd载器的标识。具体的信息Q参见第八章“q接模型”Q?/span> The Linking ModelQ?/span>
七、方法区Q?/span>The Method AreaQ?/span>
?/span>Java虚拟ZQ被加蝲cd的信息都保存在方法区中。这写信息在内存中的l织形式p拟机的实现者定义,比如Q虚拟机工作在一?/span>“little- endian”的处理器上,他就可以信息保存ؓ(f)“little-endian”格式的,虽然?/span>JavacL件中他们是以“big-endian”格式?/span> 存的。设计者可以用最适合q地机器的表C格式来存储数据Q以保证E序能够以最快的速度执行。但是,在一个只有很内存的讑֤上,虚拟机的实现者就不会(x)占用 很大的内存?/span>
E序中的所有线E共享一个方法区Q所以访问方法区信息的方法必LU程安全的。如果你有两个线E都d载一个叫Lava的类Q那只能׃个线E被容许d载这个类Q另一个必ȝ待?/span>
在程序运行时Q方法区的大是可变的,E序在运行时可以扩展。有?/span>Java虚拟机的实现也可以通过参数也订制方法区的初始大,最值和最大倹{?/span>
Ҏ(gu)Z可以被垃圾收集。因为程序中的内q加蝲器动态加载,所有类可能变成没有被引用(unreferencedQ的状态。当cd成这U状态时Q他可 能被垃圾攉掉。没有加载的cd括两U状态,一U是真正的没有加载,另一个种?/span>“unreferenced”的状态。详l信息参见第七章的类的生命周?/span> Q?/span>The Lifetime of a ClassQ?/span>
1、类型信息(Type InformationQ?/span>
每一个被加蝲的类型,?/span>Java虚拟Z都会(x)在方法区中保存如下信息:(x)
1Q、类型的全名Q?/span>The fully qualified name of the typeQ?/span>
2Q、类型的父类型的全名Q除非没有父cdQ或者弗雷Ş?/span>java.lang.ObjectQ(The fully qualified name of the typeís direct superclassQ?/span>
3Q、给cd是一个类q是接口Q?/span>class or an interfaceQ(Whether or not the type is a class Q?/span>
4Q、类型的修饰W(publicQ?/span>privateQ?/span>protectedQ?/span>staticQ?/span>finalQ?/span>volatileQ?/span>transient{)Q?/span>The typeís modifiersQ?/span>
5Q、所有父接口全名的列表(An ordered list of the fully qualified names of any direct superinterfacesQ?/span>
cd全名保存的数据结构由虚拟机实现者定义。除此之外,Java虚拟要ؓ(f)每个cd保存如下信息Q?/span>
1Q、类型的帔R池(The constant pool for the typeQ?/span>
2Q、类型字D늚信息Q?/span>Field informationQ?/span>
3Q、类型方法的信息Q?/span>Method informationQ?/span>
4Q、所有的静态类变量Q非帔RQ信息(All class (static) variables declared in the type, except constantsQ?/span>
5Q、一个指向类加蝲器的引用Q?/span>A reference to class ClassLoaderQ?/span>
6Q、一个指?/span>Classcȝ引用Q?/span>A reference to class ClassQ?/span>
1Q、类型的帔R池(The constant pool for the typeQ?/span>
帔R池中保存中所有类型是用的有序的常量集合,包含直接帔RQ?/span>literalsQ如字符丌Ӏ整数、QҎ(gu)的常量,和对cd、字Dc(din)方法的W号引用。常量池 中每一个保存的帔R都有一个烦引,像数组中的字段一栗因为常量池中保存中所有类型用到的类型、字Dc(din)方法的字符引用Q所以它也是动态连接的主要?/span> 象。详l信息参见第六章“The Java Class File”?/span>
2Q、类型字D늚信息Q?/span>Field informationQ?/span>
字段名、字D늱型、字D늚修饰W(publicQ?/span>privateQ?/span>protectedQ?/span>staticQ?/span>finalQ?/span>volatileQ?/span>transient{)、字D在cM定义的顺序?/span>
3Q、类型方法的信息Q?/span>Method informationQ?/span>
Ҏ(gu)名、方法的q回值类型(或者是voidQ、方法参数的个数、类型和他们的顺序、字D늚修饰W(publicQ?/span>privateQ?/span>protectedQ?/span>staticQ?/span>finalQ?/span>volatileQ?/span>transient{)、方法在cM定义的顺?/span>
如果不是抽象和本地本法还需要保?/span>
Ҏ(gu)的字节码、方法的操作数堆栈的大小和本地变量区的大(E候有详细信息Q、异常列表(详细信息参见W十七章“Exceptions”。)
4Q、类Q静态)变量Q?/span>Class VariablesQ?/span>
cd量被所有类的实例共享,即不通过cȝ实例也可以访问。这些变量绑定在cMQ而不是类的实例上Q,所以他们是cȝ逻辑数据的一部分。在Java虚拟Z用这个类之前需要ؓ(f)cd量(non-finalQ分配内?/span>
帔RQ?/span>finalQ的处理方式于这U类变量Q?/span>non-finalQ不一栗每一个类型在用到一个常量的时候,都会(x)复制一份到自己的常量池中。常量也像类?/span> 量一样保存在Ҏ(gu)ZQ只不过他保存在帔R池中。(可能是,cd量被所有实例共享,而常量池是每个实例独有的Q?/span>Non-finalcd量保存ؓ(f)定义他的 cd数据Q?/span>data for the type that declares themQ的一部分Q?/span>final帔R保存Z用他的类型数据(data for any type that uses themQ的一部分。详情参见第六章“The Java Class FileThe Java Class File”
5Q、指向类加蝲器的引用Q?/span>A reference to class ClassLoaderQ?/span>
每一个被Java虚拟机加载的cdQ虚拟机必须保存q个cd是否由原始类加蝲器或者类加蝲器加载。那些被cd载器加蝲的类型必M存一个指向类加蝲器的?/span> 用。当cd载器动态连接时Q会(x)使用q条信息。当一个类引用另一个类Ӟ虚拟机必M存那个被引用的类型是被同一个类加蝲器加载的Q这也是虚拟机维护不同命 名空间的q程。详情参见第八章“The Linking Model”
6Q、指?/span>Classcȝ引用Q?/span>A reference to class ClassQ?/span>
Java虚拟Zؓ(f)每一个加载的cd创徏一?/span>java.lang.Classcȝ实例。你也可以通过ClasscȝҎ(gu)Q?/span>
public static Class forName(String className)来查找或者加载一个类Qƈ取得相应?/span>Classcȝ实例。通过q个Classcȝ实例Q我们可以访?/span>Java虚拟机方法区中的信息。具体参?/span>ClasscȝJavaDoc?/span>
2、方法列表(Method TablesQ?/span>
Z更有效的讉K所有保存在Ҏ(gu)Z的数据,q些数据的存储结构必ȝq仔l的设计。所有方法区中,除了保存了上边的那些原始信息外,q有一个ؓ(f)了加快存 取速度而设计的数据l构Q比如方法列表。每一个被加蝲的非抽象c,Java虚拟机都?x)?f)他们产生一个方法列表,q个列表中保存了q个cd能调用的所有实?/span> Ҏ(gu)的引用,报错那些父类中调用的Ҏ(gu)。详情参见第八章“The Linking Model”
八、堆
?/span>JavaE序创徏一个类的实例或者数l时Q都在堆中ؓ(f)新的对象分配内存。虚拟机中只有一个堆Q所有的U程都共享他?/span>
1、垃圾收集(Garbage CollectionQ?/span>
垃圾攉是释放没有被引用的对象的主要Ҏ(gu)。它也可能会(x)Z减少堆的片Q而移动对象。在Java虚拟机的规范中没有严格定义垃圾收集,只是定义一?/span>Java虚拟机的实现必须通过某种方式理自己的堆。详情参见第?ji)?/span>“Garbage Collection”?/span>
2、对象存储结构(Object RepresentationQ?/span>
Java虚拟机的规范中没有定义对象怎样在堆中存储。每一个对象主要存储的是他的类和父cM定义的对象变量。对于给定的对象的引用,虚拟机必d耨很快的 定位到这个对象的数据。另为,必须提供一U通过对象的引用方法对象数据的Ҏ(gu)Q比如方法区中的对象的引用,所以一个对象保存的数据中往往含有一个某UŞ?/span> 指向Ҏ(gu)区的指针?/span>
一个可能的堆的设计是将堆分Z个部分:(x)引用池和对象池。一个对象的引用是指向引用池的本地指针。每一个引用池中的条目都包含两个部分:(x)指向对象池中?/span> 象数据的指针和方法区中对象类数据的指针。这U设计能够方?/span>Java虚拟机堆片的整理。当虚拟机在对象池中Ud一个对象的时候,只需要修改对应引用池?/span> 的指针地址。但是每ơ访问对象的数据都需要处理两ơ指针。下图演CZq种堆的设计。在W九(ji)章的“垃圾攉”中的HeapOfFish Applet演示了这U设计?/span>
另一U堆的设计是Q一个对象的引用是一个指向一堆数据和指向相应对象的偏UL针。这U设计方便了对象的访问,可是对象的移动要变的异常复杂。下图演CZq种设计
当程序试囑ְ一个对象{换ؓ(f)另一U类型时Q虚拟机需要判断这U{换是否是q个对象的类型,或者是他的父类型。当E序适用instanceof语句的时候也 ?x)做cM的事情。当E序调用一个对象的Ҏ(gu)Ӟ虚拟机需要进行动态绑定,他必d断调用哪一个类型的Ҏ(gu)。这也需要做上面的判断?/span>
无论虚拟机实现者用哪一U设计,他都可能为每一个对象保存一个类似方法列表的信息。因Z可以提升对象Ҏ(gu)调用的速度Q对提升虚拟机的性能非常重要Q但 是虚拟机的规范中比没有要求必d现类似的数据l构。下图描qCq种l构。图中显CZ一个对象引用相兌的所有的数据l构Q包括:(x)
1Q、一个指向类型数据的指针
2Q、一个对象的Ҏ(gu)列表。方法列表是一个指向所有可能被调用对象Ҏ(gu)的指针数l。方法数据包括三个部分:(x)操作码堆栈的大小和方法堆栈的本地变量区;Ҏ(gu)的字节码Q异常列表?/span>
每一?/span>Java虚拟Z的对象必d联一个用于同步多U程?/span>lock(mutex)。同一时刻Q只能有一个对象拥有这个对象的锁。当一个拥有这个这个对?/span> 的锁Q他可以多ơ申误个锁Q但是也必须释放相应ơ数的锁才能真正释放q个对象锁。很多对象在整个生命周期中都不会(x)被锁Q所以这个信息只有在需要时才需 要添加。很?/span>Java虚拟机的实现都没有在对象的数据中包含“锁定数据”Q只是在需要时才生成相应的数据。除了实现对象的锁定Q每一个对象还逻辑兌C ?/span>“wait set”的实现。锁定帮l线E独立处理共享的数据Q不需要妨其他的U程?/span>“wait set”帮组U程协作完成同一个目标?/span>“wait set”往往通过Objectcȝwait()?/span>notify()Ҏ(gu)来实现?/span>
垃圾攉也需要堆中的对象是否被关联的信息?/span>Java虚拟范中指出垃圾攉一个运行一个对象的finalizerҎ(gu)一ơ,但是容许 finalizerҎ(gu)重新引用q个对象Q当q个对象再次不被引用Ӟ׃需要再ơ调?/span>finalizeҎ(gu)。所以虚拟机也需要保?/span>finalizeҎ(gu) 是否q行q的信息。更多信息参见第?ji)章?/span>“垃圾攉”
3、数l的保存Q?/span>Array RepresentationQ?/span>
?/span>Java 中,数组是一U完全意义上的对象,他和对象一样保存在堆中、有一个指?/span>Classcd例的引用。所有同一l度和类型的数组拥有同样?/span>ClassQ数l的?/span> 度不做考虑。对?/span>Class的名字表CZؓ(f)l度和类型。比如一个整型数据的Class?/span>“[I”Q字节型三维数组Class名ؓ(f)“[[[B”Q两l对象数?/span> Class名ؓ(f)“[[Ljava.lang.Object”?/span>
多维数组被表CZؓ(f)数组的数l,如下图:(x)
数组必须在堆中保存数l的长度Q数l的数据和一些对象数l类型数据的引用。通过一个数l引用的Q虚拟机应该能够取得一个数l的长度Q通过索引能够讉K特定 的数据,能够调用Object定义的方法?/span>Object是所有数据类的直接父cR更多信息参见第六章“cL?/span>”?/span>
?ji)?/span>PC寄存器(E序计数器)Q?/span>The Program CounterQ?/span>
每一个线E开始执行时都会(x)被创Z个程序计数器。程序计数器只有一个字长(wordQ,所以它能够保存一个本地指针和returnValue。当U程执行 ӞE序计数器中存放了正在执行指令的地址Q这个地址可以使一个本地指针,也可以一个从Ҏ(gu)字节码开始的偏移指针。如果执行本地方法,E序计数器的值没 有被定义?/span>
十?/span>Java堆栈Q?/span>The Java StackQ?/span>
当一个线E启动时Q?/span>Java虚拟Z(x)Z创徏一?/span>Java堆栈?/span>Java堆栈用一些离散的framecȝ录线E的状态?/span>Java虚拟机堆Java堆栈的操作只有两U:(x)压入和弹?/span>frames?/span>
U程中正在执行的Ҏ(gu)被称为当前方法(current methodQ,当前Ҏ(gu)所对应?/span>frame被称为当前Q?/span>current frameQ。定义当前方法的c被UCؓ(f)当前c(current classQ,当前cȝ帔R池被UCؓ(f)当前帔R池(current constant pool.Q。当U程执行ӞJava虚拟Z(x)跟踪当前cd当前帔R池。但U程操作保存在中的数据Ӟ他只操作当前帧的数据?/span>
当线E调用一个方法时Q虚拟机?x)生成一个新的Qƈ压入U程?/span>Java堆栈。这个新的变成当前帧。当Ҏ(gu)执行Ӟ他用当前保存Ҏ(gu)的参数、本地变 量、中间结构和其他数据。方法有两种退出方式:(x)正常退出和异常推出。无论方法以哪一U方式推出,Java虚拟机都?x)弹出ƈ丢弃?gu)的Q上一个方法的帧变 为当前?/span>
所有保存在帧中的数据都只能被拥有它的线E访问,U程不能讉K其他U程的堆栈中的数据。所以,讉KҎ(gu)的本地变量时Q不需要考虑多线E同步?/span>
和方法区、堆一PJava堆栈不需要连l的内存I间Q它可以被保存在一个分散的内存I间或者堆上。堆栈具体的数据和长度都?/span>Java虚拟机的实现者自己定义。一些实现可能提供了执行堆栈最大值和最值的Ҏ(gu)?/span>
十一、堆栈Q?/span>The Stack FrameQ?/span>
堆栈帧包含三部分Q本地变量、操作数堆栈和数据。本地变量和操作数堆栈的大小都是一字(wordQؓ(f)单位的,他们在编译就已经定。数据的大取决于 不同的实现。当E序调用一个方法时Q虚拟机从类数据中取得本地变量和操作数堆栈的大小Q创Z个合适大和帧,然后压入Java堆栈中?/span>
1、本地变量(Local VariablesQ?/span>
本地变量?/span>Java堆栈帧中被组lؓ(f)一个从0计数的数l,指o(h)通过提供他们的烦引从本地变量Z取得相应的倹{?/span>Int,float,reference, returnValue占一个字Q?/span>byte,short,char被{换成int然后存储Q?/span>long?/span>doubel占两个字?/span>
指o(h)通过提供两个字烦引中的前一个来取得long,doubel的倹{比如一?/span>long的值存储在索引3Q?/span>4上,指o(h)可以通过3来取得这?/span>longcd的倹{?/span>
本地变量Z包含了方法的参数和本地变量。编译器方法的参数以他们申明的序攑֜数组的前面。但是编译器却可以将本地变量L排列在本地变量数l中Q甚至两个本地变量可以公用一个地址Q比如,当两个本地变量在两个不交叠的区域内,像循环变量i,j?/span>
虚拟机的实现者可以用Q何结构来描述本地变量Z的数据,虚拟范中没有定义如何存储long?/span>doubel?/span>
2、操作数堆栈Q?/span>Operand StackQ?/span>
向本地变量一P操作数堆栈也被组lؓ(f)一个以字ؓ(f)单位的数l。但是不像本地变量那样通过索引讉KQ而是通过push?/span>pop值来实现讉K的。如果一个指?/span>push一个值到堆栈中,那么下一个指令就可以popq且使用q个倹{?/span>
操作数堆栈不像程序计数器那样不可以被指o(h)直接讉KQ指令可以直接访问操作数堆栈?/span>Java虚拟机是一个以堆栈为基Q而不是以寄存器ؓ(f)基础的,因ؓ(f)它的 指o(h)从堆栈中取得操作敎ͼ而不是同寄存器中。当Ӟ指o(h)也可以从其他地方ȝ操作敎ͼ比如指o(h)后面的操作码Q或者常量池。但?/span>Java虚拟机指令主要是?/span> 操作数堆栈中取得他们需要的操作数?/span>
Java虚拟机将操作数堆栈视为工作区Q很多指令通过先从操作数堆栈中pop|在处理完以后再将l果push回操作数堆栈。一?/span>add的指令执行过E如 下图所C:(x)先执?/span>iload_0?/span>iload_1两条指o(h)需要相加的两个敎ͼ从本地方法区中取出,q?/span>push到操作数堆栈中;然后执行iadd指o(h)Q现 popZ个|相加Qƈ结?/span>puspq操作数堆栈中;最后执?/span>istore_2指o(h)Q?/span>pop出结果,赋值到本地Ҏ(gu)Z?/span>
3、数据Q?/span>Frame DataQ?/span>
处理本地变量和操作数堆栈以外Q?/span>java堆栈帧还包括了ؓ(f)了支持常量池Q方法返回值和异常分发需要的数据Q他们被保存在数据中?/span>
当虚拟机遇到使用指向帔R池引用的指o(h)Ӟ׃(x)通过帧数据中指向帔R区的指针来访问所需要的信息。前面提到过Q常量区中的引用在最开始时都是W号引用。即使当虚拟机检查这些引用时Q他们也是字W引用。所以虚拟机需要在q时转换q个引用?/span>
当一个方法正常返回时Q虚拟机需要重建那个调用这个方法的Ҏ(gu)的堆栈。如果执行完的方法有q回|虚拟机就需要将q个?/span>pushq调用方法的哪个操作数堆栈中?/span>
帧数据中也包含虚拟机用来处理异常的异常表的引用。异常表定义了一个被catch语句保护的一D字节码。每一个异常表中的个体又包含了需要保护的字节玛的 范围Q和异常被捕捉到旉要执行的字节码的位置。当一个方法抛Z个异常时Q?/span>Java虚拟机就是用异常表去判断如何处理q个异常。如果虚拟机扑ֈ了一个匹 配的catchQ他׃(x)控制权交给catch语句。如果没有找到匹配的catchQ方法就?x)异常返回,然后再调用的?gu)中l这个过E?/span>
除了以上的三个用途外Q数据q可能包含一些依赖于实现的数据,比如调试的信息?/span>
十二、本地方法堆?/span>
本地Ҏ(gu)Z赖于虚拟机的不同实现。虚拟机的实现者可以自己决定用哪一U机制去执行本地Ҏ(gu)?/span>
M本地Ҏ(gu)接口Q?/span>Native Method InterfaceQ都使用某种形式的本地方法堆栈?/span>
十三、执行引?/span>
一?/span>java虚拟机实现的核心?yu)是执行引擎。在Java虚拟范,执行引擎被描qCؓ(f)一pd的指令。对于每一个指令,规范都描qC他们应该做什么,但是没有说要如何d?/span>
1、指令集
?/span>Java虚拟Z一个方法的字节码流是一个指令的序列。每一个指令由一个字节的操作码(OpcodeQ和可能存在的操作数Q?/span>OperandsQ。操?/span> 码指C去做什么,操作数提供一些执行这个操作码可能需要的额外的信息。一个抽象的执行引擎每次执行一个指令。这个过E发生在每一个执行的U程中?/span>
有时Q执行引擎可能会(x)遇到一个需要调用本地方法的指o(h)Q在q种情况下,执行引擎?x)去试图调用本地?gu)Q但本地Ҏ(gu)q回Ӟ执行引擎?x)l执行字节码中的下一个指令。本地方法也可以看成?/span>Java虚拟Z的指令集的一U扩充?/span>
军_下一步执行那一条指令也是执行引擎工作的一部分。执行引擎有三种Ҏ(gu)d得下一条指令。多数指令会(x)执行跟在他会(x)面的指o(h)Q一些像gotoQ?/span> return的指令,?x)在他们执行的时候决定他们的下一条指令;当一个指令抛出异常时Q执行引擎通过匚wcatch语句来决定下一条应该执行的指o(h)?/span>
q_独立性、网l移动性?/span>安全性左右了Java虚拟机指令集的设计。^台独立性是指o(h)集设计的主要影响因素之一。基于堆栈的l构使得Java虚拟机可以在 更多的^C实现。更的操作码,紧凑的结构得字节码可以更有效的利用|络带宽。一ơ性的字节码验证,使得字节码更安全Q而不影响太多的性能?/span>
2、执行技?/span>
许多U执行技术可以用?/span>Java虚拟机的实现中:(x)解释执行Q及(qing)时编译(just-in-time compilingQ,hot-spot compiling,native execution in silicon?/span>
3、线E?/span>
Java虚拟范定义了一Uؓ(f)了在更多q_上实现的U程模型?/span>JavaU程模型的一个目标时可以利用本地U程。利用本地线E可以让JavaE序中的U程能过在多处理器机器上真正的同时执行?/span>
JavaU程模型的一个代价就是线E优先Q一?/span>JavaU程可以?/span>1-10的优先上运行?/span>1最低,10最高。如果设计者用了本地U程Q他们可能将q?/span> 10个优先映射到本C先上?/span>Java虚拟范只定义了,高一点优先的线E可以却一?/span>cpu旉Q低优先U的U程在所有高优先U线E都堵塞Ӟ?/span> 可以获取一?/span>cpu旉Q但是这没有保证Q低优先U的U程在高优先U线E没有堵塞时不可以获得一定的cpu旉。因此,如果需要在不同的线E间协作Q你?/span> M用的“同步Q?/span>synchronizatoinQ?/span>”?/span>
同步意味着两个部分Q对象锁Q?/span>object lockingQ和U程{待、激z?/span>(thread wait and notify)。对象锁帮助U程可以不受其他U程的干扰。线E等待、激zd以让不同的线E进行协作?/span>
?/span>Java虚拟机的规范中,JavaU程被描qCؓ(f)变量、主内存、工作内存。每一?/span>Java虚拟机的实例都有一个主内存Q他包含了所有程序的变量Q对象、数l合cd量。每一个线E都有自q工作内存Q他保存了哪些他可能用到的变量的拯。规则:(x)
1Q、从d存拷贝变量的值到工作内存?/span>
2Q、将工作内存中的值写?x)主内存?/span>
如果一个变量没有被同步化,U程可能以Q何顺序更C内存中的变量。ؓ(f)了保证多U程E序的正的执行Q必M用同步机制?/span>
十四、本地方法接口(Native Method InterfaceQ?/span>
Java虚拟机的实现q不是必d现本地方法接口。一些实现可能根本不支持本地Ҏ(gu)接口?/span>Sun的本地方法接口是JNI(Java Native Interface)?/span>
十五、现实中的机器(The Real MachineQ?/span>
十六、数学方法:(x)仿真(Eternal Math : A Simulation)
database Partition Feature Q?/span>
The Database Partitioning Feature (DPF) is a value-added option available with DB2 Enterprise 9. It extends the capability of DB2 9 into the parallel, multi-partition environment, improving performance and scalability of very large databases. This allows very complex queries to be executed much faster. DB2 Enterprise 9 with DPF is an ideal solution for managing data warehousing and data mining environments, but can also be used for large online transaction processing (OLTP) workloads.
A database partition can be either logical or physical. Logical partitions reside on the same physical server and can take advantage of SMP architecture. Having a
partitioned database on a single machine with multiple logical nodes is know as having a shared-everything architecture, because the partitions use common memory, CPUs, disk controllers, and disks. Physical partitions consist of two or more physical servers and the database is partitioned across these servers. This is know as a shared-nothing architecture, because each partition has its own memory, CPU’s, disk controllers and disks.
创徏database partition
1、创建需要徏立数据库分区?/span>db instance
可用命令徏?/span>db instance Q?/span>
db2icrt -s ESE -u db2admin,aaa123456 -h ANWENHAO DBINSTANCENAME
创徏完成对应?/span>instance 后需要重?/span>DB2 .
2、将新徏?/span>db instance 加入?/span>DB2中:(x)
CATALOG LOCAL NODE DB2INST1 INSTANCE DB2INST1 SYSTEM ANWENHAO OSTYPE NT;
3、在命o(h)行中讄当前需要操作的dbInstance
set db2instance=db2inst1
db2 get instance
db2 attach to db2inst1
4、创?/span>DBPartition Q?/span>
db2start dbpartitionnum 1 ADD DBPARTITIONNUM HOSTNAME ANWENHAO PORT 1 COMPUTER ANWENHAO USER db2admin PASSWORD aaa123456 WITHOUT TABLESPACES
5、创建完成后需要重新启?/span>db2?/span>DB2在此时会(x)增加一?/span>database partition q进?/span> redistribution
以上操作卛_?/span>database partition ?/span>
创徏database partition group :
CREATE DATABASE PARTITION GROUP "NODE1" ON DBPARTITIONNUMS (1);
COMMENT ON DATABASE PARTITION GROUP "NODE1" IS 'ANWENHAO _1';
然后可以在徏?/span>tablespace旉择是否建立在一?/span>database partition group中。这h们就可以L使用DB2?/span>database Partition建立集群的应用了?/span>
分区表用了数据l织Ҏ(gu)Q即Q表数据Ҏ(gu)该表中一个或多个表分区键列中的值分布到多个存储对象Q称?span style="BACKGROUND: highlight; COLOR: highlighttext">数据分区或范_(d)中。根?CREATE TABLE 语句?PARTITION BY 子句中指定的内容Q给定表的数据被划分到多个存储对象中。这些存储对象可以在不同的表I间中,也可以在相同表空间中?/span>
以下CZ演示?span style="BACKGROUND: highlight; COLOR: highlighttext">数据分区消除所产生的性能斚w的好处。如果发Z下语句:(x)
CREATE TABLE custlist(subsdate DATE, Province CHAR(2), AccountID INT) PARTITION BY RANGE(subsdate) (STARTING FROM '1/1/1990' IN ts1, STARTING FROM '1/1/1991' IN ts1, STARTING FROM '1/1/1992' IN ts1, STARTING FROM '1/1/1993' IN ts2, STARTING FROM '1/1/1994' IN ts2, STARTING FROM '1/1/1995' IN ts2, STARTING FROM '1/1/1996' IN ts3, STARTING FROM '1/1/1997' IN ts3, STARTING FROM '1/1/1998' IN ts3, STARTING FROM '1/1/1999' IN ts4, STARTING FROM '1/1/2000' IN ts4, STARTING FROM '1/1/2001' ENDING '12/31/2001' IN ts4);
假定(zhn)对 2000 q的客户信息感兴。如果发Z下查询:(x)
SELECT * FROM custlist WHERE subsdate BETWEEN '1/1/2000' AND '12/31/2000';
正如?101所昄的那P数据库服务器定只需要访问表I间 4Qts4Q中的一?span style="BACKGROUND: highlight; COLOR: highlighttext">数据分区可以解x查询?/span>
??102 中显C的另一?span style="BACKGROUND: highlight; COLOR: highlighttext">数据分区消除CZ是烦引扫描,它涉?qing)两个烦引ƈ?gu)以下Ҏ(gu)q行扫描Q?/span>
CREATE TABLE multi (sale_date date, region char(2)) PARTITION BY (sale_date) (STARTING '01/01/2005' ENDING '12/31/2005' EVERY 1 MONTH); CREATE INDEX sx ON multi(sale_date); CREATE INDEX rx ON multi(region);
如果发出以下查询Q?/p>
SELECT * FROM multi WHERE sale_date BETWEEN '6/1/2005' AND '7/31/2005' AND REGION = 'NW';
在不使用表分区时Q一U可能的Ҏ(gu)是烦?#8220;?#8221;QANDQ。烦?#8220;?#8221;QANDQ执行下列Q务:(x)
?a href="http://localhost:51000/help/topic/com.ibm.db2.udb.admin.doc/doc/c0021579.htm#indexanding">?102 中所C,在用表分区的情况下Q读取烦引以查找 region ?sale_date 的匹配项Q从而允许快速检索匹配行?/p>
q可以?DB2 说明来确?DB2 优化器选择的分区消除?strong>DP Elim Predicates 信息昄扫描了哪?span style="BACKGROUND: highlight; COLOR: highlighttext">数据分区来解决以下查询:(x)
SELECT * FROM custlist WHERE subsdate BETWEEN '12/31/1999' AND '1/1/2001'
Arguments: --------- DPESTFLG: (Number of data partitions accessed are Estimated) FALSE DPLSTPRT: (List of data partitions accessed) 9-11 DPNUMPRT: (Number of data partitions accessed) 3 DP Elim Predicates: ------------------ Range 1) Stop Predicate: (Q1.A <= '01/01/2001') Start Predicate: ('12/31/1999' <= Q1.A) Objects Used in Access Plan: --------------------------- Schema: MRSRINI Name: CUSTLIST Type: Data Partitioned Table Time of creation: 2005-11-30-14.21.33.857039 Last statistics update: 2005-11-30-14.21.34.339392 Number of columns: 3 Number of rows: 100000 Width of rows: 19 Number of buffer pool pages: 1200 Number of data partitions: 12 Distinct row values: No Tablespace name: <VARIOUS>
在用多个列作ؓ(f)表分区键的情况下Q?span style="BACKGROUND: highlight; COLOR: highlighttext">数据分区消除v作用?/span>
例如Q如果发Z下语句:(x)
CREATE TABLE sales (year INT, month INT) PARTITION BY RANGE(year, month) (STARTING FROM (2001, 1) ENDING AT(2001,3) IN ts1, ENDING AT(2001,6) IN ts2, ENDING AT(2001,9) IN ts3, ENDING AT(2001,12) IN ts4, ENDING AT(2002,3) IN ts5, ENDING AT(2002,6) IN ts6, ENDING AT(2002,9) IN ts7, ENDING AT(2002,12) IN ts8)
接着Q发Z下查询:(x)
SELECT * FROM sales WHERE year = 2001 AND month < 8
查询优化器推断只需要访?ts1、ts2 ?ts3 中的数据分区可以解x查询?/span>
可以使用多个范围?span style="BACKGROUND: highlight; COLOR: highlighttext">数据分区上实?span style="BACKGROUND: highlight; COLOR: highlighttext">数据分区
消除Q即Q一h?#8220;?#8221;QORQ运)。通过使用上一个示例中创徏的表Q执行下列查询:(x)SELECT * FROM sales WHERE (year = 2001 AND month <= 3) OR (year = 2002 and month >= 10)
数据库服务器只访?2001 q的W一季度?2002 q的最后一个季度的数据?/p>
可以生成列用作表分区键?/p>
例如Q可以发Z下语句:(x)
CREATE TABLE sales(a INT, b INT GENERATED ALWAYS AS (a / 5)) IN ts1,ts2,ts3,ts4,ts5,ts6,ts7,ts8,ts9,ts10 PARTITION BY RANGE(b) (STARTING FROM (0) ENDING AT(1000) EVERY (50))
在此CZ中,生成列上的谓词用于数据分区消除。此外,当用来生成列的表辑ּ是单调的Ӟ数据库服务器?x)将源列上的谓词转换为生成列上的谓词Q从而在生成列上启用数据分区消除?/span>
例如Q如果具有以下查询:(x)
SELECT * FROM sales WHERE a > 35
数据库服务器Ҏ(gu)Qa > 35Q在 bQb > 7Q上生成额外谓词Q从而允?span style="BACKGROUND: highlight; COLOR: highlighttext">数据分区消除?/span>
如果连接谓词下推到表访问别,则也可以?span style="BACKGROUND: highlight; COLOR: highlighttext">数据分区消除中用连接谓词。连接谓词仅在嵌套@环连接(NLJNQ的内部才下推到表访问别?/span>
误虑下列表:(x)
CREATE TABLE T1(A INT, B INT) PARTITION BY RANGE(A, B) (STARTING FROM (1, 1) ENDING (1,10) IN ts1, ENDING (1,20) IN ts2, ENDING (2,10) IN ts3, ENDING (2,20) IN ts4, ENDING (3,10) IN ts5, ENDING (3,20) IN ts6, ENDING (4,10) IN ts7, ENDING (4,20) IN ts8) CREATE TABLE T2 (A INT, B INT)
使用的谓词有Q?
P1: T1.A = T2.A P2: T1.B > 15
在此CZ中,׃不知道连接的外|因此不能定在~译时访问的额外数据分区。在q种情况下,以及(qing)在用主变量或参数标记的情况下,当绑定必需的值时Q就?x)发?span style="BACKGROUND: highlight; COLOR: highlighttext">数据分区消除?/span>
在运行时Q当 T1 ?NLJN 的内部表Ӟ?x)根?T2.A 的每个外值的谓词自动q行数据分区消除。在q行Ӟ对外?T2.A = 3 应用谓词 T1.A = 3 ?T1.B > 15Q这样就限定了访问的表空?ts6 ?ts7 中的数据分区?/span>
考虑?T1 ?T2 中的?A h下列|(x)
外部?T2Q列 A | 内部?T1Q列 A | 内部?T1Q列 B | 内部?T1Q?span style="BACKGROUND: highlight; COLOR: highlighttext">数据分区位置 |
---|---|---|---|
2 | 3 | 20 | ts6 |
3 | 2 | 10 | ts3 |
3 | 2 | 18 | ts4 |
3 | 15 | ts6 | |
1 | 40 | ts3 |
要执行嵌套@环连接(假定对内部表q行表扫描)Q数据库理器执行下列步骤:(x)
1?nbsp;在创?/span>table时可以选择table Partition 需要先创徏对应的表I间。后指定table Partition的范_(d)(x)
CONNECT TO TESTDPF;
CREATE TABLE WANGDH.TABLEPARTITIONTEST ( ID INTEGER NOT NULL , TEST BIGINT NOT NULL , CONSTRAINT CC1187661638203 PRIMARY KEY ( ID) ) PARTITION BY RANGE (ID NULLS LAST) (PARTITION PAR1 STARTING FROM (0) INCLUSIVE ENDING AT (10) INCLUSIVE IN PARTITION1 ) IN PARTITION1 CYCLE ;
CONNECT RESET;
2?nbsp;q加table partition 旉要先建立table space 。然后再在对应的table space 上徏?/span>partition
一?span> 建立table space Q?/span>
create large tablespace par2 pagesize 4K managed by automatic storage extentsize 16 overhead 10.5 prefetchsize 16;
NodeQ?/span>
创徏?/span>table space 需要选择cd为:(x)large Q大型)
二?span> 使用add table partition 增加table partition:
alter table tablepartitiontest add partition PAR2 starting from (11) inclusive ending at (20) exclusive in PAR2
可选择partition的范围?/span>Inclusive Q包?/span> exclusiveQ不包含
通过以上两种方式可在table层面上徏?/span>table partition 从而达到数据库中数据隔ȝ要求?/span>
调用程的代码是通过LocalBusinessFlowManager的callҎ(gu)。方法的单说明如下:(x)
public ClientObjectWrapper call(java.lang.String processTemplateName, ClientObjectWrapper inputMessage)Q?/pre>因此Q我们需要构Z个代表输入参数的ClientOjbectWrapper。生成一个代表输入参数的ClientObjectWrapper有多U方式,q里采用先构Z个DataObjectQ然后调用ClientObjectWrapper构造方法的方式。具体代码实现如下:(x)
ServiceManager serviceMgr = new ServiceManager(); BOFactory bofactory = (BOFactory)serviceMgr.locateService("com/ibm/websphere/bo/BOFactory"); DataObject input = bofactory.createByElement("http://HelloWorld/HelloWorldInterface", "hello"); input.setString("helloInput", msg); ClientObjectWrapper inputWrapper = new ClientObjectWrapper(input); |
BOFactory的createByElementҎ(gu)程的WSDL接口生成一个代表参数的一个DataObject。在生成代表输入的ClientObjectWrapper之后Q调用流E就变得相对比较单,具体代码片断如下Q?/p>
ClientObjectWrapper outputWrapper = mgr.call("HelloWorldProcess", inputWrapper); DataObject output = (DataObject) outputWrapper.getObject(); resp = output.getString("helloOutput"); |