Java data object technology
(Sun Bin Translation)
(The copyright of this translation is the author. For the purpose of communication, you must be reproduced, but you must indicate the source and original people! If you are interested in the book, and hope to see the Chinese translation of the book, please to O'Reilly China Publishing House email your opinion and comments: info@mail.oreilly.com.cn)
Foreword
Java Data Objects (JDO) is an important innovation in the Java platform. When developers are also in general using JDBC access to the database, when the expert group from some large enterprises, Craig Russell and David Jordan have courage to explore another road when designing and advocating EJB and CMP API. . Together with other supporters, they find simple ways to provide storage mechanisms on the Java platform, which is natural and convenient to programmers. This book describes their research results: JDO.
The core idea of JDO is to provide a Java-oriented database storage mechanism without increasing the additional work of programmers. The programmer does not need to learn SQL, nor does it need to be very troublesome to copy data from the Java object to the database or from the JDBC, they only need to use the Java class, attributes, and objects between the natural idea, and If you don't have to write a lot of code, those code will make people halo. Even for queries, programmers can use Java's Boolean expressions (ie, judgment comparison expressions) instead of SQL. In other words, the programmer only writes Java code, and storage is automatically implemented.
In addition to transparent storage, the code written by JDO is binary compatibility, which can cross the platform, cross the database. JDO can be used for object / relational database mapping, which automatically generates JDBC calls to automatically correspond to the data in the Java object and relational database. In addition, JDO objects can also be saved directly into the file to achieve the same functions and performance as the object database.
Reported to JDO's hard work: The concept of transparent storage has been widely welcomed. JDO has its own community website: JDOCENTRAL.COM, as well as the enterprise-level Java discussion area: THESERVERSIDE.COM, in these media, developers praise the simple and practical use of JDO. Many developers have replaced EntityBean with JDO and use JDO data objects in SessionBean. Other developers use JDO as a convenient high-level JDBC substitute for JSP pages and other Java code. After I and Graham Hamilton defined JDBC interface in 1995, JDO has also experienced long-term development, which has been worth merged into J2EE.
Speaking of writing JDO books, I can only think of two most suitable candidates. Craig is a regulation leader of the JDO expert group, and Dave is one of the most active members in the expert group. Their qualifications are far beyond this group. On this basis, JDO is designed very practical. Both of them have more than ten years of research in programming language and data, including strict transaction semantics, multiple forms of storage models, object relationships, buffering efficiency, storage, and non-storage objects interaction, actual development code. Simple and more. They all worked in ODMG (subgroups of object data management teams, OMG) as a core member for many years. Most importantly, as developers, both people love and urgently need the functions provided by JDO. Craig and Dave have now collaborate with an incisive, easy-to-read and practical entry. I hope everyone will love it like me.
Rick Cattell, Deputy Software CTO Sun Microsystems, February 16, 2003
table of Contents
(Some terms can be found in the directory) 1. Preliminary Overview Defines the data object model to store classes to store classes to compile the class declaration as a stored project catalog structure enhancement class code to store Create Database Connection and transaction get a PersistenceManager Creating a FOSTORE database to save an instance of an instance to save an instance Access instance change instance delete instance summary
2. JDO Interface Overview Javax.jdo Package JDO-related exception javax.jdo.spi package (for JDO product developer) optional feature identifier features optional collection class transaction-related optional feature
3. JDO System JDO Appacts The Java Virtual Machine System SLRSISTENCEMANAGER Multi PersistenceManager Access the same database Multi PersistenceManager Access Different database shared JDO Product buffer database access Direct access file system or local database remote access a JDO server Remote Access a SQL Database JDO Application System System For JDO Applications in the JDO Fat Client Web Server on your local database, connect to Web Service's JDO App Connect to the Fat Client of Application Server with EJB Components, the web server containing the EJB server, using sessionbean as an external interface EJB SessionBean provides "Rand Control Storage - CMP" with JDO
4. Define Classification of Classification Class Class Class Class Class Class Class Class Class Java Class and Metadata (Metadata) JDO Metadata Inherits Media Mania's object model Property Support type Property Storage Media Mania Model's Complete Metadata
5. Database mapping mode Build a model building in the Java and relationship model based on SQL 99, model builds to map classes to the table to map single-value attributes to field name mapping type mapping index identity inheritance reference collection and relationship Adoption of foreign key adopt table (JOIN TABLE) One-on-one Relational Mark List (LIST) and Mapping (MAP)
6. Class Enhancement Enhancement Reference Reinforced Binary Compatibility Reinforced Binary Compatibility Reinforced Binary Compatibility Reinforced Binary Compatibility Reinforced Data Attribute Adjustment
7. Create a JDO Run Environment Configuration PersistenceManagerFactory Connection Parameter Sign Multiple Instances Settings Defines Optional Signs and Default Settings with Specific Vendors Uncountable Parameters Get the PersistenceManager User Object Close PersistenceManager Close PersistenceManager Factory Transaction Parameter transactions and database locking JDO transaction types Get a transaction Settings Transaction Type Transaction Rolling Rolling Data Recovery View Transactions Whether PersistenceManager Multithow
8. Instance Management Instance Storage Explicit Save Repalatability Storage Class Extended Access Access A Class Extension Class Extended Traversal Ignore Buffer Access and Update Instance Explicit Delete Extension
9. JDO Query Language Query Components Create and Initialize the Name Space Type Attribute, Parameters, and Variable Name Keyword Identifies in Query Inquiry in Query Square Inquiry Declaration Executive Query Precommination Query Query Filter Condition Expression Features The operator in the query references the set query result closes Query 10. Object identity Overview of the identity type metadata identification class database identifier Applications Identifier Property Type Can Store Equals () and havehcode () Method application ID class Single property master key composite primary key with foreign bond composite primary key inheritance system acquisition Identifier Identifier related method acquisition identification class acquisition instance identifier obtaining an instance of an instance of an instance obtaining an instance of the current application identification identifier identifier String Form Advanced Topic Selection Identification Type Adopted with the comparison of the query across the PersistenceManager
11. Status of data objects in the Life Cycle and the Status of Convert Life Cycles Transient (Temporal) Persistent-New Hollow (Space Mentality, Object Status Indications Other Object Status) Persistent-Clean (Net value state, representation Database consistency) Persistent-dirty (dirty data status, indicating that it has been changed but not synchronized to the database) Persistent-deleted (deleted) Persistent-new-deleted (new delete) status Review status conversion database transaction status conversion transaction Status between state conversion transactions
12. Property Management Transaction Related Attribute Null Value Properties Getting Default Access Group Gets Managing Serial Life Cycle Events in All Properties Attributes Management Serial Lifecycle Event Management One Class and Second Category Object Detects a two-class object embedded set element as a second class Storage class instance sharing
13. Buffer Management Refresh Instance Refresh Instances of Cushions Refresh Instances Abolition Instance Replication Support Transaction Temporary Instance Support Transaction Temporary Examples of Transactions Transaction The Substantial Signal Temporary Review
14. Non-affordable access to non-transactional methods Read the Persistent-Nontransactional status transaction to keep the data transaction after returning the data transaction, restore the stored instance Recovery Persistent-new instance Recovery Persistent-new instance Recovery Persistent-new instance Example
15. When the optimistic transaction is submitted, verify the state of the optimistic transaction in the failed business, the optimistic mode of optimistic translation, the instance of the optimistic mode, make the instance transaction change instance submit rollback
16. Web Server Environment Web Server Access PersistenceManagerFactory For the Request Services Each PersistenceManager requests a PersistenceManager for each transaction requesting a PersistenceManager Each Session, a PersistenceManager transaction J SP page struts and JDO
17. J2EE Application Server Enterprise JavaBean (EJB) Status SessionBean Configuring PersistenceManagerFactory Container Controlled Transaction The Status SessionBean Container Controlled Transaction The SESSIONBEAN Component Controlled Transaction Javax.Transaction.usertractions Javax.jdo.transAction Component Controlled Transaction SESSIONBEAN Component Controlled Transaction Situation SessionBean Message Components (Message-Driven Beans) Save Entities and JDO Local Storage Remote Storage Appendix
A. Lifecycle status and conversion
B. JDO metadata format DTD
C. JDO interface and exception class
D. JDO Query language BNF syntax
E. Source code for demonstration procedures
index
Glossary
Duration (Persistence, also data storage) represents the storage of data or objects. The so-called persistence, that is, the data or object can remain independent of the operating environment, such as the system crashed or reboot, the originally saved data is still lost with the end of the program or the reinitialization of the system. In general, the database is a typical persistent processing mechanism. Container Managed Persistence and Self-control Storage is a two kinds of implementation of entity bean (Entity Beans) in an Enterprise Java Component (EJB) technology, from the EJB container (ie J2EE server) ) To control the access to the data source is called a compliance storage (referred to as CMP), and the entity bean's own code is used to implement the data source access (referred to as BMP). See the EJB technical documentation for details. Managed Environment Indicates the environment that is constructed by the J2EE specification, which is built from different middleware products, and each application component is mutually called by JNDI (Java Name Tree Interface, Similar WINDOS). Such an environment is called a controlled environment JDO product (JDO Implementation, or referred to as product) is some middleware implemented by JDO specification, and the middleware manufacturer is designed and implemented in accordance with the JDO specification. PersistenceManager's most commonly used API interface classes in JDO technology, indicating that the storage, acquisition, and creation of the item is responsible for completing the object. The identity of PersistenceManager is equivalent to the Connection database connection in JDBC (actually a connection) PersistenceManagerFactory (Storage Manager Factory) This is a PersistenceManager's access to a PersistenceManager must be obtained from a PersistenceManagerFactory. Similar to javax.sql.datasource in JDBC in identity and status. Database (DATASTORE) indicates a system or mechanism that provides underlying storage for JDO, which is translated into "data bin" more accurate, but considers the reader's accepted level, or use "database" easier to accept, just reading this article Time, please note that not to talk to a relational database, a database (Datastore) mentioned in this article, including file storage mechanism, relational database, object database, network storage, LDAP, etc. can provide sustained storage management system metadata (Metadata) It is also possible to refer to a descriptor (especially in the EJB system), which is used to describe how Java classes mapped to a descriptive XML structured data in a specific database, indicating which classes need to be stored, and how to store details. In Java and related middleware, similar descriptions of the nature are called metadata, such as describing the ResultSet metadata of the query result set in the JDBC, is the field structure, size, etc. of the returned result record set.
Enhance enhanced enhancements to enhance the classes that need to be stored with the actual underlying data source, need to be translated and generated. Class files to carry out the transformation of binary code, join the code to deal with the underlying environment of the JDO product. This process of transformation of .Class files generally uses a tool, which is called enhancement, and this tool is generally provided by JDO product vendors, called an enhancer. Iterate also referred to repeated or traversal, indicating that the elements in an object set are sequentially accessed in a specific order. This is one of the core concepts of Java's Collection architecture. Chapter 1 Initial Overview
As a new language of the heeler protrusion, Java defines a standard operating environment, and user-defined classes are executed. An instance of these user-defined classes represents data in a real environment, including data stored in databases, files, or some large transaction systems, and small systems typically require a mechanism to control data storage locally.
Since data access technology is different in different data source types, the data is accessed into a challenge to program developers, and the programmer needs to use a specific programming interface for each type of data source (API) ), That is, at least two languages must be known based on these data source development services: Java language and data accessed by the data source. This data access language is generally different depending on the data source, which enhances the development cost of a certain data source.
Before Java Data Object Technology (JDO) is released, there are usually three ways to store Java data: serialization (ie, serialization, also known as serialization), CMP (container storage) mode in JDBC and EJB. Serialization is used to write a status of an object, and other object structures it point to, in an output stream (such as files, networks, etc.), which guarantees the relationship between the object written, In this way, at another moment, this object structure map can be reconscribed completely. However, serialization does not support transaction, query, or sharing data to different users. It only allows access to the particle size (referring to the extent of access objects) at first serialization, and it is difficult to maintain when the application needs to handle multiple or multiple serializations. Serialization is only applicable to the easiest application, or in some embedded systems that cannot effectively support the database.
JDBC requires you to deal with the data fields and map them into the table of the relational database. Developers are forced to deal with two distinctive data models, language and data access methods: Java, and relational data model in SQL. Implementing mappings from relational data models to Java object models in development are complicated, so that most developers are never defined for data definitions; they simply write process-proof Java code to the underlying relational database The data table is manipulated. The end result is: they can't get any benefits from object-oriented development.
The EJB component system is designed to support distributed objects. It also includes continuity of support for container management persistence Container Managed Persistence (see Glossary). Mainly due to their distributed characteristics, EJB applications are much more complicated than JDO, and the consumption of resources is much larger. However, JDO is designed to have certain flexibility, so that JDO products can be used to implement EJB storage processing at the bottom layer, thereby combining EJB containers. If your application requires object storage, but does not require distributed features, you can use JDO to replace EJB components. The most typical JDO usage scheme in the EJB environment is to access the JDO objects directly in EJB to avoid using entity components (Entity Beans). The EJB component must run in a controlled service environment in control (Managed, see Glossary). However, JDO applications can run in a controlled environment, or in an uncontrolled independent environment, which makes you flexibly choose the most appropriate application running environment. If you focus on the design Java object model, then use JDO to store instances of your data classes, you will greatly improve productivity and development efficiency. You only need to handle an information model. JDBC requires you to understand the relationship model and SQL language (translator Note: JDO is not to replace JDBC, but an abstract intermediate layer based on JDBC, providing a simpler data storage interface). Even when using EJB CMP (ie, the RF storage, see the glossary), you have to learn many other aspects related to the EJB system, and there are still limitations in JDO in modeling. . JDO specifies the agreement between the JDO operating environment and your storage object classes. JDO is designed to support multiple data sources, including data sources such as databases that are not considered. From now on, we use the database (see Glossary) to indicate any underlying data source you visited through JDO.
This chapter will discuss the basic capability of JDO, which is based on a small application developed by a virtual Media Mania. This company rents and sells a variety of forms of entertainment audiovisual products in many stores in the United States. There are some kiosks in their store, providing some movies and actors in the movie. This information is open to customers and stores to help choose goods that are right for customers.
Define data object model
Figure 1-1 is a UML class diagram showing the related classes of the object model of Media Mania and the relationships between mutual relationships. A Movie object represents a specific movie. Each actor who appears at least in a movie is represented by an actor object. The Role (role) class represents a particular role that an actor played in a movie, so the Role class also represents a relationship between movies and actors, which contains an attribute (the role name in the movie). Each movie contains one to multiple characters. Each actor can play different roles in different movies, even play multiple characters in the same movie.
Figure 1-1 MEDIA MANIA's UML class diagram of the object structure
We will put these data classes and programs that manipulate these data class instances into the com.mecdiamania.prototype package.
The class that needs to be stored
We define several classes such as Movie, Actor, and Role as sustainable, indicating that their instance can be stored in the database. First let's take a look at the complete source code for each class. There is a package statement in each class (the translator Note: The original book is written into "import"), so it can be clearly seen in which package used in this example is in which package.
Example 1-1 shows the source code of the MOVIE class. JDO is defined in the javax.jdo package, pay attention to this class does not have to import any specific JDO classes. Quote in Java and the Collection and related subclass (interface) in the java.util package are used to represent the relationship between our classes, which is the standard way in most Java applications.
Properties in the MOVIE class use standard types in Java, such as String, Date, Int, etc. You can declare the property as Private, do not need to define the corresponding GET and SET methods for each property. There are also methods for accessing these private properties in the Movie class, although these methods are used in other parts in the program, but they are not required by JDO. You can use properties packaging to provide methods needed to be exemplary models. This class has some static properties (static), which are not stored in the database.
"GenRes" attribute is a string type, the content is the movie style (action, love, strange, etc.) belonging to the movie). A set interface is used to represent the character set in the actor table of the movie. "AddRole ()" method Adds the element into the actor table, and "getCast ()" method returns a collection that cannot be changed, which contains the actor table. These methods are not required by JDO, just prepared for application programming. "ParseleaseDate () method and" formatReleaseDate () method are used to standardize (format) the date of issue of the movie. In order to keep the code simple, if the parameter format of ParseleaseDate () is wrong, NULL will be returned.
Example 1-1 Movie.java
Package com.mediamania.prototype;
Import java.util.set;
Import java.util.hashset;
Import java.util.collections;
Import java.util.date;
Import java.util.calendar;
Import java.text.SIMPLEDATEFORMAT;
Import java.text.parsePosition;
Public class movie {
Private static simpledateformat yearfmt = new simpledateformat ("yyyy");
Public static final string [] mparatings = {
"G", "pg", "pg-13", "r", "nc-17", "nr"}
PRIVATE STRING TITLE;
PRIVATE DATE RELESEDATE;
Private int RunningTime;
PRIVATE STRING
PRIVATE STRING Website;
PRIVATE STRING GENRES;
PRIVATE SET CAST; // Element Type: Role
PRIVATE MOVIE () {}
Public Movie (String Title, Date Release, Int Duration, String Rating,
String genres) {
THIS.TITLE = Title;
ReleaseDate = release;
RunningTime = DURATION;
THIS. RATING = Rating;
THIS.genRES = GENRES;
Cast = new hashset ();
Public string gettitle () {
Return Title;
}
Public Date getReleaseDate () {
Return ReleaseDate;
}
Public string getrating () {
Return Rating;
}
Public int getRunningTime () {
Return RunningTime;
}
Public void setWebsite (String site) {
Website = site;
}
Public string getWebsite () {
Return Website;
}
Public String getgenres () {
Return genres;
}
Public void addrole (role role) {
Cast.Add (Role);
}
Public set getcast () {
Return Collections.unmodifiableSet (CAST);
}
Public Static Date ParseleaseDate (String Val) {
Date Date = NULL;
Try {
Date = yearfmt.parse (val);
} catch (java.text.parsexception eXC) {}
Return Date;
}
Public string formatReleaseDate () {
Return Yearfmt.Format (releasedate);
}
}
JDO has added a requirement to a class that needs to be stored: an unparalleled constructor. If you do not define any constructor in class code, the compiler will automatically generate a parameter-free constructor; if you define a refinement, you must define a non-refined constructor, you can declare it as Private is forbidden to access external access. If you don't define this no-argument constructor, some JDO products will automatically generate one, but this is just the features provided by the specific JDO product, which is not portable.
Example 1-2 shows the source code of the ACTOR class. In our goals, all actors have a name that will not be repeated to identify themselves, which can be different from the name of the birth. Based on this, we use a String to represent the name of the actor. Each actor may play a plurality of roles, "ROLES" members in the class represent the properties of this side of the Actor and Role relationship. The annotation of the first line is only for documentation, which does not implement any special features for JDO. The second row and the first line "AddRole ()" and "RemoveRole ()" method enables the program to maintain an actor instance and the ROLE instance set it associated.
Example 1-2 actor.java
Package com.mediamania.prototype;
Import java.util.set;
Import java.util.hashset;
Import java.util.collections;
Public class actor {
PRIVATE STRING NAME;
1 Private set roles; // Element Type: Role
Private actor () {}
Public actor (string name) {
THIS.NAME = Name;
Roles = new hashset ();
}
Public string getname () {
Return Name;
}
2 public void addrole (role role) {
Roles.Add (Role);
}
3 public void removerole (role role) {
Roles.Remove (Role);
}
Public set getroles () {
Return collections.unmodifiableSet (ROLES);
}
}
Finally, Examples 1-3 show the source code of the Role class. This class represents the relationship between the MOVIE class and the ACTOR class, and includes the name of the specific role played in a movie. The constructor initializes the reference to the MOVIE and Actor objects, and keeps logic consistency by calling the addrole () method in the other end of the relationship.
Example 1-3 Role.java
Package com.mediamania.prototype;
Public class role {
PRIVATE STRING NAME;
PRIVATOR ACTOR;
Private movie movie;
Private role () {}
Public role (String Name, Actor, Movie movie) {
THIS.NAME = Name;
THIS.ACTOR = actor;
this.Movie = Movie;
Actor.addrole (this);
Movie.Addrole (this);
}
Public string getname () {
Return Name;
}
Public actor getactor () {
Return actor;
}
Public movie getmovie () {
Return movie;
}
}
At this point, we have learned the source code of each class existing in the database. These classes do not need to import or use any JDO-related specific classes. Further, in addition to the non-arranging constructor, these classes are stored without any data or methods. Code for accessing or updating attribute data and maintaining the relationship between instances is exactly the same as the standard code in most Java applications.
Category declaration as a storageable
In order to let the class can be stored, it must be specified which classes are required to be stored and need to be provided with the specific storage details, while the Java code is not reflected in the Java code. JDO describes this information using a metadata file (Metadata, see Glossary) in an XML format. You can define metadata files in XML format based on classes (multiple files) or packages (a file). If it is based on class, the file name is the same as the name of the class (the translator's note: does not include the package name), but the extension is ended with ".jdo". Therefore, the metadata file describing the MOVIE class needs to be named "movie.jdo" and is placed in the same directory with the compiled movie.class. If you are using a packet-based metadata file, it contains multiple classes under the package and multiple sub-package (SUB-Package). Examples 1-4 show metadata described in MEDIA MANIA's object models. This metadata is based on the package where this object model is located and writes in "COM / MediaMania / Prototype / package.jdo".
Example 1-4 ... / prototype / package.jdo metadata in the file
XML Version = "1.0" encoding = "UTF-8"?>
1
"- // Sun Microsystems, Inc.//dtd Java Data Objects Metadata 1.0 // En"
"http://java.sun.com/dtd/jdo_1_0.dtd">
2
4
5
field>
clas>
6
field>
clas>
package>
jdo>
The "JDO_1_0.dtd" file indicated in the line line provides the definition of the elements used in the JDO metadata file. This document type definition (DTD) is provided by the JDO specification, must be provided by a JDO product. This file can also be downloaded at http://java.sun.com/dtd. You can also change the content in the "DOCTYPE" to a copy of your local file system.
Metadata files can contain information about some storage details with one or more packages containing storage classes. Each package is defined by a "package" element that has a "name" attribute to represent the name of the package. The second line gives our correspondent package elements of our com.mediamania.prototype package. In the package element, it is a class element in each package. (If the third line is a description element of the MOVIE class). Multiple package elements can be written in this file, which cannot be nested to each other.
If the storage details of a attribute must be additionally pointed out, you need to add a "field" element inside the "Class" element, see the 4th line. For example, you can indicate what type of element type is placed in a collection type property through this field element. This element is not necessary, but the addition of this element can be more efficient and more accurately completed. The MOVIE class has a collection (SET) type property: CAST, and the Actor class also has a collection of attributes: Roles; they all contain references to Role. The 5th line marked the element type of CAST. In most cases, the default value of a attribute in the metadata is assumed to be the most common value (such as the element type of the property of the Collection type, will be default as object).
All possible properties will be deemed to be stored by default (that is, sustainable). "Static" and "Final" properties cannot be set to be stored. The attribute of a "transient" is not considered to be stored by default, but it can be explicitly indicated in the metadata to be stored. The fourth chapter will explain this problem in detail.
Chapter 4, 10, 12, and 13, will describe the description of which features you can perform in the properties in classes and classes. For a class that has no collection of attributes like "Role", you can only list this class in the metadata, as 6, as long as this class doesn't need anything special Different from the default case.
Project compilation environment
In this section, we will look at the development environment used to compile and run our JDO application. This includes the project's file directory structure, compiles the related JAR files required, and enhances the stored class (Enhance, see Glossary) Syntax (we will reinforce this concept in this section) ). The establishment of this environment is generally related to the JDO products you specifically, so your actual project development environment and related catalog structures may be slightly different. You can use Sun Company's JDO reference product (Reference Implementation, SUN is a simple product that implements specifications to implement the JDO specification, which is used to provide reference to other JDO vendors, or use directly as JDO products, just The performance is convenient. This is a bit similar to the sample server in the J2EE development kit with the J2EE development package as the J2EE specification), or you can choose other JDO products according to your needs. The examples in this book are based on JDO reference products. You can choose JSR-12 on http://www.jcp.org, then download it to this reference product. When you have a JDO product installed, you need to build a directory structure, and set the corresponding classPath to include all JAR files and related directories you need to do so that you can compile and run your application.
JDO introduces an additional step in your compilation process, called class enhancements (see Glossoms). Each class that needs to be stored must be enhanced to be used in the JDO's operating environment. Your stored classes are compiled into some .class files by the Javac compiler, and an enhancer reads these generated binary code files and the corresponding metadata file, and then insert some extra code according to the information indicated by the metadata file. In binary code, generate some new .class files that can be run in the JDO environment. Your JDO application can only transfer these enhanced class files. The JDO reference product includes an enhancer called "Reference Enhancer".
JAR file required by JDO reference product
When you use a JDO reference product, you need to put the following JAR files in your classpath during the development process. At runtime, all of these JAR files must also be in your classpath. JDo.JAR JDO specification defined standard several interfaces and classes.
Jar file of JDori.jar Sun's reference product
BTree.jar JDO Reference The software used in the product is used to manage the data stored in the file. The JDO reference product uses a file to save the data object.
JTA.jar Java transaction control API. These include the SYNCHRONIZATION interface defined in the javax.transaction package, which is used in the JDO interface. Some other tool classes contained in this JAR file are generally useful in a JDO product. You can download this JAR file on http://java.sun.com/products/jta/index.html
ANTLR. Jar JDO Reference Product Analysis The syntax analysis technology related to the JDO query language (ie jdoql, see the glossary). Antlr 2.7.0 is used in the reference product. You can download it on http://www.antlr.org.
Xerces.jar References Xerces-J 1.4.3 in parsing XML files (mainly metadata files). This file can be downloaded on http://xml.apache.org/xerces-j/.
The first three files are included in the JDO reference product; the last three files can be downloaded from their respective websites.
References also include a JAR file: jdo-enhance.jar, including a reference enhancer. All of them are also there in the jdori.jar file. In most cases, you will use jdori.jar in the development environment and running environment, and don't need JDORI-Enhancer.jar files. JDORI-Enhancer.jar files were packaged separately. You can enhance class code independently of the specific JDO products. In addition to the reference product, some other products will also release this JAR file with the product. If you use other JDO products, its document tells you the list of JAR files you need. A product usually puts all of these JAR files in a special directory generated in its installation. The JDO.jar file containing the standard interface of JDO should be included in all JDO products, in general, this file will exist in a specific vendor's JDO product. JDOCENTRAL (http://www.jdocentral.com) provides a large number of JDO resources, including many commercial JDO products for free trial download.
Project catalog structure
For Media Mania App Development environments, you need to use the following directory structure, this project must have a root directory, where there is a place for the system's file system. The following directorys are based on this root directory:
SRC This directory includes all source code for the application. In the src directory, there is a subdirectory system in accordance with the COM / MediaMania / Prototype structure (corresponding to the com.mediamania.prototype packet in Java). This is also the directory where movie.java, actor.java, and role.java source files are located.
Classes When the Java source code is compiled, the generated .CLASS file is placed in this directory.
Enhanced This directory stores enhanced .CLASS class code file (generated by the enhancer)
Database This directory stores the JDO reference product for storing the data.
Although such a directory structure is not required by the JDO specification, you have to understand it so that we can follow our description of Media Mania applications.
When you perform your JDO app, the Java running environment must be transferred to enhanced version of class files, which is the class files in the enhanced directory. Therefore, this directory in your classpath must be in the CLASSES directory. As an alternative, you can also use it to reinforce the unhappy files directly with your enhanced class file.
Enhance class code for storage
Categories must be enhanced before, they must be enhanced before they are handled by JDO environments. The JDO Enhancer adds additional data and methods in your class, so that it can be processed by JDO products. The enhancer first reads information from the class file generated by the Javac compiler, and then generates a new enhanced class file that contains the necessary functions according to metadata. JDO standardizes the changes made by the enhancer so that the enhanced class file has binary compatibility and can be used in other JDO products. These enhanced documents are also independent of any specific database.
As mentioned earlier, the enhancer in the JDO reference product provided by Sun is called a reference enhancer. JDO product vendors may generally provide their own booster; the syntax of the command line call enhancer may differ from here. Each product will provide you with documentation to interpret if you enhance your class on this product.
Examples 1-5 give command lines for the use of reference enhancers to enhance our Media Mania applications. "-d" parameter indicates that the directory of the enhanced class file will be stored, and we have planned to put it under the enhanced directory. The enhancer receives a series of JDO metadata files and a range of sets of parameters that require enhanced class files. The separator between the catalog and the last-continalization may not be the same, depending on the operating system you compile.
Example 1-5 enhances the class
Java com.sun.jdori.enhancer.main -d enhanced /classes/com/mediamania/prototype/package.jdo /
Classes / COM / Mediamania / Prototype / Movie.class /
Classes / Com / Mediamania / Prototype / Actor.class /
Classes / Com / Mediamania / Prototype / Role.class
Although the metadata file and the source code are more convenient, the JDO specification is a recommended metadata file to be tuned as a class file as a resource to be classloader. Metadata is needed when compiling and running, so we will
Package.jdo metadata file
The directory of the Prototype package in the Classes directory system.
In Example 1-5, all the .class class files in our object model are listed together, but you can also enhance each class file separately. When this enhancement command is executed, it puts the enhanced new file in the enhanced directory.
Create a database connection and transaction
Since our classes have been enhanced, their instances can also be stored in the database. Let's take a look at the application if you have a connection to the database and perform some operations in a transaction. We start writing software code directly using the JDO interface, and all JDO interfaces used in the app are defined in the javax.jdo package.
One interface in JDO is called PersistenceManager (Meter, which has a connection to the database. A PersistenceManager has an instance of a Transaction interface in JDO for controlling the beginning and end of a transaction. This Transaction instance acquisition method is the CURRENTTRANSACTION () method for calling the PersistenceManager instance.
Get a PersistenceManager
PersistenceManagerFactory is used to configure and get PersistenceManager. The method in the PersistenceManagerFactory is used to set some configuration properties that control the behavior of the PersistenceManager instance obtained. Thus, the first step of a JDO application is to get a PersistenceManagerFactory instance. To get this example, you need to call the following JDOHELPER class static method:
Static PersistenceManagerFactory getPersistenceManagerFactory (Properties Props);
This Properties instance can be set by program settings or from the file. Examples 1-6 lists the contents of the configuration file we will use in Media Mania applications. Among them, the PersistenceManagerFactoryClass attribute in the first line indicates which JDO product adopted by providing the PersistenceManagerFactory interface that provides specific JDO products. In this example, we indicate the class defined by Sun's JDO reference product. Other attributes listed in Examples 1-6 include connection URLs and username / passwords for connecting to specific databases, which are generally required to connect to specific databases.
Example 1-6 jdo.properties file content
1 javax.jdo.PersistenceManagerFactoryClass = com.sun.jdori.FOSTORE.FOSTOREPMF
Javax.jdo.Option.connectionURL = FOSTORE: Database / FOStoredbjavax.jdo.Option.connectionUserName = DAVE
Javax.jdo.option.connectionpassword = jdo4me
Javax.jdo.opption.optimistic = false
This format of this connection URL relies on the specific database employed. In the JDO reference product, it includes its own storage mechanism, called "File Object Database File Object Store". The ConnectionURL attribute in Example 1-6 indicates that the actual database is located
Database directory, under the root of our project. In this example, we provide a relative path; however, it provides an absolute path. This URL also specifies the name of the FOSTORE database file file.
FOSTOREDB "start.
If you use other JDO products, you need to provide additional values to the above properties, you have to provide some additional properties. Please refer to the documentation of the product to obtain an instructions for the necessary properties that need to be configured.
Create a FOSTORE database
To use Fostore, we must first create a database. The programs in Examples 1-7 use the jdo.properties file to create a database; all applications use this profile. Chain 1 Turn these configuration properties into a Properties instance from the jdo.properties file. The second line of the program joins a "com.sun.jdori.Option.connectionCreate" property to indicate that the database needs to be created. Set it to TRUE to guide the reference product to create the database. We use GetPersistenceManagerFactory () to get PersistenceManagerFactory in the first line. The fourth line generates a PersistenceManager.
To complete the creation of the database, we also need to start and end a transaction. The CurrentTransAction () method of the PersistenceManager is called in Chapter 5 to access the Transaction instance associated with the PersistenceManager. The sixth line and the 7th line call the begin () and commit () methods of this Transaction instance to start and end a transaction. When you perform this program, you will generate a FOSTORE database in the Database directory, including two files: fostore.btd and fostore.btx.
Example 1-7 Create a FOSTORE database
Package com.mediamania;
Import java.io.fileinputstream;
Import Java.io.InputStream;
Import java.util.properties;
Import javax.jdo.jdohelper;
Import javax.jdo.PersistenceManagerFactory;
Import javax.jdo.PersistenceManager;
Import javax.jdo.transaction;
Public class createDatabase {
Public static void main (string [] args) {
CREATE ();
}
Public static void create () {
Try {
InputStream PropertyStream = New FileInputStream ("jdo.properties");
Properties JDOPROPERTIES = New Properties ();
1 JDOPROPERTIES.LOAD (PropertyStream);
2 JDOPROPERTIES.PUT ("com.sun.jdori.Option.connectionCreate", "true"); PersistenceManagerFactory PMF =
3 JDoHelper.getPersistenceManagerFactory (JDOPROPERTIES);
4 PersistenceManager PM = PMF.GetPersistenceManager ();
5 Transaction TX = pm.currenttransaction ();
6 tx.begin ();
7 tx.commit ();
} catch (exception e) {
System.err.Println ("Exception Creating The Database");
E.PrintStackTrace ();
System.exit (-1);
}
}
}
JDO References provide this programming to create a FODATORE database, while most databases provide a JDO tool to create a database. JDO does not specify an interface that is unrelated to the vendor to create a database. The creation of the database is generally related to the specific database. This procedure shows how to complete this step in the Fostore database.
Also, if you use JDO on a relational database, you can have an additional step in some cases: Create or map the object model to an existing database mode (SHEMA, a database user and the data it own. The syndrome of the table system). Creating a database mode is related to the specific JDO products you use, you need to view the documentation of the product to decide to take the necessary steps.
Example operation
To this end, we already have a database that can store instances of the data classes, each program needs to get a PersistenceManager to access or update the database. Example 1-8 gives the source code for the MediamaniaApp class. This class is the basic class of each application in this book. Each program is a specific subclass of the specific business logic in the execute () method ( Concrete subclass, relative to abstract abstract).
Mediamaniaapp has a constructor to read configuration information (line 1) from jdo.properties. After transferring the configuration information from this file, it calls the getPropertyoverrides () method and merges into the final property set (Properties) to the JDOPRoperties object. A program class can overload getPropertyOverrides () to provide additional configuration information or change the configuration given in the jdo.properties file. This constructor gets a PersistenceManagerFactory (line 2) and then get a PersistenceManager. We also offer a getPersistenceManager () method to get the PersistenceManager outside the MediamaniaApp class. Transaction associated with PersistenceManager is acquired in the 4th line.
Each program subclass calls an ExecuteTransAction () method defined in the MediamaniaApp class, which starts a transaction in row 5, and then calls the Execute () method in line 6, i.e., however, the specific function of the subclass is executed. We have chosen a special programming design to simplify and reduce redundant code that creates a runable environment. These are not required by JDO, you can also choose the most appropriate way according to your application environment.
When the () method implemented in the subclass returns, we will try to submit this transaction (line 7), and if there is any abnormality, we will roll back this transaction and print the exception information to the system. In the error output stream (System.err). Example 1-8 MediamaniaApp base class
Package com.mediamania;
Import java.io.fileinputstream;
Import Java.io.InputStream;
Import java.util.properties;
Import java.util.map;
Import java.util.hashmap;
Import javax.jdo.jdohelper;
Import javax.jdo.PersistenceManagerFactory;
Import javax.jdo.PersistenceManager;
Import javax.jdo.transaction;
Public Abstract Class MediamaniaApp {
Protected PersistenceManagerFactory PMF;
Protected PersistenceManager PM;
Protected Transaction TX;
Public abstract void execute (); // defined in Concrete Application Subclasses
protected static map getpropertyoverrides () {
Return new hashmap ();
}
Public Mediamaniapp () {
Try {
InputStream PropertyStream = New FileInputStream ("jdo.properties");
Properties JDOPROPERTIES = New Properties ();
1 JDOPROPERTIES.LOAD (PropertyStream);
JDOPROPERTIES.PUTALL (GetPropertyoverrides ());
2 PMF = JDOHELPER.GETPERSISTENCEMANAGACTORY (JDOPROPERTIES);
3 pm = pmf.getPersistenceManager ();
4 tx = pm.currenttransaction ();
} catch (exception e) {
E.PrintStackTrace (System.err);
System.exit (-1);
}
}
Public persistenceManager getPersistenceManager () {
Return PM;
}
Public void executeTransaction () {
Try {
5 tx.begin ();
6 execute ();
7 tx.commit ();
} catch (throwable exception) {
Exception.PrintStackTrace (System.err);
IF (tx.isactive ())
TX.rollback ();
}
}
}
Storage instance
Let's take a look at a simple program called CREATEMOVIE for storing an MOVIE instance, as shown in Example 1-9. The function is placed in the execute () method. After constructing a CreateMovie instance, we call the ExecuteTransaction () method defined in the MediaManiaApp base class, which calls the overloaded Execute () method in this class. This execute () method is from the row 5 to initialize a separate MOVIE instance and then save this instance in line 6 calls the MakePersistent () method of the personcerManager. If this transaction is successfully submitted (Commit), this Movie instance is stored in the database. Example 1-9 Create a MOVIE instance and save it
Package com.mediamania.prototype;
Import java.util.calendar;
Import java.util.date;
Import com.mediamania.mediamaniaapp;
Public class createmovie extends mediamaniaapp {
Public static void main (string [] args) {
Createmovie Createmovie = New Createmovie ();
CreateMovie.executeTransaction ();
}
Public void execute () {
Calendar Cal = Calendar.getInstance ();
Cal.clear ();
Cal.set (Calendar.Year, 1997);
Date Date = Cal.getTime ();
5 Movie Movie = New Movie ("Titanic", DATE, 194, "PG-13",
Historical, DRAMA ";
6 pm.makepersistent (movie);
}
}
Now let's take a larger application: loadMovies, as shown in Examples 1-10, which reads and creates multiple MOVIE instances from a file containing movie information. This information file name is passed to the program as a parameter, and the LoadMovies constructor initializes a bufferedReader to read the information. The execute () method reads a row and analyzed from this file by calling Parsemoviedate () to create a MOVIE instance at row 1, and save it in line 2. When this transaction is submitted in ExecuteTransAction (), all newly created MOVIE instances are saved to the database.
Example 1-10 loadingMovies
Package com.mediamania.prototype;
Import java.io.fileReader;
Import java.io.bufferedreader;
Import java.util.calendar;
Import java.util.date;
Import java.util.StringTokenizer;
Import javax.jdo.PersistenceManager;
Import com.mediamania.mediamaniaapp;
Public class loadingmovies extends Mediamaniaapp {
Private buffredreader reader;
Public static void main (string [] args) {
LoadMovies Loadmovies = New LoadMovies (Args [0]);
LoadMovies.executeTransaction ();
Public loadMovies (string filename) {
Try {
FileReader Fr = New FileReader (FileName);
Reader = New BufferedReader (fr);
} catch (exception e) {
System.err.Print ("Unable to open input file");
System.err.println (filename);
E.PrintStackTrace ();
System.exit (-1);
}
}
Public void execute () {
Try {
While (Reader.Ready ()) {
String line = reader.readline ();
Parsemoviedata (line);
}
} catch (java.io.ioException e) {
System.err.Println ("Exception Reading Input File");
E.PrintStackTrace (System.err);
}
}
Public void parsemoviedata (string line) {
StringTokenizer tokenizer New StringTokenizer (Line, ";");
String title = tokenizer.nextToken ();
String datestr = tokenizer.nextToken ();
Date releasedate = movie.parseleasedate (dateStr);
INT RunningTime = 0;
Try {
RunningTime = integer.parseint (tokenizer.nextToken ());
} catch (java.lang.numberformatexception e) {
System.err.Print ("Exception Parsing Running Time for");
System.err.println (title);
}
String banging = tokenizer.nextToken ();
String genres = tokenizer.nextToken ();
1 Movie Movie = New Movie (Title, ReleaseDate, RunningTime, Rating,
GenRes);
2 pm.makepersistent (movie);
}
}
The data format in the movie information file is:
Movie Title; Running Time; Movie Rating; Genre1, Genre2, Genre3
The data format used to indicate the date of the release is controlled by the MOVIE class, so ParseleseDate () is called to generate a Date instance based on the date of origination. A movie can belong to a variety of styles that are listed on the tail of the data line.
Access instance
Let us now access the Movie instance in the database to verify that we have successfully saved them. There are many ways to access instances in JDO:
From a class extension (extent, representation of a class and all the subclasses) it is asteted (Iteerate, see Glossary) Browse (NaviGate) to browse (NaviGate) to perform a query
Extent (Extension) is used to access a tool for a class and all its subclasses. And if you only want to access some instances in the program, you can perform a query, and a Boolean assertion (ie, judgment statement) that must be satisfied in the query is specified to limit the return instance. After the program accesses an instance from the database, it is possible to browse other instances by reference to other instances of other instances or traversal of other instances. These instances do not push into memory from the database before being accessed. The above ways of these access instances are often used, and JDO guarantees that each instance will only have a copy in memory in a PersistenceManager. Each PersistenceManager controls a separate transaction context (Transaction Context). Traverse a class extension
JDO provides an Extent interface to access a class extension. This extension allows access to all instances of a class, but does not mean that all instances are in memory. The PrintMovies program given in Examples 1-11 below uses the MOVIE class extension.
Example 1-11 spreads the expansion of the MOVIE class
Package com.mediamania.prototype;
Import java.util.iterator;
Import java.util.set;
Import javax.jdo.PersistenceManager;
Import javax.jdo.extent;
Import com.mediamania.mediamaniaapp;
Public class printmovies extends mediamaniaapp {
Public static void main (string [] args) {
PRINTMOVIES MOVIES = New PrintMovies ();
Movies.executeTransaction ();
}
Public void execute () {
1 extent extent = pm.getextent (movie.class, true);
2 Iterator it = extent.iterator ();
While (ore.hasnext ()) {
3 MOVIE MOVIE = (Movie) it.next ();
System.out.print (movie.gettitle ());
System.out.print (";");
System.out.print (movie.getrating ());
System.out.print (";");
System.out.print (movie.formatReleaseDate ());
System.out.print (";");
System.out.print (movie.getrunningTime ());
System.out.print (";");
4 system.out.println (movie.getgenres ());
5 SET CAST = Movie.getcast ();
Iterator Castiterator = Cast.iterator ();
While (Castiterator.hasNext ()) {
6 role role = (role) Castiterator.next ();
System.out.print ("/ t");
System.out.print (roule.getname ());
System.out.print (",");
7 System.out.println (roule.getactor (). Getname ());
}
8 EXTENT.CLOSE (ITER);
}
}
In the first line, we get an extension of a MOVIE class from the PersistenceManager. The second parameter indicates whether all subclasses of the MOVIE class, false makes only instances of the MOVIE class are returned, even if there are other MOVIE subclasses The example exists. Although we currently have no Movie subclasses, True is used to ensure that the examples of similar MOVIE subclasses that may be added in the future will be returned. The Extent interface has an Iterator () method, that is, we are transferred to each instance in this class extension in row 2 to get an Iterator traveler. Line 3 uses a traverser to access instances of the MOVIE class. The program can be operated for the MOVIE instance to obtain data and print it out. For example: row 4 we call getgenres () to get the style to which a movie belongs, line 5 we get the character set in the movie, get each role in the row 6 and print its name, line 7 we pass call getActor () To view the actor object of the role, this is what we have defined in the Role class, we printed the name of the actor.
When this program ends the traversal of class extensions, this traverster is turned off in line 8 to release the relevant resources that are occupied throughout the time. For an extension, multiple traverses can be performed at the same time, this close () method closes a specific travers, and the CloseAll () method can turn off all traversers associated with a class extension.
Browse Object Model
Example 1-11 demonstrates traversal to Movie class extension. But in the line 6, we also browsed a film-related role collection according to the object model. In the line 7, we also accessed the relevant actor instances through reference in the Role instance. 5 and lines 7 show access to "TO-MANY" and "to-one" relationship (TO-One) ". From a relationship from one class to another has a weight (cardinality, indicating the total number of target objects that may occur), indicating that one or more instances are associated. A reference represents a case where the weight is one; and a set is used to associate multiple objects (weight is much).
The syntax required for access associated instances is exactly the same as the standard browsing method of the associated object in memory. Program between row 3 and row 7 does not need to call any JDO interface, which is simply traverse through the relationship in the object. Related examples are only read from the database and generated from the database until the program is directly accessed. Access to the database is transparent, instances need to be tone. Some JDO products also provide mechanisms other than Java interfaces to adjust the cushioning mechanism for the JDO product. Your Java program is independent of these optimizations, but you can get improved performance from these optimizations.
The way to access the relevant database objects in the JDO environment is the same as the TRANSIT object object object object, so you can write your software in a non-JDO. Software for consideration without any storage factors for JDO or other aspects can complete the browsing of instance objects in the database via JDO. This feature greatly promotes the development of productivity, which allows existing software to be quickly and easily integrated into the JDO environment.
Execute query
You can also run a query on a class extension. The Query interface in JDO is used to select an instance set that meets certain conditions. The remaining examples in this chapter need to access the specified Actor or Movie object in accordance with a given unique name. These methods (see Examples 1-12) are different; getActor () performs a name-based query, and the getMovie () method performs a table-based query.
Example 1-12 Query Method in Prototypequeries class Package com.mediamania.Prototype;
Import java.util.collection;
Import java.util.iterator;
Import javax.jdo.PersistenceManager;
Import javax.jdo.extent;
Import javax.jdo.qury;
Public class prototypequeries {
Public Static Actor getActor (PersistenceManager PM, String Actorname) {
1 extent actoreXtent = pm.getextent (actor.class, true);
2 query query = pm.newquery (actoreXtent, "name == actorname");
3 Query.DeclareParameters ("String Actorname");
4 Collection results = (color) query.execute (actorname);
Iterator it = result.iterator ();
Actor actor = NULL;
5 IF (ore.hasnext ())
actor = (actor) iter.next ();
6 query.close (result);
Return actor;
}
Public Static Movie GetMovie (PersistenceManager PM, String MovietiTitle) {
Extent movieextent = pm.getextent (movie.class, true);
Query Query = PM.NewQuery (movieextent, "title == movietitle");
Query.DeclareParameters ("String MovieTitle");
Collection result = (color) query.execute (movietitle);
Iterator it = result.iterator ();
Movie movie = NULL;
IF (ore.hasnext ())
Movie = (movie) iter.next ();
Query.close (Result);
Return movie;
}
}
Let's take a look at the getActor () method. In row 1 we take the extension of an ACTOR class, line 2 creates a query instance by the newquery () method defined in the PersistenceManager interface, which is established based on this class extension and corresponding filtering criteria.
The "Name" identifier in the filter condition represents the Name property in the ACTOR class. Namespace used to determine how this identifier depends on the class extension that initializes this Query instance. Filtering conditions Expression indicate that the actor's name is equal to actorName, in which we can use the "==" to compare two strings without having to use Java's syntax (name.equals (actorname). The ActorName identifier is a query parameter that is declared in the row 3. A query parameter allows you to give a value when the query is executed. We choose the same identifier "actorname" as a parameter name of this method, as a query parameter name. This query is executed in the fourth line, as the value of the getActorName parameter value as the query parameter actorName. The return type of query.execute () is defined as Object, in JDO1.0.1, the returned type is always the type, so we can directly convert this return object to a Collection. In JDO1.0.1, the returns return Object is to extend the future to returns a type other than a Collection. After that, our method is trying to access an element object in Chapter 5. We assume that one name is in the database, only one Actor instance is corresponding to the database. Before returning this result, the line 6 closes this query to release the relevant resources. If this query finds the name of the actor instance, then return, otherwise return NULL if the query result is empty.
Change instance
Now let's take a look at the programs for changing the instances in the database. When a program accesses an instance in a database, it can change one or more attribute values of this instance. When the transaction is submitted, all changes to these instances will be automatically synchronized to the database.
The UpdateWebsite program given in Examples 1-13 is used to set websites related to a movie. It has two parameters: the first is the film name, the second is the movie website URL. After initializing this program instance, the executeTransAction () method is called, and the Execute () method of this program is called.
Row 1 Call getMovie () (defined in Example 1-12) to get the MOVIE object of the specified slice, if getMovie () returns NULL, the program reports the film that cannot be found, and then exits. Otherwise, in row 2 we call setWebsite () (defined in Example 1-1) to set the WebSite property given to the parameter value given. When ExecuteTransaction () is submitted to this transaction, the modification of the MOVIE instance will be automatically synchronized into the database.
Example 1-13 Changing a property
Package com.mediamania.prototype;
Import com.mediamania.mediamaniaapp;
Public class updatewebsite extends mediamaniaapp {
PRIVATE STRING MOVIETITETLE;
PRIVATE STRING NewWebsite;
Public static void main (string [] args) {
String Title = args [0];
String Website = args [1];
UpdateWebsite Update = new updatewebsite (title, website);
Update.executeTransaction ();
}
Public UpdateWebsite (String Title, String Site) {Movietitle = Title;
NewWebsite = Site;
}
Public void execute () {
1 Movie movie = prototypequeries.getMovie (PM, MovietiTitle);
IF (movie == null) {
System.err.Print ("Could Not Access Movie with Title of");
System.err.println (movietitle);
Return;
}
2 Movie.SetWebsite (NewWebsite);
}
}
In Examples 1-13, you can see that the program does not need to call any JDO interface to change the properties of the MOVIE object, this program has accessed an instance and then calls a method to change its website properties, this method uses Java standard syntax To change the corresponding properties. There is no additional coding before committing to synchronize the update to the database, and the JDO environment will automatically change. This program executes the operation of the stored instance without the need to import or use any JDO interface.
Now let's take a big program, named Loadroles, to show some of the characteristics of JDO. Loadroles, see Examples 1-14, responsible for transferring a movie role and the information of actors who play these roles. LoadRoles is passed to a separate parameter, which is used to indicate a file name, and then a bufferedReader is initialized in the program's constructor to read this file. It reads the text of the file, one role per line, follow the format:
Movie Title; actor's name; role name
Usually all characters of a movie are combined in the adjacent position in this document; LoadRoles uses some small optimization to determine whether the currently processed role is a movie with the previous role.
Example 1-14 Example Change and Persistence-By-Reachability
Package com.mediamania.prototype;
Import java.io.fileReader;
Import java.io.bufferedreader;
Import java.util.StringTokenizer;
Import com.mediamania.mediamaniaapp;
Public class loadroles extends Mediamaniaapp {
Private buffredreader reader;
Public static void main (string [] args) {
Loadroles Loadroles = New Loadroles (Args [0]);
Loadroles.executeTransaction ();
}
Public loadingroles (string filename) {
Try {
FileReader Fr = New FileReader (FileName);
Reader = New BufferedReader (fr);
} catch (java.io.ioException e) {
System.err.Print ("Unable to open input file");
System.err.println (filename);
System.exit (-1);
}
}
Public void execute () {
String lasttitle = "";
Movie movie = null; try {
While (Reader.Ready ()) {
String line = reader.readline ();
StringTokenizer tokenizer = New StringTokenizer (Line, ";");
String title = tokenizer.nextToken ();
String actorname = tokenizer.nextToken ();
String Rolename = tokenizer.nextToken ();
IF (! Title.equals (lasttitle)) {
1 MOVIE = prototypequeries.getmovie (PM, Title);
IF (movie == null) {
System.err.Print ("Movie Title Not Found:");
System.err.println (title);
CONTINUE;
}
Lasttitle = Title;
}
2 actor = prototypequeries.getactor (PM, Actorname);
IF (actor == null) {
3 actor = new actor;
4 pm.makepersistent (actor);
}
5 role role = new role (RoleName, Actor, Movie);
}
} catch (java.io.ioException e) {
System.err.Println ("Exception Reading Input File");
System.err.Println (e);
Return;
}
}
}
Where the execute () method reads each row information in the file. First, it checks if the movie name of the line is the same as the previous line. If not, the line 1 calls getMovie () to get the movie according to the title, if the film name does not exist in the database, then the program outputs an error Information and skip this line of information. Line 2 Try to access the name of the name of the name, if the name of the name is not found, a new actor will be created, set its name in the row 3, and save it in row 4.
In the program, we have read the file information and set up relevant instances in the database in the database. The row that really completed the task is line 5. The row creates a new role instance. This role constructor has defined in Example 1-3; here we repeat it in more detail:
Public role (String Name, Actor, Movie movie) {
1 .name = name;
2 this.actor = actor;
3 this.Movie = Movie;
4 actor.addrole (this);
5 Movie.Addrole (this);
}
Row 1 Initialize the name of this role, line 2 Create a reference to the relevant actor object, line 3 creates a reference to the corresponding movie instance. The relationship between actor and role and the relationship between Movie and Role are bidirectional, so the other end of the relationship also needs to be updated, and the ADDROLE () method we call the actor in the row 4, it adds this role to the In the Roles collection of actor objects; similar, row 5 we call the AddRole () method of the movie object to add this role to the Cast collection of the movie object. The addition of the current role in actor.roles and movie.cast as an element will cause changes to the objects referenced by the Actor and Movie. The Role constructor shows you that you can create a relationship to another instance by simply establishing a reference, or you can join one or more instances to the referenced collection of references to another instance. This process is an embodiment of an object relationship in Java, which is directly supported in JDO. When the transaction is submitted, the relationship established in memory will be synchronized into the database.
The role constructor returns, the LOAD () method handles the next line in the file. This While cycle ends after all the lines of reading the file. You may have noticed that we have never called the MakePersistent () method for the Role instance, while the ROLE instance will also be saved to the database because JDO supports "Persistence-by-reachability". Reachability storage allows any unsearable instances of a stored class to be saved when submitted, as long as it can be directly or indirectly reached directly or indirectly from a preserved instance. The reachability of the instance is based on a direct reference or a collection of reference. The object tree formed by all the reachable examples of an example is referred to as the "COMPLETE CLOSURE" "of this instance. The reachability rules are transmitted sexually applied in all references in memory in memory such that the entire complete closure is stored.
From other storage instances to remove all the references to a storage instance do not automatically remove the removed instance, you need to delete this instance, which will be our next section. If you create a reference to a non-storage instance in a transaction, but then modify the reference relationship to make the non-storage instance are not referenced, then this non-storage instance remains non-storage status when submitting. Will be saved to the database.
Storage accessibility allows you to write a large pile of code without calling any JDO interface to save an instance, so your code can focus on how to build an instance in the memory, and JDO products will be in memory Save the non-storage instance established by the relationship to the database. Your program can establish a fairly complex object system map in memory and then build a reference to this map from a stored instance to complete these new objects.
Delete instance
Now let's take a look at a program that deletes some instances from the database. In Examples 1-15, the DeleteMovie program is used to delete a MOVIE instance. The film name of the movie to be deleted is given as a parameter. Row 1 Try to access this movie instance, if the film name is not existent, the program reports an error and exits. In line 6 we call the DeletePersistent () method to delete the Movie instance itself.
Example 1-15 Delete a MOVIE instance from the database
Package com.mediamania.prototype;
Import java.util.collection;
Import java.util.set;
Import java.util.iterator;
Import javax.jdo.PersistenceManager;
Import com.mediamania.mediamaniaapp;
Public class deletemovie extends mediamaniaapp {
PRIVATE STRING MOVIETITETLE;
Public static void main (string [] args)) {string title = args [0];
Deletemovie deletemovie = New deletemovie (Title);
DeleteMovie.executeTransaction ();
}
Public deletemovie (String title) {
MovietiTitle = Title;
}
Public void execute () {
1 Movie movie = prototypequeries.getMovie (PM, MovietiTitle);
IF (movie == null) {
System.err.Print ("Could Not Access Movie with Title of");
System.err.println (movietitle);
Return;
}
2 set cast = moVie.getcast ();
Iterator it = cast.Ist.iterator ();
While (ore.hasnext ()) {
Role role = (role) iter.next ();
3 actor actor = role.getactor ();
4 actor.removerole (roule);
}
5 PM.DeletePersistentall (CAST);
6 pm.deletepersistent (movie);
}
}
We also need to delete all the roles of the movie, in addition, we also need to delete these references since the actor instance contains references to the role instance. Dow 2 we get the Role instance collection related to the Movie instance, then traverse each role, get the actor it associated with the row 3, because we have to delete this role, so we will remove the actor's reference in the row 4 . Dow 5 we call DeletePersistentall () to delete all role instances in the role table of the movie. When the transaction is submitted, the movie instance and related role instances are deleted from the database, and all actors associated with the movie are also updated, thereby no longer contain references to these deleted roles.
You must call these DeletePersistent () methods to explicitly delete instances in the database, which is not the reverse method of makepersistent () because MakePersistent () uses a rule of reachability storage. Further, JDO's database does not have a garbage collection mechanism in Java to allow an instance to be automatically deleted when it is not referenced by other instances in the database. Realizing equivalent garbage collection mechanisms is a very complex procedure, and such systems often become low performance.
summary
You have seen that an application with a certain size can be written independently of JDO, using traditional Java modeling, grammar, and programming skills. You can define the information you want to save in the application based on the Java object model. When you use classes to expand or query the instances of access to the database, your code seems to have no difference with the Java program in other access to the instance. You don't need to learn other data models or access language similar to SQL, you don't need to give mapping methods between objects in memory into the database. You can fully utilize the object-oriented characteristics in Java without any restrictions (the translator's note: limits the actual still, but only affects it), including the use of inheritance and polymorphism, and these The JDBC or EJB system is impossible; you can use object models and very little code to develop applications compared to these other competitive techniques. Simple, usual Java objects can be saved to the database in a transparent manner or accessed in the database. JDO provides a very easy to get started and efficient environments to write Java applications that need to save data. Translator's note
This book "Java Data Objects" is two members of the JDO specification expert group: expert group leader Craig Russell and senior object technical expert David Jordan jointly prepared JDO entry textbook, authoritative and practical, in mid-April 2003, JDO1 .0 specification is issued by O'Reilly Press, which is officially published by O'Reilly Press. For information on this book, please see: http://www.oreilly.com/catalog/jvadtaobj/chapter/index.html
(If you are interested in the book, and hope to see the Chinese translation of the book, please email O'Reilly Chinese Publishing House to express your opinion and opinion: info@mail.oreilly.com.cn)
The copyright of this article belongs to the author, but welcome to reprint, the premise is to indicate the source and the original. In addition, welcome to some of my articles in my column, and make valuable comments!