JDO experience of a New York Female Technician

Source: Internet
Author: User
Tags stock prices
Document directory
  • Overview
  • An object storage example
  • Store a book object using JDO
  • Comparison of the two versions (JDBC vs JDO)
  • Conclusion
  • JDO attribute Configuration
  • Still imperfect
  • Introduction
  • Source code:
  • Diagram
  • Comments


JDO experience of a New York Female Technician

Introduction to JDO applications
By Teresa Lau
Translated from: http://www.sys-con.com/java/articleprint.cfm? Id = 1899

This article describes the principles, usage, and features of JDO based on an actual relational class structure instance and kodojdo product. Especially in comparison with the traditional JDBC technology, for example, the reality that the code of a class is reduced from 480 lines to 140 lines indicates that JDO reduces the code. In addition, the author of this article is a girl with more than five years of experience as a Java consultant. She has a master's degree and is currently working in New York.

Java Data Object (JDO) is a standardized API used to access objects in a data warehouse.

What makes JDO stand out from various Data Object Access Technologies is its high ease of use and flexibility.

JDO provides transparent object storage. Therefore, for developers, no additional code (such as the use of JDBC APIs) is required to store data objects ). These tedious routine work has been transferred to the JDO product provider, freeing developers to concentrate their time and effort on business logic. In addition, JDO is flexible because it can run on any data underlying layer. JDBC is only intended for relational databases (RDBMS distributed do is more common and provides underlying storage functions for any data, such as relational databases, files, XML, and object databases (odbms, makes applications more portable.

Introduction Descriptor (metadata) and Enhancer)

In JDO, any class that needs to be stored must be persistencecapable, and any other class that uses these classes must be persistenceaware (known for storage ). It looks a bit complicated, but the good news is that you don't need to implement your class in the code to implement the javax. JDO. persistencecapable interface or persistenceaware interface. You only need to write a class as usual. The JDO manufacturer will provide an enhancement tool which will transform your class code. the transformation of the binary code in the class file is not very advanced. There are many tools available for you to transform the class file, for example, output logs at the beginning and end of a method), implement the persistencecapable interface based on your descriptor. The only extra work you need to do is to write an XML format descriptor file for the classes you need to store. Appendix 1 shows a descriptor file that will be used in subsequent code demonstrations. (Attachment 17 and the code in this article can be downloaded at www.sys-com.com/java/sourcec.cfm .)

Generally, descriptors are very short. It is not difficult to write them by default. JDO has obtained a lot of information from the class itself. You only add additional information to the descriptor in the following cases:
. You need to change the default operation method of JDO, for example, to make an attribute not stored in the database, even if it is not marked as transient
. Some additional information is that JDO cannot be obtained from the class itself, for example, which attribute you want to set as the primary key in the database (Note: This is necessary only when application identity is enabled ), or what is the element type in a collection type (collection or sub-interface/class )?

Storage Manager (persistencemanager)

When your class is enhanced, you may use persistencemanager to store your object. To obtain a persistencemanager, you must first set some attributes, which usually include the following information:
. Database connection information
. JDO product class name
. Default attributes, including connection pool size

Row 23rd in Attachment 3 shows how to set a properties object to obtain a JDO persistencemanagerfactory (equivalent to datasource In the JDBC connection pool), and then obtain a persistencemanager object (equivalent to the connection object in JDBC ), then, you can use this persistencemanager object to add, update, delete, and query objects (which will be discussed later ). After you complete these operations, you need to close the master persistencemanager object to release it so that it can be used again (such as another thread ).

The code snippet in Attachment 3 tells you to use JDO to store and query objects. Using a persistencemanager object pm, you can use the PM. makepersistent () method to save a new object to the database (Row 1 ). An object must be saved to the database only when it appears for the first time (Note: more strictly, you must explicitly call makepersistent () only when there is no reference to the stored object () method), when it already exists in the database, you can directly update the object information by accessing its properties. All updates are saved to the database when the current transaction (Database concept: transaction) is committed. If you do not want to save the changes to the master, simply roll back the current transaction (lines 15th to 17 ). Similarly, you can call pm. deletepersistent () to delete an object (26th rows ).

To access an object that has been stored, you can simply traverse its extent (all extensions of the class), which is a logical term for this class of objects (12th to 15 rows ).

If you want to selectively retrieve a subset of all objects of a class, you can create a query ). To do this, call pm. newquery () to obtain a query object and pass in parameters: a set of candidate objects and a filter. The candidate object set can be a collection or extent of a class. The filter is a jdoql (JDO Query Language) statement. After you create this query, You can execute it to obtain a set that meets the conditions (collection, 22nd to 26 rows ). Jdoql is the query language of JDO. It is a bit like SQL, But it follows the Java syntax. The example here is just a simple example. With jdoql, your filter string can be very complex. In addition, if you use the bound parameter in the filter string, you can write a simple query and execute it multiple times, and each time a new parameter value is given. For more information about jdoql, see the resource list in this article.

