What are JDO's help for development-instance parsing?

Source: Internet
Author: User
Document directory
  • 1. Division of rights and responsibilities: Business Development Group and Database Management Group
  • 2 UML entity class diagram
  • 3 transparent storage
  • 4. flexible query: jdoql vs SQL
  • 5 long strings
  • 6. Resource Recycling: PM. Close ()
  • 7. ID and Object Model
  • 8 buffering and optimistic transaction
  • 9 jdbc2.0 and jdbc3.0


What are JDO's help for development-instance parsing?

(The copyright of this article belongs to the author. You are welcome to repost it, but you must specify the source and original author)

1. Division of rights and responsibilities: Business Development Group and Database Management Group

For a project, the development team is logically divided into two parts: Business Development Group and database management group. The two have their own characteristics and responsibilities, but their boundaries are clear and there will be no entanglement between them. The following table describes the differences between the two:

Personnel Composition
Business Development Group system analyst and programmer.
Database Management Group dBA and operation and maintenance personnel. Generally, one or two people can, and can span multiple projects.

Work content
The Business Development Team designs data class diagrams, designs business logic interfaces, and implements them using code (generally in a class similar to sessionbean)
The Database Management Group maps data tables through data class diagrams. Generally, you only need to make a slight adjustment to the table structure automatically generated by JDO.

Required knowledge and tools
Business Development Team UML, Java, JSP, Ant. The tool can be any IDE.
The JDO principle of the database management group, the class diagram in UML, and the connection pool configuration. Tools include powerdesigner, database access tools, and details of the specific JDO products used

What are their responsibilities? Lt; br> the Business Development Team submits the UML entity class diagram of the data section to the database management group and some details (such as whether a property is a long string ). Call the persistencemanagerfactory connection pool in the code.
The database management group establishes a corresponding database based on the UML class diagram and business development team's suggestions on some details (basically automatically completed), and configures the corresponding JDO persistencemanagerfactory (a J2EE connector, just like configuring a database connection pool)

Workload
The Business Development Group is related to the business, because the main amount of code is in the business logic.
The database management group is generally not large, but it may take some effort to import data from the old database, but it is only a one-time task.

Work required for function changes involving Data Structure Changes
On the one hand, the Business Development Team adjusts the UML entity class diagram and submits it to the database development team. On the other hand, the business logic code is rewritten according to the new function requirements.
The Database Management Group adjusts the database structure based on the new UML entity class diagram (some JDO products can be completed automatically ). The server configurations remain unchanged.

Because the work for the database management group is relatively simple, but just a matter of quantity, the following introduction does not involve the work of the Database Management Group as much as possible, but only for the business development group.

2 UML entity class diagram

A uml entity class diagram is a part of the data involved in a project. The data is not lost as the program is aborted. It is called a sustainable (persistent), and the data in all databases is sustainable.
At the beginning of our design, we should analyze the entity classes (that is, sustainable data classes) in the system to draw the entity class diagrams. In this elementary class chart, you can not include any attributes, but must include the relationship between entity classes so that you can see the approximate outline of the system at a glance.
The following is a simple demonstration object class diagram, which is a diagram of the main entities in a forum.

Simply put, a project is composed of some relational entity classes, control classes for processing business logic, and border classes for input/output data. In addition, some interfaces or special services may be added, such as text message/Email sending or third-party data access interfaces.
With the above figure, the DBA will be clear about the data tables in the database and how the tables are associated. However, tables in the database do not correspond to entity classes one by one. For example, for a Multi- ing relationship in an object class diagram, the database must have an additional table to correspond to, and some attributes of some objects may be placed in another additional table to enhance performance.
The next step is to add attributes to the object class based on the graph, and then add accessors (getxxx ()/isxxx () and setxxx () to each attribute ), and some necessary methods (such as getage (), get the age through the current date and birthday ). In this way, it becomes a complete object class graph. Is an object class graph that adds common attributes.

Next, add the accessor method for common attributes, and add another member. getage () method. This entity class graph is complete. These processes are simple and many tools can be automatically completed.
One thing to note is that for entity classes, as long as this diagram is given and corresponding Java class code is generated using tools, the code of these classes is complete, you no longer need to write code in it.

3 transparent storage

