总的来说,高级数据库课程分为分布式数据库和面向对象数据库两块。分布式数据库介绍了分布式数据库的方方面面,包括数据库系统的设计、查询处理优化、事务管理和恢复、并发控制、可靠性、安全性与目录管理等。面向对象数据库基本上回顾了OO的方方面面,只是结合数据库的背景进行详细分析,无特别之处。Project基本就是搞笑的,题目也不知道用了多少年从古至今(据说最早01年就开始用这个题目,不知真假但至少有六七年历史)。而Versant数据库这个题目本身就是结合OO思想设计表结构,将表结构持久化到Versant数据库,然后结合B/S架构(JSP写前台,Versant数据库,Java写逻辑)处理方式,从数据库中读取数据(增删改查),写数据到数据库,无他。迫于还有两门课(组合数学和算法设计分析)复习压力,后面想办法再解决Project报告。
课程本身枯燥无味(其实某些算法还是挺有意思,像基本时间戳调度、多版本时间戳调度、2PC、2PL、3PC和SDD-1半连接优化计算),只是从上课内容没看出任何高级的地方。不止一次在朋友圈吐槽了这门课(其实是这类),连自己都快麻木。在讲者赶时间赶进度、做任务(几乎不与听者沟通交流)式的教学方式下,本身就很枯燥的课程更让听者反感至极。讲者高高在上,一味争取完成填鸭式教学任务而忽略课程体系结构本身以及背景的探讨、介绍(根本无视课程背景介绍的重要性以及听者的学习感受,开始-结束-开始-结束-…)。讲者不是心有余而力不足(有意识传道授业但方法和讲课技巧能力有限),而是彻底走自己的路,听者爱听不听。这些导致的结果是听者囫囵吞枣,讲者完成任务,大部分概念都只是在几天里突击被记了个皮毛,而得不到深入理解更不谈具体应用,我相信忘得肯定比记的快。
有一种似曾相似的感觉,为了考试死记硬背,为了下一门考试再清空记忆,再重头开始然后循环。我甚至相信没在课上学过这些会更好1,至少我不会讨厌这类课。这是种糟糕并且被我痛恶的感觉,我只是希望目前的教育方式2能有所改观,我只是希望能学以致用。我在试着改变自己,更深的体会后面再细聊或者参考链接。
下面给出试卷的回忆
面向对象数据库部分:
一、语句的含义(不一定完全准确,大概是这样) 15分
(1)、persistent declare distance :vertex,vertex ->float
(2)、persistent declare mirror :Cuboid || vertex,vertex,vertex->void
(3)、declare marry :person || person -> void
refine declare marry :Employee || person -> void
(4)、 ploymorph declare ...
(5)、 ploymorph overload select (\t1 <= {\t2}) : \t1 || (\t2->bool) -> \t1
二、设计题 15分
(1)动物、哺乳、非哺乳、灵长类、非灵长类、人、猩猩的抽象结构图,自行车、支架、
车把、车轮、轮圈、轮辐等的抽象结构图
(2)写出(1)的类,人类的行为:吃食物、结婚;猩猩的行为:跳越、吃事物, 属性自定
(不要怀疑你的眼睛,题目跟那位学长提供的是一样的,千真万确~)
分布式数据库部分
三、简答题 30分
1、什么叫同构同质DDB、异构DDB,举例说明。
2、分段的意义,分段的原则。
3、可靠性的协议的内容。
4、什么叫"下读"、"上写"。
5、2PC的控制类型,简要说明特点。
四、用SDD-1算法计算半连接的代价、执行站点。15分
题目是作业原题,分布式数据库系统习题3.7
五、时间戳调度 10分
给出一系列读写申请,描述动作发生情况,具体来说,比如RTM=20,WTM=25,
<R(x), 19>
<R(x), 22>
<W(x), 21>
<W(x), 28>
六、描述2PL,解释在什么情况下引入ROWA,并描述其算法。 15分
答案就不给了,毕竟自己学的比较烂,而且题目不难,仔细复习都可以找到答案。
由于要做数据库的课程设计,所以要学习使用versant,并且把多年没碰过的eclipse也再捡起来。在这里做一点小小的记录,让自己以后少走弯路吧。
1.1. Create a Database(创建数据库)
1.Make the database directory(创建数据库目录)
The first step in creating a new database is to create a subdirectory for it under the Versant root database directory. You do this with the Versant utility makedb. To create the database directory for the databasetutdb, run the makedb utility with the database name as argument.
makedb tutdb
This creates a subdirectory, owned by you, under the Versant root database directory. To see the location of this root directory, use the oscp utility.
oscp -d
(在Versant的根目录下建立一个数据库目录,使用Versant的makedb语句。查看Versant的根目录使用oscp语句)
2.Create the database structure(创建数据库结构)
Now you can create the database in the newly created database directory. To create the database, use the createdb utility.
createdb tutdb
This creates the storage structure and log files for the database system in the database directory tutdb.
(在新创建的数据库目录下建立数据库,创建数据库使用createdb语句)
1.2 Create a Persistence Capable Class(创建持久型类)To create a Java class for persistent objects, first write the .java source code file as usual. No changes are necessary to allow objects of this class to be stored in the database. These changes will be done automatically for you in the enhancement process.( 通常首先写.java源文件为持久型的对象创建一个java类。不需要你做一些更改实现对类的象来在数据库中存储,在 enhancement进程中将自动实现更改。)
Our first examples will use a Person class, which is included in the tutorial directory. To indicate that instances of Person are persistent objects, a corresponding line will be added to the configuration file that is read during the enhancement process. (为了表示一个Person类的实例是持久型的对象,一行对应的代码将被加到配置文件中,他将在enhancement进程中读出。)This will be described in greater detail in the section on enhancement.
TUT/src/tutorial/model/Person.java
package tutorial.model;
public class Person {
public String name;
public int age;
public Person(String aName, int anAge) {
name = aName;
age = anAge;
}
public String toString() {
return "Person: " + name + " age: " + age;
}
}
In the Person class above the name and age attributes have not been hidden with the
private or protected access modifiers. Although not allowing publicly accessible fields
is often considered standard object-oriented programming practice, this would only serve to
complicate the example and distract from the main concepts being illustrated.
1.3. Create an Application(创建一个应用)
Our first example application will simply create instances of the Person class. The sample application makes a persistent object using the following process.
• Connect to the database and start a transaction by creating a new TransSession object.
• Create a new instance of class Person as usual using the new operator.
• Commit the transaction by ending the session.
(用三步实现一个持久型对象
1、建立数据库连接并通过创建一个TransSession对象的启动一个连接
2、用new语句创建一个Person实例
3、提交事务结束会话)
TUT/src/tutorial/CreatePerson.java
package tutorial;
import com.versant.trans.*;//添加V/JVI Classes
import tutorial.model.*;
public class CreatePerson {
public static void main(String[] args) {
/* if (args.length != 3) {
System.out.println("Usage: java CreatePerson <database> <name> <age>");
System.exit(1);
}*/
String database = "tutdb";
String name = "Jerry";
int age = 23;
TransSession session = new TransSession(database);
Person person = new Person(name, age);
session.makePersistent(person);
//先把这句屏蔽了,编译,然后enhance,然后再去掉屏蔽,然后在编译一次。
session.endSession ();
}
}
解释:
Import V/JVI Classes
In the example application, the V/JVI class TransSession is used. To import this class into the
namespace of the application program, use the Java import directive. This class is located in the V/JVI package com.versant.trans .
注意:import com.versant.trans.*;//添加V/JVI Classes
需要添加类库,参照以下
Afterwards reference the jar file jvi7.0.1-jdk1.4.jar as a user library to your projects build path. To do that right click on TUT in the package explorer and choose javaBuildPath|libraries|AddExternalArchives
Now choose the file as <VERSANT_ROOT>/lib/jvi7.0.1-jdk1.4.jar and click ok.
你会发现没有jvi7.0.1-jdk1.4.jar,那是因为这段话是在Versant7.0里的,没有更新啊!有木有,坑爹那,是jvi80.jar!
Start Database Session
Before any persistent objects can be created or accessed, you must connect to the database by starting a database session. Starting a database session initiates Versant processes that allow you to access Versant databases. You can use Versant database methods and persistent objects only within a session.
(在任何持久对象创建或者访问前必须通过启动一个数据库会话来连接数据库。启动一个数据库会话就会初始化Versant进程允许访问Vresant数据库。只有在一个会话中,才可以使用Versant的数据库的方法和持久对象。 )
In the V/JVI transparent binding, starting a database session is accomplished by creating a new instance of the TransSession class. The constructor for this class has two parameters, a set of properties and a session capability. Beginning a session can be controlled by several options. These options are set in the Properties object that is passed to the TransSession constructor. For now, we are only interested in one option, the name of the database. (For more information, on the available options when starting a session, please refer to section on the TransSession class in the Java Versant Interface Reference Manual.)
(在V/JVI中使用透明性机制,启动一个数据库会话是通过创建一个TransSession类的实例实现的。这个类的构造函数有两个参数,分别是一组属性和会话能力。开始一个会话是可以通过几个选项控制。这些选项在设置属性的对象时传递给TransSession构造函数。以上的实例我们只使用了一个数据库的名字选项。)
Start a Transaction
A logical JDO transaction is started and changes made to objects in the context of the transaction are saved when the transaction is commited.
pm.currentTransaction().commit();
Starting a database session also starts a short transaction. All changes to persistent objects are written to the database only if the transaction is successfully commited.
Create a Persistent Object
Since the Person class will be designated as a persistence capable class in the configuration file, no special code must be written to create persistent Person objects. Simply invoke(调用) the new operator as usual.
The TransSession.makePersistent() method causes the given object to be stored persistently in the database.
Commit the Transaction
Ending the session causes the active short transaction to commit. To commit a transaction without ending the session, use the TransSession.commit() method.
1.4. Compile the Java Classes(编译java类)
To compile the classes of a V/JVI application, simply invoke the Java compiler as usual. No special action needs to be taken. However, it is necessary to correctly set the CLASSPATH environment variable so that the V/JVI classes can be accessed by the compiler.
The V/JVI classes are located in a .jar file in the [VERSANT_ROOT]/lib release directory. The nameof this file depends on both the V/JVI and Java version numbers. For example, the .jar file for JVI 7.0.1with JDK 1.4 is named jvi7.0.1-jdk1.4.jar. Add the .jar file to your CLASSPATH environment variable.
In addition, it is necessary to add the directory containing the Java source files to your CLASSPATH. The exact method for setting CLASSPATH depends on the system being used. Please refer to your Java documentation for correctly setting CLASSPATH.
An Ant script is provided for this tutorial. To compile the Java classes using Ant, use the following
command-line calls.(本教程提供了一个Ant脚本。要使用Ant编译Java类,请使用以下命令行调用。)
cd TUT
ant clean
ant compile
1.5Enhance the Java Classes(加强java类)
Enhancement is where the "magic" of the Versant JVI transparence takes place. The enhancer is a post-processing utility that modifies your Java classes so that instances can be stored in the database. It also augments code that accesses these persistent objects so that they correctly interact with the database.
(加强器是一个后处理器,它修改Java类以实现实例在数据库中的存储。它同时声明代码能够实现持久对象,这样这些持久对象就可与数据库联系。)
The enhancer is termed a post-processor because it manipulates Java .class files, not .java source files.That is, the input to the enhancer is a set of compiled Java classes, because enhancement occurs after compilation. The output of the enhancer is a corresponding set of class files; but these classes have been modified to correctly work with Versant databases. Post-processing is feasible for two main reasons.
• Java .class files contain virtual machine language instructions that are independent of any one processor.Thus, the same .class files can be executed on different platforms. This means that the enhancer does not have to consider platform-specific details.
• The .class files have a relatively simple structure that make them easy to read and modify by utilities such as the enhancer.
(加强器之所以被成为后处理语句是因为它修改Java .class文件而不是java源文件。也就是说加强器的输入是编译过的Java类,因为加强语是在编译后。加强器的输出是一系列类文件,但是这些类已经被修改以适应于Versant数据库。后处理是可行的基于两个原因。
·Java .class文件包含独立于任何处理器的虚拟机语言指令。那么.class文件能够在不同的平台上执行。这就意味着加强器不需要考虑特定平台细节。
·.class文件是由相对简单的指令组成的,这就使得他们能被加强器容易的读取和修改
)
Although it actually does quite a bit more, the enhancer performs three main functions on its input .class files.
• The schema of the persistent classes is captured and code is generated to inform the database of this schema.
• Code is generated that moves objects from the database into Java memory and vice versa.
• Application code that accesses and modifies persistent objects is augmented to mark objects as dirty and fetch objects from the database, so that changes to these objects are written to the database when the transaction is committed.
(虽然实际上加强器做的工作比较堵,但它主要对输入的.class文件处理三个主要的功能:
·捕获持久化类的架构和生成代码来告知此架构的数据库。
·生成从数据库中移动对象到Java的内存的代码,反之亦然。
·增强的应用程序代码访问并修改持久对象标记为脏对象,并从数据库中提取的对象,当事务被提交时使这些对象的变化写入到数据库中。
)
A configuration file, usually named config.jvi, controls the behavior of the enhancer. This file specifies the persistence category of each of the classes that are being enhanced. The configuration file for the example application above is as follows.
c tutorial.model.Person
a tutorial.CreatePerson
n**
注意:
新建config.jvi时必须要配置eclipse,参考
<VERSANT_ROOT>\sdk\examples\jvi\IDE\eclipse\EclipseJVIPlugin文档,在第1页里有一段话
Follow the normal Eclipse software update procedures (from the Eclipse Help | Software Updates | Findand Install... menu) to install the Versant JVI plugins.
这段话写的很传神,但是你会发现你找不到Software Updates 这个选项,再一次华丽的碎了一地。参考
http://blog.sina.com.cn/s/blog_6d9ecdef0100n8cq.html
可以解决,然后照着做没有什么问题。
在第5页里Running the sample application这一段,如果你照着,那么恭喜你你再一次被耍了。你编译时会出错。因为上面讲的很清楚,你要先编译java类文件,然后才能enhance,对不对?在CreatePreson类中将下面的语句做一些处理。
session.makePersistent(person);
先把这句屏蔽了,编译,然后enhance(第5页里有详细说明),然后再去掉屏蔽,然后在编译一次。Enhance若成功后会在工程文件夹bin下生成相应的Pickler_Vj文件,如Preson类会在Person_Pickler_Vj文件
category c.
The letter c indicates that the class (in the example, the tutorial.model.Person class)
is categorized as persistence capable. This means that objects of the class can be stored in the Versant database and the enhancer will modify the class so that persistence is possible.
(c 表示这个类被标示为持久的。也就是能在Versant数据库中存储和被加强器将要修改的类以实现持久性。)
category a. In the configuration file, the letter a indicates that a class is persistence aware. In the example,the CreatePerson class, is persistence aware. This means that CreatePerson instances will not be stored in the database but that the methods of class CreatePerson will be augmented to correctly work with other persistent objects, such as Person objects.
(a表示这个类不会被Versant存储,但能够与持久对象一起协同工作的类。)
category n. The letter n indicates that the class should not be enhanced and n** means that the classes that have not been categorized with a or c will not be enhanced.
(n,n**表示这些类不会被加强)
The configuration file supplied with the V/JVI installation has already been updated to work
with this and the following examples. The configuration file is located in
[VERSANT_ROOT]/sdk/examples/jvi/tutorial/src/config.jvi.
The enhancer looks for .class files in an input directory and writes the modified .class files in an output directory. These two directories are specified on the command line when the enhancer is executed. The input directory is the top of the package hierarchy for all of the classes comprising the V/JVI application. After the enhancer is run, the output directory mimics the structure of the input directory. The input and output directories for the tutorial examples can be found in your V/JVI installation as the TUT/src/ and TUT/build/ directories.
To enhance the Java classes, you can use the supplied Ant script.
cd TUT
ant enhance
Afterwards, the build directory will contain the enhanced .class files as well as additional files with names ending in Pickler_Vj.class. These classes assist in making the model objects persistent.
1.6. Run the Application(运行程序)
To run the sample application, simply invoke the Java interpreter as usual. However, it is very important to include the directory containing the enhanced .class files in the CLASSPATH. Failure to do so will result in run-time errors.
In addition, since the V/JVI libraries are implemented using native methods (functions written in the C language), the operating system must be able to locate the Versant dynamic-link libraries. These are located in the [VERSANT_ROOT]/lib/ subdirectory of your V/JVI installation. On UNIX machines, this directory is normally added to your LD_LIBRARY_PATH environment variable. On Windows machines, this directory must be added to your PATH.
To execute the CreatePerson application.
ant runCreatePerson
The above command adds a single Person object to the tutdb database, with name Bob and age 28. This can be seen using the Versant db2tty utility.
db2tty -d tutdb -i tutorial.model.Person
For more information, on the db2tty utility refer to the Versant Database Administration Manual
终于成功了,有木有?
db2tty -d tutdb -i tutorial.model.Person
Accessing Objects(访问对象,推荐用第2种方法)
There are two basic ways of finding existing objects in the database, with roots or with queries. Once a persistent object has been found by either of these two methods its fields can be read and modified and its methods can be invoked. Any changes made will be written back to the database at the next transaction commit.
(有两种基本的方法可以实现在数据库中查询对象,通过根或者查询。一旦一个持久对象被任意这两种方法访问,它的域可以被访问和修改并且它的方法可以被调用。任何修改都可以在下一个提交事件被写会数据库。)
2.1. Finding Objects with Roots(通过根访问对象)
A root is a persistent object that has been given a name. This name can be used to find the object later. A root name is a bit like a file name although the system of roots in V/JVI is much simpler than a true file system. In particular, there is one space for root names in each database.
(一个根是一个被命名的持久对象。可以使用这个名字,以后找对象。实际上在每个数据库中都名为根留下空间。 )
Root names should be applied to only a relatively small number of objects in a database. Many database applications have complex, connected graphs of objects. A root provides a simple starting point for these graphs.
(在数据库中根名字仅用于一些相对较少数目的对象。许多数据库应用程序有复杂,对象连接图。根为这些图表提供了一个简单的出发点。)
There are three fundamental root operations.
• Making a new root by giving an object a name.
• Finding an object with a given root name.
• Deleting a root name.
(有三种基本的根操作:
·为一个对象赋名创建一个新的根
·通过跟名字查找一个对象
·删除一个跟名字
)
First, let's make a new root by giving a name to an object. The following example application,
CreatePersonWithRoot, creates a new Person object and gives it a root name.
TUT/src/tutorial/CreatePersonWithRoot.java
package tutorial;
import com.versant.trans.*;
import tutorial.model.*;
public class CreatePerson{
public static void main(String[] args) {
/*if (args.length != 4) {
System.out.println ("Usage: java CreatePersonWithRoot" +
"<database> <name> <age> <root>");
System.exit(1);
}*/
String database = "tutdb";
String name = "Mary";
int age = 20;
String root ="root";
TransSession session = new TransSession(database);
Person person = new Person(name, age);
session.makeRoot(root, person);
session.endSession();
TransSession session1 = new TransSession(database);
Person p = (Person) session1.findRoot(root);
System.out.println("Found " + p);
session1.endSession();
}
}
2.2. Finding Objects with Queries
Versant provides a query language, VQL, to search for persistent objects that match certain criteria. V/JVI supports simple VQL queries. These queries can be used to find objects that have been stored in the database.
(For more information refer the chapter Fundamental JVI, section VQL Queries in the Java VERSANT Interface Usage Manual.)
(Versant提供一个查询语言VQL,搜索符合特定条件的持久对象。)
The following program finds all Person objects located in a database.
package tutorial;
import java.util.*;
import com.versant.trans.*;
import tutorial.model.*;
public class CreatePerson {
public static void main (String[] args) {
/*if (args.length != 1) {
System.out.println(
"Usage: java FindPersonWithVQL <database>");
System.exit(1);
}*/
String database = "tutdb";
TransSession session = new TransSession(database);
VQLQuery query = new VQLQuery(session,
"select selfoid from tutorial.model.Person");
//此处使用的是VQL查询语言见D:\Versant\8\doc\VODFundamentals 18章
Enumeration e = query.execute();
while (e.hasMoreElements()) {
Person person = (Person) e.nextElement();
System.out.println("Found " + person);
}
session.endSession();
}
}
Finding all Person objects proceeds in three steps.
• First, the query object is constructed with a query that means " find all objects from the Person class".
• Next, the query is executed. This tells the Versant database to find the matching objects.
• Finally, the matching objects are fetched from the database using an instance of the Java interface java.util.Enumeration. The enumeration provides restricted access to a sequence of objects so that the objects are not retrieved from their database until explicitly demanded by the application program with the nextElement() method.
(查找所有的Person对象需要三步:
·首先,查询对象的构造使用一个查询语句,这意味着"找到Person类中的所有对象"
·其次,执行查询语句。这就通知Versant数据库去查找匹配的对象。
·最后,通过Java接口java.util.Enumeration(枚举)的一个实例将匹配的对象从数据库中取出。枚举提供受限制的访问使对象使用nextElement()方法的应用程序不会从他们的数据库被检索直到明确要求的对象序列。 )
Execute the FindPersonWithVQL application with Ant.
ant runFindPersonWithVQL
Running the application gives the following output.
Chapter 3. Changing Persistent
Objects(更改持久对象 )
This example shows how to modify persistent objects.
Like the previous program, it finds all Person objects in a database. This time, however, instead of simply displaying the contents of the object, the age of each Person object is increased by one. After all, we are all getting older every year!
TUT/src/tutorial/IncreaseAge.java
package tutorial;
import java.util.*;
import com.versant.trans.*;
import tutorial.model.*;
public class CreatePerson {
public static void main(String[] args) {
/*if (args.length != 1) {
System.out.println(
"Usage: java IncreaseAge <database>");
System.exit(1); Person a=new Person("",1);
}*/
String database = "tutdb";
TransSession session = new TransSession(database);
VQLQuery query = new VQLQuery(session,
"select selfoid from tutorial.model.Person");
Enumeration e = query.execute();
while (e.hasMoreElements()) {
Person person = (Person) e.nextElement();
person.age++;
System.out.println("Increasing " + person.name +"'s age to " + person.age);
}
session.endSession();
}
}
Chapter4.Deleting Persistent Objects(删除持久对象)
Persistent objects in a Versant database remain in the database until explicitly deleted. To delete objects from a database, use the TransSession.deleteObject() method.
The following points must be kept in mind when deleting objects from the database.
•If the server profile parameter commit_delete is OFF this function will send the delete
request to the source database and the object is deleted immediately.
• If commit_delete is ON this function will acquire a Write Lock on the object and set its
status as "Marked for deletion". The object will be physically deleted during transaction
commit. If a rollback occurs, these objects are un-marked and their status restored.
• Queries run on the database will not include objects marked for deletion in the result sets.
(1如果服务器配置参数commit_delete关闭这个功能会将删除请求发送到源数据库中对象将被立即删除。
2如果commit_delete打开这个函数将获得一个写锁定的对象并设置其作为"标记为删除"。在事件的提交对象将被删除。如果一个重复发生,这些对象将无标记和他们的状态将恢复。
3对数据库的查询不包括对象标记为删除的结果集。
)
The following program will delete an object with a given root name.
TUT/src/tutorial/DeletePersonWithRoot.java
package tutorial;
import com.versant.trans.*;
import tutorial.model.*;
public class DeletePersonWithRoot {
public static void main(String[] args) {
if (args.length != 2) {
System.out.println(
"Usage: java DeletePersonWithRoot <database> <root>");
System.exit(1);
}
String database = args[0];
String root = args[1];
TransSession session = new TransSession(database);
Person person = (Person) session.findRoot(root);
session.deleteObject(person);
session.endSession();
}
}
Unlike C++, Java does not support a delete operation for dynamically allocated objects. Instead, Java relies on garbage collection to rid memory of unreferenced objects. Therefore, the deleteObject() method deletes the persistent object from the database only, not from memory! After deletion, the object in memory should not be accessed. The object will be deleted from the database at transaction commit. Deleting an object is not the same as deleting a root. Deleting a root simply removes the root name associated
with the object and does not delete the object from the database.
Execute the DeletePersonWithRoot application with ant runDeletePersonWithRoot.
Running the same program a second time generates an exception because the object was deleted from the database and the root name removed.
Chapter 5. Using Links
In a Versant database, a link is a reference within a persistent object to another persistent object. A link is essentially an attribute that contains the LOID (logical object idetifier) of a persistent object. A Versant link is analogous to a pointer or reference in a programming language. In fact, the analogy is so strong that links are implemented as normal Java references in V/JVI.
(在Versant数据库中,一个连接联系着两个持久对象。一个连接是本质上是属性,包含一个持久化对象的LOID(逻辑对象idetifier)。一个Versant连接很像编程语言的一个指针或者是一个引用 。实际上,这种比喻是形象的,连接在V / JV中当做普通JavaI引用链接。 )
Links are extremely easy to use. You simply define your classes in exactly the same way that you would when writing a normal, non-database, Java application. The enhancer takes care of all of the work of converting references to links and fetching objects from the database when they are accessed.
(连接相对比较容易用。你可以像其他普通的非数据库引用程序以比较比较简单的方式定义类。加强器处理所有相关的连接和从数据库中取对象的工作。)
To illustrate how links work in a V/JVI transparent persistence application, we will use simple Employee and Department classes. The Employee class contains a reference to the Department class so that each employee belongs to one department. Similarly, the Department class contains a reference to the Employee class so that one employee manages each department.
TUT/src/tutorial/model/Employee.java
package tutorial.model;
public class Employee extends Person {
public Department department;
public double salary;
public Employee(String aName, int anAge, double aSalary) {
super(aName, anAge);
salary = aSalary;
}
public String toString() {
return "Employee: " + name + " age: " + age +" salary: " + salary + " " + department;
}
}
TUT/src/tutorial/model/Department.java
package tutorial.model;
public class Department {
String name;
Employee manager;
public Department(String aName, Employee aManager) {
name = aName;
manager = aManager;
}
public String toString() {
return "Department: " + name + " manager: " +((manager != null) ? manager.name : "nobody");
}
}
The following application creates some Employee objects and stores them in the database.
TUT/src/tutorial/CreateEmployee.java
package tutorial;
import java.util.Enumeration;
import com.versant.trans.*;
import tutorial.model.*;
public class CreateEmployee {
public static void main(String[] args) {
String database = "tutdb";
TransSession session = new TransSession(database);
Employee the_boss = new Employee("The Boss", 42, 110000);
Employee jane_jones = new Employee("Jane Jones", 24, 80000);
Employee john_doe = new Employee("John Doe", 25, 75000);
Employee lois_line = new Employee("Lois Line", 36, 70000);
Department engineering = new Department("Engineering", the_boss);
Department marketing = new Department("Marketing", lois_line);
the_boss.department = engineering;
jane_jones.department = engineering;
john_doe.department = marketing;
lois_line.department = marketing;
session.makePersistent(the_boss);
session.makePersistent(jane_jones);
session.makePersistent(john_doe);
session.makePersistent(lois_line);
session.makePersistent(engineering);
session.makePersistent(marketing);
VQLQuery query = new VQLQuery(session,
"select selfoid from tutorial.model.Person");
//此处使用的是VQL查询语言见D:\Versant\8\doc\VODFundamentals 18章
Enumeration e = query.execute();
while (e.hasMoreElements()) {
Person person = (Person) e.nextElement();
System.out.println("Found " + person);
}
session.endSession();
}
}
Chapter6.Transitive Persistence(过渡持久性)
So far you have seen just one way of storing objects persistently in the Versant database. That is, explicitly calling makePersistent() or makeRoot(). However, an object of a persistence capable class can also become persistent through a mechanism called transitive persistence. If a persistence capable object is referenced in a persistent object, it too becomes persistent.
To illustrate the concepts of persistence capable classes and transitive persistence we will use the following simple LinkedList class.
TUT/src/tutorial/LinkedList.java
package tutorial.model;
public class LinkedList {
int label;
LinkedList next_node;
public LinkedList(int aLabel, LinkedList list) {
label = aLabel;
next_node = list;
}
public String toString() {
return label + ((next_node == null) ? "" : " " + next_node);
}
}
Now consider the following application which creates a linked list.
TUT/src/tutorial/CreateLinkedList.java
package tutorial;
import com.versant.trans.*;
import tutorial.model.*;
public class CreateLinkedList {
public static void main(String[] args) {
if (args.length != 1 && args.length != 2) {
System.out.println(
"Usage: java CreateLinkedList <database> [root]");
System.exit(1);
}
String database = args[0];
String root = (args.length == 2) ? args[1] : null;
TransSession session = new TransSession(database);
LinkedList list = null;
for (int i = 0; i < 5; i++)
list = new LinkedList(i, list);
if (root != null)
session.makeRoot(root, list);
session.endSession();
}
}
This application creates, in memory, a linked list with five nodes labeled from 4 down to 0. The program takes an optional second command-line argument, the root name. If the root name is given, then the head of the linked list is made persistent by the makeRoot() method. On the other hand, if the optional argument is not given none of the linked list nodes are made persistent.
To execute the CreateLinkedList application without a root name, run ant runCreateLinkedList.
By using the db2tty utility you can see that there are no LinkedList objects in the database.
db2tty -d tutdb -i tutorial.model.LinkedList
Now run the same application, this time with a root name, with the command
Ant runCreateLinkedListWithRoot.
Now the db2tty utility will show the five LinkedList nodes in the database. You can also see them with the following application.
TUT/src/tutorial/FindLinkedList.java
package tutorial;
import com.versant.trans.*;
import tutorial.model.*;
public class FindLinkedList {
public static void main(String[] args) {
if (args.length != 2) {
System.out.println(
"Usage: java FindLinkedList <database> <root>");
System.exit(1);
}
String database = args[0];
String root = args[1];
TransSession session = new TransSession(database);
LinkedList list = (LinkedList) session.findRoot(root);
System.out.println("Found List: " + list);
session.endSession ();
}
}
Execute the FindLinkedList application with ant runFindLinkedList. This will display the following.
Found List: 4 3 2 1 0
This means that even though only a single object was explicitly made persistent (by the makeRoot()method), five objects were actually persistently stored in the database. The reason is transitive persistence.Since the head of the linked list, node 4, is persistent and contains a link to node 3, node 3 is transitively persistent as well. In addition, since node 3 is persistent and contains a link to node 2, node 2 is persistent,and so on.
While this example demonstrates a very simple form of transitive persistence, where the linked objects were arranged in a regular, linear form, transitive persistence will apply to much more complicated linked structures as well. Any object of a persistence capable class becomes persistent if it can be reached from a persistent object by following links.
Chapter 7. Second Class Objects(第2类对象,内部类)
All of the objects that you have seen in this tutorial are first class objects. This means that the Versant database recognizes them as individual objects and has assigned a LOID to each one that is stored in the database.However, V/JVI supports another kind of persistent object, the second class object or SCO. A second class object cannot exist in the database in its own right, it must exist as an attribute of a first class object. The second class object is in some sense subordinate to a first class object. This first class object is sometimes referred to as the owner of the SCO. Each SCO can have only one owner.
Second class objects use the Java serialization(串行) mechanism to achieve persistent storage. Serialization turns an object into a byte stream, that is, an array or sequence of bytes that can be deserialized to reconstitute the object(反序列化重组 ). There is a tradeoff involved in using first class or second class objects. First class objects require more database overhead since the database has to handle each separately. (第一类对象需要更多的数据库的开销,因为数据库已经分别处理。)Second class objects, on the other hand, do not work easily with database queries (since the database has no knowledge of the Java serialization format)and involve some extra runtime serialization overhead. In addition, SCOs cannot be shared between first class objects because each SCO can have only one owner.
Fortunately, other than the restriction on sharing SCOs, you do not have to change the way in which you write your Java programs to determine if the tradeoffs(权衡) are beneficial or harmful to the performance of your application. Only the configuration file need be changed.
As a simple example of using SCOs, consider the following Friend and Address classes. Each of your friends has an address, but you might not want these addresses to occupy their own object in the database because the Address class is really just a way of grouping related information so that it can be dealt with at once in your application program.
To indicate that the instances of the Address class should be second class objects, mark this class as category d in the configuration file.
c Friend
d Address
(The d stands for dependent, an alternate way of saying the object is second class.)
public class Friend extends Person {
String phone_number;
Address address;
}
Address.java
public class Address {
String street;
String city;
String state;
int zip_code;
}
Now, whenever a Friend object is written to the database, the Address object will be serialized along with it. If you change the category from d to p (always persistent) or c (persistence capable), your application will behave in the same way, only the representation in the database will change.
总结:
1创建数据库
在Versant的根目录下建立一个数据库目录,使用Versant的makedb语句。查看Versant的根目录使用oscp语句。然后创建数据库
makedb mydbname
createdb mydbname
2创建持久型类三步骤:
1)建立数据库连接并通过创建一个TransSession对象的启动一个连接
2)用new语句创建一个类实例
3)提交事务结束会话
String database = "mydb";
String name = "Jerry";
int age = 23;
TransSession session = new TransSession(database);
Person person = new Person(name, age);
session.makePersistent(person);
//先把这句屏蔽了,编译,然后enhance,然后再去掉屏蔽,然后在编译一次。
session.endSession ();
3Enhance the Java Classes
A configuration file, usually named config.jvi, controls the behavior of the enhancer. This file specifies the persistence category of each of the classes that are being enhanced. The configuration file for the example application above is as follows.
c tutorial.model.Person
a tutorial.CreatePerson
4访问对象
Person person = new Person(name, age);
session.makeRoot(root, person);
session.endSession();
TransSession session1 = new TransSession(database);
Person p = (Person) session1.findRoot(root);
System.out.println("Found " + p);
session1.endSession();
2)Finding Objects with Queries
TransSession session = new TransSession(database);
VQLQuery query = new VQLQuery(session,
"select selfoid from tutorial.model.Person");
//此处使用的是VQL查询语言见D:\Versant\8\doc\VODFundamentals 18章
Enumeration e = query.execute();
while (e.hasMoreElements()) {
Person person = (Person) e.nextElement();
System.out.println("Found " + person);
}
session.endSession();
}