An object storage example

To check whether JDO is as good as Sun said, I will write some code and use JDO and JDBC to store the book object I created (see appendix 4 ). This book object has a name attribute and a block object. To make the example interesting, there is a limit on the book object: Each book is uniquely identified by its name. That is to say, you cannot add two books with the same name.

A block is a part of a book. It can be a document, chapter, or section. The top-level block is of the document type and can include any number of chaptor blocks. Each chaptor block can contain any number of setion blocks. Therefore, these blocks have a nested relationship. In each block, we use a hashmap to store any number of key-value pairs of other blocks.

Appendix 5 lists a book used for testing in my example. This book consists of two chapters: Chapter 1 and section 2. In particular, chapter 2 has an attribute: color = Red.

Using the example of this book, I want to implement the following storage function:

. Add: check if I can successfully add two books to the database. If I add a third book with the same name, an exception occurs when the name uniqueness check fails.
. Update: check if I can update a book: Add a property "comment" to its root block. When I submit (COMMIT), these updates should be saved, and if I roll back, these updates will be discarded.
. Delete: Check whether a book can be queried through query and then deleted from the database.

Without JDO, I usually design like this: first design several related relational data tables to store the data in the book, and then use SQL and JDBC to store/read these tables. Due to the length, I will not list my JDBC implementation here, but if you are interested, you can download it from the jdj website. Note: To implement these functions through JDBC/SQL, I have to write a long piece of code (480 lines !). What I want to do now is to show you how easy it is to use JDO to implement the same function.

Store a book object using JDO

When I use JDO to store a book object, although I use the same book primary key class as the JDBC Method, the ID attribute of the block is completely unnecessary. In JDBC mode, you must use the ID attribute to reference different blocks in the data table. But in JDO, I don't need this attribute at all, because JDO will automatically process it at the underlying layer.

To indicate that the book object needs to be stored, I wrote a descriptor to mark the book and block classes (see appendix 1 ). In the descriptor, the children set attribute of the block class indicates that its element type is block (10th to 11 rows ), the key and value types of hashmap are both string (lines 12th to 14 ). In addition, because the ID attribute is not really required by the block, I indicated in the descriptor that it does not need to be stored (8th rows ). In the descriptor segment of the book, I indicate that the nm (name) attribute is its primary key (5th rows). Therefore, the book class needs to use a custom identity (application identity ), the class name is bookkey (4th rows ). For the code of the bookkey class, see appendix 6.

In this example, the JDO product I use is kodojdo (using relational databases as the underlying layer ). There are many JDO products on the market (implementation); you can choose any of them, and your code does not need to be changed. For the underlying relational database, I chose enhyda instantdb (a relational database attached to the Kodo product ). The essence of JDO is that developers do not need to know how a JDO product stores data into a database, so I do not need to design any data tables, even though we use relational databases at the underlying layer. Kodo provides a tool named schematool to automatically create the required data table structure based on my descriptor. All I need to do is run the following command to prepare the underlying database (Note: In fact, kodojdo2.4.0 and later versions can complete automatic Database Synchronization. This step can be omitted. However, we recommend that you use it only during development ):
Schematool action refresh book
Schematool action refresh Block

Next, I will compile my class normally, and then use the Kodo enhancer named jdoc to enhance my class code: these steps can be completed using ant batch processing tools, and most JDO vendors provide ant task support ):
Jdoc book
Jdoc Block
Jdoc bookpersistjdo