For developers, they mainly focus on the implementation of business logic, which requires some control classes to implement these logics. These control classes can generally be named in xxxsession mode to indicate the control classes for a certain type of users, such as membersession, which completes some functions after Member logon; adminsession is used to complete some functions after Administrator Logon.
In one of these control classes, you only need to use the JDO standard interface class (javax. JDO. *) to obtain access to the previous entities, so as to complete business functions. A typical method is as follows:

How to post a topic for a membersession:


PublicTopic posttopic (String title, string content, string forumid ){
// Start the business logic process
Javax. JDO. persistencemanager PM = getpersistencemanagerfactory (). getpersistencemanager ();
PM. currenttransaction (). Begin ();

// Set basic attributes for a topic.
Topic topic =NewTopic ();
Topic. settitle (title );
Topic. setcontent (content );
Topic. setposttime (NewDate ());

// Obtain relevant forums and currently logged-on Members
// The following this. logonmemberid is the member ID that must be provided when the membersession object is generated.
// This membersession object is generally generated during logon.
Forum = (ForUM) PM. getobjectbyid (PM. newobjectidinstance (Forum.Class, Forumid ));
Member author = (member) PM. getobjectbyid (PM. newobjectidinstance (member.Class,This. Logonmemberid ));

// Set the Forum and author for this topic
Topic. setforum (ForUM );
Topic. setauthor (author );

// Mark as to be stored
PM. makepersistent (topic );

// By The Way, modify the attributes of the Forum and the author.
Forum. settopiccount (Forum. gettopiccount () + 1 );
Author. setpostcount (author. getpostcount () + 1 );

// Business logic process completed
PM. currenttransaction (). Commit ();
PM. Close ();
}