Here, as long as I move the Unreinforced class file (book. class, blockpersist. class, bookpersistjdo. class) and descriptor are placed in a location that can be found in jdoc, jdoc will change these class codes to persistencecapable, and classes not marked as storage will be enhanced to persistenceaware. In this example, Book. Class and block. Class are transformed to persistencecapable, while bookpersistjdo. Class is transformed to persistenceaware. (Note: It should be noted that most of the opinions advocate that non-storage classes only access the attributes of the stored objects through accessors (that is, the get/set/is method, in this way, these non-storage classes do not need to be reinforced at all to reduce complexity .)

After these classes are enhanced, any operation on my objects can be completed through persistencemanager. With the code I mentioned above, I can easily get a persistencemanager pm and use it to add, delete, and update a book. Appendix 7 shows the code snippet of my bookpersistjdo. java. The method in addbook (row 3rd) demonstrates how to add a book through JDO, while deletebook (row 13th) demonstrates how to delete a book.

To retrieve a book by name, I created a query using the jdoql filter. After executing this query, I get a set of objects that meet the condition (Collection) (rows 25th to 29 ). After obtaining a book object, I directly change its attributes and then submit the object.

Appendix 3 shows the test results of my JDO method example. The result is as expected. First, I successfully added a book to the database, and then added another book with the same name. The result is a jdouserexception, which indicates that the rule of name uniqueness is violated. Next, I can update the information of a book, submit the updates, or discard the updates through rollback. Finally, I can find a book by name in the database and delete it.

Comparison of the two versions (JDBC vs JDO)

Using JDO and JDBC to solve the same problem, I observed the following:
1. Using JDO, I can do the same thing as JDBC. I can use jdoql to query objects. By marking the NM attribute of the book class as the primary key, I can ensure that the certificate name is unique. In addition, I can add, delete, and update these objects.
2. JDO makes transaction processing easier. In the JDBC Method, because a book is actually mapped to many records in four different relational data tables, I must ensure that all the insert and delete operations are completed in the same transaction. On the contrary, JDO only needs one operation to save all these changes, and I do not need to use transaction to maintain the atomicity of this operation.
3. bookpersistjdo. Java has only 140 rows, which is much less than bookpersistjdbc. Java (480 rows). All of these facts show that JDO makes my code much less. In particular, the nested relationship between my classes makes the table structure in relational databases more complex. In my JDBC implementation, I had to spend a lot of time designing my database to store and obtain these nested data. I have to use an ID field to represent each block and use a foreign key to express the parent/child relationship. In JDO implementation, I don't need to consider these issues at all, and everything is properly stored.
4. The buffer mechanism I add to JDBC implementation to improve performance is not required in JDO, because JDO products generally include performance optimization and buffering. This also saves me a lot of work, because I don't need to worry about whether my buffer is always synchronized with the database.

In addition to these differences, the JDO product and my JDBC implementation may be slightly different. For example, this JDO product uses a relational database and may also adopt a similar table structure design and ID generation mechanism, and uses JDBC to store data. However, the key is that I don't need to know the details of these implementations: these burdens are transferred to professional JDO vendors, who prefer to do better in these details. In addition, these vendors can freely choose to implement storage in other types of storage technologies, such as object databases or files, these give us great flexibility in choosing a specific storage method.

Conclusion

JDO provides many benefits:
. It has all required data storage functions: add, delete, modify, transaction, data uniqueness, Buffer
. It removes a lot of tedious work from developers, making the code easier to read and maintain.
. It is independent from specific vendors and prevents vendor dependencies.
. Although my code is not displayed, it can work in any data warehouse to make development flexible and portable

JDO is a valuable technology. This article is just your starting point. For more information, see the following resources.

Resources

. All-in-One Website: http://www.jdocentral.com/
. Standard: http://access1.sun.com/jdo/
. Roos, R. (2002 ). java data objects. addison Wesley Press: http://www.ogilviepartners.com (Translator's note, I have a pdf version from the author of this book for me that can be shared with everyone, but not for commercial purposes)
. The example of the JDO product used in this article: solarmetric: http://www.solarmetric.com/Software/Kodo_JDO. The development team of this product is basically from MIT. Kodojdo has the following Disadvantages: Unlike the jdogenie product of hemiscript in South Africa, kodojdo has an independent descriptor editing tool that can only be used with jbuilder7 or later. However, at my suggestion, they are going to add this tool to version 3.0 .)

JDO attribute Configuration

Attachment 2 provides the property files I will use later. I used a relational database. Row 14th contains the database connection information. The second line contains the Class Name of the JDO product I used (Translator's note: the vendor's implementation class for persistencemanagerfactory ). Rows 8th to 10 are the default settings for persistencemanager, indicating that I use optimistic transaction and that data can be restored from the buffer during rollback. These values are not retained during submission: the purpose is to ensure that the Updates generated by triggers in some databases can be read back from the database ). There are still many details about which options can be used for transaction. Read the JDO APIs to find their meanings and use them as needed.

JDBC implementation

Here I will briefly describe how to store the book class through JDBC. After knowing how much work is involved, you will better understand what JDO has done for you.

I created four tables to store books (see figure 1 ). To ensure data uniqueness, the NM field of the book table is marked as a single index ). To track the attributes and subsets of each block, I added a blockid field for each block. This blockid field is generated when each block is added to the database (add 1 to the blockid value in the largest block table already exists ).

Adding a book involves breaking the information of a book object into four tables: Book, block, blockrelation, and blockattr. In particular, each block needs to generate a blockid. Furthermore, blocks is nested or recursive. I have to write recursive code to insert the data into the database.

In the example of creating a book in Attachment 5, these data tables are displayed in Figure 2. As you can see, a book is converted into many rows in four tables. Therefore, all the insert operations must be packaged in a transaction, in this way, you can ensure that a book is fully added or completely canceled and will never be incomplete. Similarly, deleting a book involves finding all the appropriate rows to be deleted from the four tables and deleting them in a transaction to ensure that the book is completely deleted or deleted.

For better performance, I don't want to recursively retrieve data from four tables every time someone needs to query a book. I created a bookcache to retrieve all the books from the database when the application starts running. When I add, delete, and update these books, my Code ensures that the bookcache is synchronized with the database. All this work is done in this cache so that you can simply search for a book by name in the cache.

Still imperfect