In this way, this method is finished. We can see that you only need to place the Code related to the object class between the start and commit of PM. currenttransaction.
The only intermediate interface that needs to deal with JDO is to call PM for the newly generated object (topic. makepersistent (), but in many cases, as long as the object retrieved from the PM points to this object (for example: Author. getposttopics (). add (topic) does not require this statement at all (of course, it is true), because PM will reachability) stored the newly generated objects that can be directly or indirectly indicated in the database.
The code above demonstrates that we do not have to call the UPDATE function for each object that has changed, because the jdo pm will automatically track these changes and synchronize the objects that have actually changed to the database. This is "transparent storage ".

4. flexible query: jdoql vs SQL

Jdoql is the query language used in JDO and an object-based query language. It is similar to oql and ejbql, but does not have the disadvantages that ejbql can only be static.
The advantages of the object-based query language are described in many articles. Only one note: jdoql is based entirely on the UML entity class diagram and does not need to care about any content in a specific database.
Here are some examples to illustrate this flexibility.

4.1 examples: search for all forums posted by an author

We only provide the author's name as the parameter. We hope to obtain all forums where he has posted or replied to the topic. We need the following jdoql condition: the target of the query is the forum class, and then the jdoql filter string.
This = _ topic. forum & (_ topic. author. name = "<author name>" | _ topic. contains (_ reply) & _ reply. author. name = "<author name> ")
Then, declare the variables used: topic _ topic; reply _ reply;
Run the SQL statement. The general JDO product will optimize the query as much as possible:

Select a. <The most common field group that can be predefined> from Forum A, Topic B, reply C, member D

Where. forum_id = B. forum_id and (B. member_id = D. member_id and D. name = '<author name>' or B. topic_id = C. topic_id and C. member_id = D. member_id and D. name = '<author name> ')

From the above, we can see that jdoql is far better than SQL in terms of readability and maintainability. We can also use the author's name as a binding parameter, which makes it easier.
If you operate SQL directly, it will become very troublesome. On the one hand, you should pay attention to the attribute names in the object class and the corresponding fields in the database, because in most cases, the spelling of the two is different because of various factors (such as database keyword conflicts.
We can further expand from this example:

4.2 examples: search for all forums posted by an author, where the total number of posts is greater than 100 and the author has earned his/her favorites.

Write the filter string as follows:
This = _ topic. forum & (_ topic. author = _ author | _ topic. contains (_ reply) & _ reply. author = _ author) & amp; _ author. name = '<name of the author>' & postcount> 100 & _ author. favoriteforums. contains (this)
This time, one more variable is used: Member _ author. The underlying SQL can be simulated by yourself.

5 long strings

We often encounter a text string entered by the user that exceeds the size of the specified data field, which makes it very difficult to process, especially some strings that do not have to limit the length, for example, the content of a topic article may contain tens of thousands of characters, which forces us to split it into many sub-records and place a portion of each sub-record. All of this increases the amount of code and maintenance.
Now with JDO, our code is much simpler. We may try to use the transparent storage feature provided by JDO to implement it through some simple tool classes: the principle is to split the string into substrings.


PackageJdo_util;
ImportJava. util .*;

Public ClassStringhelper {
Public StaticList setlongstring (string value ){
If(Value = NULL)ReturnNULL;
IntLen = value. Length ();
IntCount = (LEN + partSize-1)/partsize;
List list =NewArraylist (count );
For(IntI = 0; I <count; I ++ ){
IntFrom = I * partsize;
List. Add (value. substring (from, math. Min (from + partsize, Len )));
}
ReturnList;
}

Public StaticString getlongstring (list ){
If(List = NULL)ReturnNULL;
Stringbuffer sb =NewStringbuffer ();
For(Iterator itr = List. iterator (); itr. hasnext ();) sb. append (itr. Next ());
S = sb. tostring ();
ReturnS;
}

Private Static IntPartsize = 127;// The size of the string segment. For different databases, such as Oracle 2000
}

With this class, we only need to set the topic. the content type is changed to list, and its access interface remains unchanged. It is still string, but the content is changed: (and the element type of the List is specified in the JDO descriptor as string)


Public ClassTopic {
...
List content;// Original string type
...
PublicString getcontent (){
ReturnStringhelper. getlongstring (content );
}

Public VoidSetcontent (string value ){
Content = stringhelper. setlongstring (value );
}
}

In this way, the problem of long strings is solved, and other related Code does not need to be changed at all, which supports the infinite length of theme content.
Finally, the only drawback is that you need
Content. startswith ('% <keyword> ')
Change
Content. Contains (s) & S. startswith ('% <keyword> ')
In addition, the query results may not be accurate (for example, the query results span exactly two substrings ). Fortunately, the query requirements for long string fields are generally not too many.
It should be noted that the use of traditional SQL also requires extra queries on the split string, and has the same disadvantages.
In addition, this feature requires an optional option in the JDO Product Support specification: javax. JDO. Option. List, which is supported by several major JDO products. For example, kodojdo and jdogenie.

6. Resource Recycling: PM. Close ()

When we use traditional SQL to write code, the most dangerous issue is resource release, which is particularly important in Web-based applications. Because JDBC-related resources are not allocated in the Java virtual machine, but are allocated at the underlying system level, Java's garbage collection mechanism is overwhelmed, resulting in slow system memory consumption and crash.
Resources that need to be released in JDBC include connection, statement, preparedstatement, and resultset. When assigning values to these types of variables, the previous resources must be released. It is undoubtedly a tedious and easy to be ignored.
In JDO, things become much simpler, and all resources are in PM. close () will be automatically released (unless the JDO product adds cache for preparedstatement and resultset), which is the requirement of JDO specifications. Therefore, you only need to remember to call pm. Close () when processing the object class. For example, the following code:


Persistencemanager PM = NULL
Try{
PM = getpersistencemanagerfactory (). getpersistencemanager ();
// Perform data processing

}Finally{
PM. Close ();
}

Some people may just dislike calling it and feel bored because a PM should be opened every time and closed when used up. If the JDO product does not have a PM connection pool, performance may be affected. In this way, we can use the tool class inheriting java. Lang. threadlocal below to accomplish this:


Public ClassPersistencemanagerretrieverExtendsThreadlocal {
/**
* Initialize a persistencemanager reader based on the configuration information.
* @ Param P
*/

PublicPersistencemanagerretriever (Java. util. properties p ){
PMF = jdohelper. getpersistencemanagerfactory (P );
}

/**
* Obtain the relevant persistencemanagerfactory
* @ Return a persistencemanagerfactory object
*/

PublicPersistencemanagerfactory PMF (){
ReturnPMF;
}

/**
* Obtain a persistencemanager related to the current thread.
* @ Return a persistencemanager object
*/

PublicPersistencemanager PM (){
Return(Persistencemanager) Get ();
}

/**
* Release all JDO resources related to this thread
*/

Public VoidCleanup (){
Persistencemanager PM = PM ();
If(PM = NULL)Return;

Try{
If(! PM. isclosed ()){
Transaction Ts = PM. currenttransaction ();
If(TS. isactive ()){
Log. Warn ("an unfinished transaction [" + PMF. getconnectionurl () + "]! "+ TS );
TS. rollback ();
}
PM. Close ();
}

}Catch(Exception ex ){
Log. Error ("error occurred when releasing JDO resources:" + ex, ex );

}Finally{
Set (null );
}
}

PublicObject get (){
Persistencemanager PM = (persistencemanager)Super. Get ();
If(PM = NULL | pm. isclosed ()){
PM = PMF. getpersistencemanager ();
Set (PM );
If(Log. isdebugenabled () log. debug ("retrieved new PM:" + Pm );
}
ReturnPM;
}

Public Static FinalLogger log = logger. getlogger (persistencemanagerretriever.Class);
PrivatePersistencemanagerfactory PMF;
}

In this way, you only need to call


persistenceManagerRetriever.pm();

In addition, persistencemanagerretriever. Cleanup () is called only once after it is used up.

This persistencemanagerretriever can be added to the initialization code of a system class:


PersistenceManagerRetriever persistenceManagerRetriever = new PersistenceManagerRetriever(properties);

You can configure a jspfilter to close the PM Statement (persistencemanagerretriever. Cleanup () related to the current thread, for example:


public static class JspFilter implements javax.servlet.Filter {
public void doFilter(
javax.servlet.ServletRequest request,
javax.servlet.ServletResponse response,
javax.servlet.FilterChain chain)
throws javax.servlet.ServletException,java.io.IOException {
try {
chain.doFilter(request,response);
} finally {
if(pmRetriever != null) pmRetriever.cleanup();
}
}
public void init(javax.servlet.FilterConfig filterConfig) throws javax.servlet.ServletException {}
public javax.servlet.FilterConfig getFilterConfig() { return null; }
public void setFilterConfig(javax.servlet.FilterConfig fc) {}
public void destroy() {}
}

Then we configure it in the webapp descriptor:


<filter>
<filter-name>jdo_JspFilter</filter-name>
<filter-class>…xxx.jdo_util.JspFilter</filter-class>
</filter>

<filter-mapping>
<filter-name>jdo_JspFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>

In this way, the code in JSP is simpler:




persistenceManagerRetriever.pm().currentTransaction().begin();

// Call some xxxsession. somemethodthatusespm () methods that process business logic. These methods directly use persistencemanagerretriever. PM () to obtain PM.

Persistencemanagerretriever. PM (). currenttransaction (). Commit ();

No exception to be processed. jspfilter will handle the exception.

7. ID and Object Model

The object identification field is actually a field of the database category. These attributes are not required in the object model. That is to say, in a Java application, the identifier of an object is the address in the memory, which is not the attribute of the object itself, because the object can be uniquely identified based on the memory address. For example, after a Java program editing vector maps reads map elements (objects) from a file, these objects have a unique memory address, therefore, you do not need to add a property similar to "ID" to each object and write it to the file.
JDO also adopts this concept. IDs are independent of objects and are not part of objects. We can see in the previous graph of the Forum entity class that each class has no attributes such as "ID. So how does JDO control the correspondence with the primary key in the database? There are two common tool methods:
Object persistencemanager. getobjectid (Object OBJ)
Object persistencemanager. getobjectbyid (Object OBJ, Boolean validate)

In this way, you can get the ID of an object at any time, or you can find the object at any time through an ID. The first method can also be replaced by javax. JDO. jdohelper. getobjectid.
In the mode recommended by the JDO specification, these IDs are automatically generated by the JDO product. In a project application, these IDs are used only when an object is referenced, for example, transmitted between two pages. In addition, these id classes can be exchanged with strings, which facilitates the transmission between JSP. The ID controlled by the JDO product is called datastore identity, and the field name in the data table is generally "jdo_id ".
If you really want to control the ID of the object in the database by yourself, JDO also provides the User-Defined ID. At this time, this ID exists as an attribute of the object, which can be of any type, Int, date, string, or other custom composite types (such as the combination of two attributes as IDS ). This type of ID is called application identity.
Personally, I suggest using datastore identity in a new project, which saves a lot of time. In Entity classes, you can also write alternative methods to maintain compatibility with application identity, such:


public class SomePersistentClass {

public String getId() {
return JDOHelper.getObjectById(this).toString();
}

public static SomePersistentClass getById(String id) {
PersistenceManager pm = persistenceManagerRetriever.pm();
return pm.getObjectById(pm.newObjectIdInstance(SomePersistentClass.class, id));
}
}

This method is valid for both types of IDs. Note that this class has these two methods, but there is no ID attribute.

8 buffering and optimistic transaction

Caching is a highlight of JDO. Although the JDO specification does not strictly require any buffer for a JDO product, almost every JDO product, especially commercial product, has a sound buffer system, this system is one of the key points of competition between different JDO products.
The main JDO products include the following buffers:
1. PM connection pool. Buffer persistencemanager. Similar to the JDBC connection pool, when calling pm. Close (), it does not close, but waits for the next call or timeout.
2. preparedstatement buffer. If a jdoql statement is found to be the same as a previously used sentence at the bottom layer of JDO, a new preparedstatement is not re-analyzed and generated, but an existing statement in the buffer pool is used. Caching preparedstatement is also a function in jdbc3.0 specifications. The bottom layer of JDO finds that if the driver is configured to comply with the jdbc3.0 specification, the driver buffer will be used; otherwise, the buffer will be used.
3. resultset buffer. There are not many JDO products for this buffer implementation. Currently, it seems that only kodojdo 2.5.0 beta is implemented. The mechanism is that when the second request executes the same jdoql statement and query with the same parameters, the JDO underlying layer extracts the set from the previous execution results and returns it directly, greatly enhancing the performance. However, it is resource-consuming because scrollableresultset in jdbc2.0 is used.

Generally, when we update a database, we will lock the database and set different isolation levels to complete different degrees of locking, such as lock records, lock fields, lock tables, and lock databases. JDO can be set in the vendor extension tag of a specific JDO product. In addition, the JDO specification also provides a method that does not lock the database at all: javax. JDO. option. optimistictransaction is an optional option, that is, it does not force the JDO vendor to implement it, but the JDO products of several major vendors all implement this function.
The principle of optimistictransaction is to add a transaction control field to the database record of each object, and then all the object changes are completed in the memory of the Java Virtual Machine. When submitted, this control field is used to check whether the modified object has been modified by other external programs after being retrieved from the database. Generally, this field can be implemented in the following ways:
1. Store the time of the last change, and use multiple field names as "jdo_last_update_time"
2. Store the number of times that have been changed in history, and use multiple field names as "jdo_version"

In a transaction of optimistictransaction, the underlying layer of JDO does not lock the database, which ensures that transaction with a long time span does not affect the execution of other threads (requests, however, if the number of update operations is large and the access volume is large, the probability of failed transaction submission will also increase.

9 jdbc2.0 and jdbc3.0

JDO is only an object-Level Packaging built on JDBC, and the two cannot be replaced by each other. In fact, JDBC specifications have been improving functions and performance from 1.0 to 2.0, and then to 3.0.
Of course, the JDO product will not let go of this. The general JDO product will check which specification the JDBC driver is configured at the underlying level, and will try its best to use the driver's own functions to implement specific operations. For code developers, we can only master jdbc1.0 operations and a small number of 2.0 operations in most cases. Only some experts proficient in JDBC can use advanced functions in jdbc3.0. Therefore, using JDO can also help us improve performance and efficiency without understanding the jdbc3.0 specification.
In other words, JDBC technology itself is a very complicated thing. to optimize performance, many JDBC and database technologies need to be used, such as inner join, left/right Outer Join, batch update, and so on. These have high technical requirements for developers. On the one hand, we must precisely understand the application scope and actual usage considerations of each technology, and on the other hand, the code will be more complex. Therefore, since many experienced JDO vendors are doing these things, why bother us?

I have introduced several obvious advantages of JDO for the development of our database projects. In future articles, I will continue to write about the conceptual issues in the use of JDO and the configuration and use of specific JDO products, as well as some tips.
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.