Aside from the advantages mentioned above, there are some other aspects that JDO is not enough to do:
. It is good for new projects, but if you want to use JDO for existing relational databases, you need to do more ing work (edit descriptor)
. For developers, after using JDO, we no longer need to process the underlying database access, so performance optimization may be more difficult than the original. Because JDO has to do a lot of extra work, such as tracking changes in object attributes to synchronize internal buffering, and so on, how does JDO product play a critical role in performance?
. Jdoql does not support aggregate operations, such as Max, Min, and sum. (Note: Chapter 24th of the jdo1.0 specification describes in detail what the next 2.0 specification should do, including this)
. It would be much better if jdoql errors can be found during compilation. For example, in a filter string, you can specify an attribute name through a string. You can easily write an error name, but the compilation will not go wrong, so it will only go wrong at runtime. (Translator's note: SQL also has the same problem)
. Some people think that the advantage of JDO is that you do not need to write any more SQL statements, but the real situation is that you must learn jdoql.

Introduction

Teresa Lau has been an independent Java consultant for more than five years, focusing on financial systems. She has a master's degree in computer science and is currently working in New York.

Source code:

Listing 1 metadata for my example

1 <? XML version = "1.0"?>
2 <JDO>
3 <package name = "WHS. JDO">
4 <class name = "book"
Identity-type = "application"
Objectid-class = "bookkey">
5 <field name = "Nm"
Primary-Key = "true"/>
6 </class>
7
8 <class name = "Block">
9 <field name = "ID"
Persistence-modifier = "NONE"/>
10 <field name = "children">
11 <collection
Element-type = "Block"/>
12 </field>
13 <field name = "attributes">
14 <map key-type = "string"/>
15 <MAP value-type = "string"/>
16 </field>
17 </class>
18 </package>
19 </JDO>

Listing 2 properties for setting up JDO

1 javax. JDO. Option. connectionusername =
Database User
2 javax. JDO. Option. connectionpassword =
Password of the user
3 javax. JDO. Option. connectionurl =
URL of the database
4 javax. JDO. Option. connectiondrivername =
Classname of JDBC driver
5
6 javax. JDO. persistencemanagerfactoryclass =
Com. solarmetric. kodo. impl. JDBC.
Jdbcpersistencemanagerfactory
7
8 javax. JDO. Option. Optimistic = true
9 javax. JDO. Option. restorevalues = true
10 javax. JDO. Option. retainvalues = false

Listing 3 JDO code fragment

1 // --- get persistence manager ---
2 persistencemanagerfactory =
Jdohelper. getpersistencemanagerfactory
(Property );
3 persistencemanager PM =
Factory. getpersistencemanager ()
4
5 // --- add ---
6 pm. currenttransaction (). Begin ();
7. makepersistent (OBJ );
8 pm. currenttransaction (). Commit ();
9
10 // --- iterate extent & update ---
11 pm. currenttransaction (). Begin ();
12 extent ext = PM. getextent
(Myclass. Class, false );
13 For (iterator I = ext. iterator ();
I. hasnext ();){
14 myclass OBJ = (myclass) I. Next ();
15 obj. setfield1 ("AA ");
16}
17 Pm. currenttransaction (). Commit ();
18
19
20 // --- query and delete ---
21 pm. currenttransaction (). Begin ();
22 string filter = "Nm =/" JDO book /"";
23 query qry = PM. newquery (EXT, filter );
24 collection C =
(Collection) qry.exe cute ();
25 object OBJ = C. iterator (). Next ();
26 pm. deletepersistent (OBJ );
27 pm. currenttransaction (). Commit ();
28
39 // --- Close resources ---
30 pm. Close ();

Listing 4 book & Block object

1 class book {
2 string nm;
3 block = new block ("document ");
4
5 book (string name ){
6 This. Nm = Name;
7}
8
9 void addchild (Block E ){
10 block. addchild (E );
11}
12}
13
14 class block {
15 string type;
16 integer ID;
17 map attributes = new hashmap ();
18 list children = new arraylist ();
19
20 block (string type ){
21 This. type = type;
22}
23
24 void addchild (Block E ){
25 children. Add (E );
26}
27
28 void setattribute (string key,
String ATTR ){
29 attributes. Put (Key, ATTR );
30}
31}

Listing 5 create test book

1 Book = New Book ("intro to JDO ");
2 block chp1 = new block
("Overview", "chapter ");
3 block sec11 = new block
("Advantage of JDO", "section ");
4 chp1.addchild (sec11 );
5 block chp2 = new block
("Example", "chapter ");
6 chp2.setattribute ("color", "Red ");
7 block sec21 = new block
("JDBC code", "section ");
8 block sec22 = new block
("JDO code", "section ");
9 chp2.addchild (sec21 );
10 chp2.addchild (sec22 );
11 book. addchild (chp1 );
12 book. addchild (chp2 );

Listing 6 bookkey. Java

1 public final class bookkey {
2 Public String Nm = NULL;
3 Public bookkey (){}
4
5 Public bookkey (string nm ){
6 This. Nm = Nm;
7}
8
9 Public Boolean equals (Object O ){
10 if (O = This) return true;
11 if (! (O instanceof bookkey ))
Return false;
12 Return (bookkey) O). nm. Equals (Nm );
13}
14
15 public int hashcode (){
16 return nm. hashcode ();
17}
18
19 Public String tostring (){
20 return nm;
21}
22}

Listing 7 bookpersistjdo. Java

1 class bookpersistjdo {
2
3 Public book addbook (Book)
4 throws jdouserexception {
5 persistencemanager PM = getpm ();
6 transaction TRAN =
PM. currenttransaction ();
7 Tran. Begin ();
8. makepersistent (book );
9 Tran. Commit ();
10 return book;
11}
12
13 public void deletebook (Book ){
14 persistencemanager PM = getpm ();
15 transaction TRAN =
PM. currenttransaction ();
16 Tran. Begin ();
17 Pm. deletepersistent (book );
18 Tran. Commit ();
19}
14
15 public collection getallbooks (){
15 persistencemanager PM = getpm ();
17 string filter = "";
18 extent = PM. getextent
(Book. Class, false );
19 query qry = PM. newquery
(Extent, filter );
20 return (collection)qry.exe cute ();
21}
22
23 public book getbook (string name ){
24 persistencemanager PM = getpm ();
25 string filter = "Nm =/" "+
Name + "/"";
26 extent = PM. getextent
(Book. Class, false );
27 query qry = PM. newquery
(Extent, filter );
28 collection C =
(Collection) qry.exe cute ();
29 return (book) C. iterator (). Next ();
30}
31}

Additional code for this article ZIP file ~ 7.78 KB

Diagram

Figure 1

Figure 2

Figure 3

Comments

JDO not vendor independent
Posted by Scott P. Smith on Mar 4 @ 0:27 pm

A few weeks ago, I attended a one hour talk by Oracle's ctor of technology, Donald Smith covering persistence archetectures. in it he stronugly stated that JDO is not completely vender independent. I don't know that myself. i'm just repeating what he said, which conflicts with claims made in this article.

(Read & respond ...)

--------------------------------------------------------------------------------
Author lacks JDBC knowledge
Posted by Donald bales on Mar 4 @ 07:39 pm
The whole article became tainted when the author stated :"... JDBC provides persistence only for relational databases... "Not true. JDBC can handle most of the data sources listed. in fact, implements JDO implementations utilize JDBC "under the covers ". second, JDO claims to be able to support these other data sources, but I don't see your implementations. JDO provides a slick registration for relational databases, but it's not the silver bullet that it's hyped to be.

(Read & respond ...)

--------------------------------------------------------------------------------
JDO not vendor Independant
Posted by I Davie on Mar 5 @ AM
JDO is meant to be a java standard not a database standard. Oracle are not interested in JDO because it gives developers choice and Oracle don't like that! If they're forced to move that way they will but not by choice

(Read & respond ...)

--------------------------------------------------------------------------------
Pro-JDO comments from JDO vendors
Posted by Scott P. Smith on Mar 5 @ 10:12 am
Another thing that Donald Smith (no relation) from Oracle said was that the only people making positive comments about JDO are JDO vendors. I see "I Davie" is with versant, which is soon to be a JDO vendor according to their Web site.

I am very neutral with regard to JDO. I have never used it. Can we hear comments from someone (WHO doesn

(Read & respond ...)

--------------------------------------------------------------------------------
JDO
Posted by Bret on MAR 9 @ 11: 22 pm
Http://www.sys-con.com/java/article.cfm? Id = 1899

(Read & respond ...)

--------------------------------------------------------------------------------
Anti-JDO comments
Posted by David tinker on Mar 14 @ 08:26 AM
Treat anything that anyone associated with Oracle has to say about JDO with caution. oracle own toplink, a $10 K/CPU o/R mapping tool that competes directly with JDO. if JDO is sucessful who will pay that kind of money for vendor-lock-in O/R Mapping? The most expensive JDO implementations are approx $3 K with no runtime costs.

I won't say anything about JDO as I work on JDO genie from hemisphere technologies try it for yourself!

(Read & respond ...)

--------------------------------------------------------------------------------
Non-vendor comment
Posted by Chester Arnold on Mar 24 @ 07:49 AM
I agree with David Tinker. you need to learn to try things out and not always believe vendors who are trying to salvage tanking stock prices. I 've used a number of JDO implementations including the one the article used (Kodo JDO ). the quality of JDO implementations vary widely so trying them out is probably the best thing you can do.

You can find a list of JDO implementations at www.jdocentral.com.

(Read & respond ...)

--------------------------------------------------------------------------------
Oracle fear !!
Posted by Alf on Mar 25 @ 09:57 AM
It is a matter of time. You will see that programmers prefer JDO, and Oracle will have to offer their own implementation of the JDO specification.
You can

(Read & respond ...)
--------------------------------------------------------------------------------

The copyright in this article belongs to the author, but you are welcome to repost it on the premise that the source and original author are indicated. In additionMy columnView my other articles and provide valuable comments!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.