What are the help of JDO to development - an example analysis

xiaoxiao2021-03-06  42

1 Interpretation: Business Development Group and Database Management Group

For a project, the development team is logically divided into two: business development groups and database management groups. The two have characteristics, each is responsible, but the boundaries between each other are very clear, there will be no entanglement. The following table shows the difference between the two:

Staff composition

Business development group system analyst, programmer.

Database management group DBA, run maintenance personnel. Generally, one to two can, and can across multiple items

Work content

Business development group design data class diagram, design business logic interface and use code implementation (generally in the class similar to SessionBean)

The database management group passes the data table map through the data class map, which is generally only necessary to make a little adjustment on the table structure of JDO.

Knowledge and tools required

Business Development Group UML, Java, JSP, Ant. Tools can be any IDE.

Database Management Group JDO Principle, class diagram in UML, connection pool configuration. Tools include PowerDesigner, Database Access Tools, Some Details of the specific JDO products

Mutual responsibility models? Lt; br> Business development group submits the UML entity class diagram of the data part to the database management group, and some detail (such as a string of a very long). After the other party is configured, the PersistenceManagerFactory connection pool is called in the code.

The database management group establishes a corresponding database based on the UML class diagram and the business development group (substantially automatically completed), configures the corresponding JDO PersistenceManagerFactory on the server (a J2EE Connector, just like the configuration database connection pool)

Workload

The business development group is related to the business, because the main code amount is logical

The database management group is generally not large, but some work may be needed when importing data from the old database, but it is a one-time job.

Work required to change the function change of data structure

On the one hand, the business development group adjusts the UML physical clashot, submitted to the database development group; on the other hand, rewrite the business logic code according to the new functional requirements

The database management group adjusts the database structure according to the new UML physical class map (some JDO products can be done automatically). The server is configured unchanged.

Since the work content for the database management group is relatively simple, just the problem, the following introduction does not involve the work of the database management group, and only for the business development group.

2 UML physical clashot

The UML physical class diagram is part of the project involved in the data, which does not be lost as the program is aborted, referred to as sustainable (Persistent), data in all databases can be sustainable.

When we are designing, we should analyze which entity classes (ie, sustainable data classes) should be analyzed, thereby drawing entity class diagrams. On this initial class map, it may not contain any properties, but must include the relationship between the entity class, so that the system's approximate contour can be seen.

Below is a simple model entity class diagram, a relationship diagram of major entities in a forum.

Simply put, the project can be said to be a control class with the interrelated entity class plus the processing business logic, and the boundary of the input / output data, which may additionally add some interfaces or special services, such as SMS / mail or facing Third-party data access interface, etc.

With this picture above, DBA is more clear about what kind of data table will have in the database, how to associate between tables. However, the tables in the database are not one by one. For example, a lot of correspondences in the physical class diagram, there must be an additional table in the database, some of some of some of the entities may be placed in another additional table to enhance performance.

The next step is to add an attribute to the physical class based on this picture, then add an access device to each attribute (Accessors, getxxx () / isxxxx (), and setxxx (), etc.), and some must-have methods (such as getage (), Aged by the current date and birthday). In this way, it becomes a complete entity class diagram. The following figure is a physical class diagram added to add ordinary properties. Next, join the accessor method for normal attributes, may add a member.getage () method, this entity class is completed. These processes are relatively simple, and there are many tools that can be done automatically.

One thing to focus on, for the entity class, just give this picture, then use the tool to generate the corresponding Java class code, these class code is completed, and will not write code in it later.

3 transparent storage

For developers, main work is concentrated in business logic, which requires some control classes to implement these logic. These control classes can generally name the XXXSession to indicate the control class for a class, such as the MemberSession, complete some of the functions after the member is logged in; Adminssis is used to complete some of the functions after the administrator login.

In one of these control classes, you only need to obtain access to the previous entity through the JDO specification interface class (javax.jdo. *) To complete the business function. A typical approach is as follows:

MEMBERSESSION's posting method:

public Topic postTopic (String title, String content, String forumId) {// business logic process begins javax.jdo.PersistenceManager pm = getPersistenceManagerFactory () getPersistenceManager ();. pm.currentTransaction () begin ();. // into a Mr. Theme, set basic attribute Topic Topic = new Topic (); Topic.SetTitle; Topic.SetContent (Content); Topic.SetPostTime (New Date ()); // Get relevant forums and currently logged in members // The this.logonmemberid used below is the membership ID that must be provided when generated by this MEMBERSESSION object. // This MEMBERSESSION object is usually generated when logging in. Forum forum = (Forum) pm.getObjectById (pm.newObjectIdInstance (Forum.class, forumId)); Member author = (Member) pm.getObjectById (pm.newObjectIdInstance (Member.class, this.logonMemberId)); // Set the Theme forum and author Topic.Setforum (forum); Topic.Setauthor (Author); // Marking is required to store PM.MakePersistent (Topic); // By the way, change forum and authors forum.Settopiccount (Forum.gettopiccount) () 1); Author.SetPost () 1); // Business logic process complete PM.CurrentTransAction (). Commit (); pm.close ();} This method is over. We can see that as long as the code related to the physical class is placed in the start and submission of PM.CurrentTransaction ().

The only middle need to deal with JDO is to call PM.makePersistent (), but in many cases, as long as the object taken out from the PM points to this object (such as: Author.getPosttopics) ) .add (Topic)) If this statement does not need this statement (of course, it is right), because PM will directly or indirectly point to the object that is currently in the database according to the principle of reachability. The newly generated objects are stored.

The above code illustrates that we don't have to call the update function for each changeable object, as the JDO PM will automatically track these changes and will synchronize the object that does change to the database. This is "transparent storage."

4 flexible query: JDOQL VS SQL

JDOQL is the query language used in JDO. It is an object-based query language. It is very similar to OQL, and it is also very like EJBQL, but there is no shortcoming that only EJBQL can only exist.

There are many articles in the advantages of object inquiry languages, and there is no longer explained here. Just illustrate: JDOQL is completely based on the UML physical class, does not necessarily pay anything in the specific database. Some examples will be given below to illustrate this flexibility.

4.1: Find all forums with authors published

The parameters we give only the names of the author, I hope to get all him published the theme or the topic forum. We need this JDOQL condition: first query the target is the Forum class, then the JDOQL filter string

THIS == _topic.forum& (_topic.author.name == " || _topic.contains (_Reply) && _reply.author.Ame ==" Name> ")

Then, the variable used is declared: topic _topic; reply _reply;

Execute SQL again. The general JDO product translates this query as possible to:

Select a. From Forum A, Topic B, Reply C, MEMBER D

Where a.forum_id = b. forum_id and (b.member_id = d. MEMBER_ID AND D.NAME = '' or b.topic_id = c. Topic_id and c.member_id = D.MEMBER_ID AND D.NAME = ' ')

From above, we can see that JDOQL is far better than SQL in readability or maintainability. We can also use the author's name as a binding parameters, which will be simpler.

If you direct SQL directly, you will be very troublesome. On the one hand, pay attention to the properties name in the entity class. On the one hand, pay attention to the corresponding field in the database, because in most cases, the spelling of the two is due to various factors (such as database Keyword conflicts, etc.) will be different.

Open from this example, we can further:

4.2 Cases: Find all forums with authors published in a post, the total number of passes is greater than 100 and those involved by the author's own favorites

Very simple, write the filter string:

THIS == _topic.forum && (_topic.author == _author || _topic.contains (_Reply) & _Reply.author ==_author) & _author.name == '<>' && postcount> 100 &&_author.favoriteforum .Contains (this)

This time, a variable used: MEMBER _AUTHOR. Its underlying SQL can go to analog yourself.

5 long string

We often encounter a certain information text string of the user exceeds the size of the specified data field, which leads to a troublesome processing, especially some strings that are not necessary to limit the length, such as one of the subject articles, it is possible Ten thousand words, this forces us to divide them a lot of sub-records, each record in the middle. All of this makes our code amount, and the maintenance amount is increased.

Now has JDO, our code is simple, we may try to use the transparent storage function provided by JDO, through some simple tool classes: principle is to split it into a string string. package jdo_util; import java.util *;. public class StringHelper {public static List setLongString (String value) {if (value == null) return null; int len ​​= value.length (); int count = (len partSize- 1) / Partsize; list = new arraylist (count); for (int i = 0; i

With this class, we only need to change the type of Topic.content to List, and the interface of its accessor is constant, still string, just changing: (and indicating the element type of the List in the JDO descriptor) String)

public class Topic {... List content; // original type String ... public String getContent () {return StringHelper.getLongString (content);} public void setContent (String value) {content = StringHelper.setLongString (value);}}

In this way, the problem of the long string is solved, and other related code does not need to be changed, which supports unlimited topics.

Finally, the only drawback is to perform keyword queries for content.

Content.StartSwith ('% )

Become

Content.Contains (s) && s.startswith ('% )

Also, it is possible to query the result of less standard (such as just across two substrs parts). Fortunately, general this query requirement for a long string field is not too much.

It should be noted that the use of conventional SQL also requires additional queries on the split string and has the same disadvantage.

In addition, this feature requires an optional options in the JDO product support specification: javax.jdo.option.list, the main sever JDO products are supported. For example, Kodojdo and JDogenie. 6 Resources Recycling: PM.Close ()

When we use traditional SQL write code, the most dangerous is the resource release problem, which is especially important in Web-based applications. Because the resources associated with JDBC are not allocated in the Java virtual machine, the Java garbage collection mechanism is long, causing the system memory to crash slowly.

Resources that require proactive releases in JDBC include: Connection, Statement, PreparedState, ResultSet, must release the previous resource when each variable for these types is assigned. It is undoubtedly a cumbersome and easily ignored things.

In JDO, things become simpler, all resources are automatically released during PM.Close () (unless JDO products add some Cache for PreparedStatement and ResultSet, this is the requirements for JDO specifications. Therefore, as long as we remember that PM.Close () is called when the physical class is processed. For example, the following code:

PersistenceManager PM = NullTry {PM = getPersistenceManagerFactory (). GetPersistenceManager (); // Do some of the processing of data classes} Finally {PM.Close ();}

Some people may not like to call it, feel annoying, because every time you have to use a PM, it is turned off, if the JDO product does not have a PM connection pool, performance may be affected. In this way, we can use the following inherited Java.lang.ThreadLocal tools to complete this:

public class PersistenceManagerRetriever extends ThreadLocal {/ ** * a PersistenceManager initialized according to configuration information acquirer * @param p * / public PersistenceManagerRetriever (java.util.Properties p) {pmf = JDOHelper.getPersistenceManagerFactory (p);} / ** * Get a related PersistenceManagerFactory * @return PersistenceManagerFactory objects * / public PersistenceManagerFactory pmf () {return pmf;} / ** * Get associated with a current thread PersistenceManager * @return a PersistenceManager objects * / public PersistenceManager pm () {return (PersistenceManager Get ();} / ** * Release all JDO resources related to this thread * / public void cleanup () {PersistenceManager PM = PM (); if (pm == null) return; try {ix (! pm). Isclosed ()) {Transaction TS = PM.CurrentTransAction (); if (Ts.ISACTIVE ()) {log.warn ("Discover an unfinished Transaction [" PMF.GetConnectionURL () "]!" TS) Ts.rollback (); Pm.close ();}} catch ("Exception ex) {log.error error:" EX, EX);} finally {set (null);}} public object get () {PersistenceManager PM = (PersistenceManager) super.get (); if (pm == null || pm.isclosed ()) {pm = pmf.getPersistenceManager (); set (pm); if (log.Indebugenabled ()) log.debug "RETRIEVED New PM:" PM);} Return PM;} public static final logger log = logger.getlogger (PersistenceManagerRever.Class); private persistenceManagerFactory PMF;}

This way, as long as in a thread (such as a page request), you only need to call PersistenceManagerRetriever.pm () directly in all places where PM is required.

That is, and, only PersistenceManagerRever.cleanup () only is called only after the last use is completed.

This PersistenceManagerRetriever can join in the initialization code of a system class:

PersistenceManagerRetriever PersistenceManagerRetriever = New PersistenceManagerRetriever (property);

The statement of the PM of the current thread is closed (PersistenceManagerRetriever.cleanup ()) can configure a JSPFilter to complete it, such as:

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 are configured in a descriptor of WebApp:

jdo_jspfilter ... xxx.jdo_util.jspfilter jdo_jspfilter *. jsp

This way, our code in JSP is simpler:

... persistenceManagerRetriever.pm (). CurrentTransAction (). Begin ();

// Call some XXXSESSION.SOMEMETHODTHATUSESPM () method of processing business logic, which is directly used in PersistenceManagerRetriever.pm (). PersistencemanagerRetriever.pm (). CurrentTransAction (). commit ();

Do not process an exception, JSPFilter belongs to handle itself.

7 ID and object model

Object identification fields, actually just a field of a database, which is actually not required in the object model. That is, in the Java application, an identification of an object is the address in memory, not the properties of this object itself, as this object can be uniquely determined based on this memory address. For example, a Java program that edits vector maps, after reading each map element (object) from the file, these objects have a unique memory address, so it is not necessary to add a similar "ID" to each object. And write to the file.

JDO also uses this concept, ID is independent of the object, does not belong to a part of the object. We can see in front of the forum entity class diagram, and there is no attribute similar to "ID" in each class. So how do JDO controls the correspondence with the primary key in the database? This is two commonly used toolbar methods:

Object persistenceManager.getObjectId (Object Obj)

Object persistenceManager.getObjectByid (Object Obj, Boolean Validate)

In this way, you can get the ID of an entity object at any time, or you can find the object at any time. The first method can also be replaced with javax.jdo.jdohelper.getObjectId ().

In the JDO specification, these IDs are automatically generated by JDO products. In project applications, only when the reference is required, such as between the two pages. Also, these ID classes can be transpleated with String, which is convenient for JSP delivery. This ID is called DataStore Identity, which is typically "JDO_ID" in the field name in the data table.

If you really want yourself to control the ID in the database, JDO also provides user-defined IDs. At this time, the ID is existed as an attribute of the object, which can be any type, int, date, string, or other customized Compound types (such as two properties together as ID). This type of ID is called Application Identity.

In a person concern, I recommend using Datastore Idity in the new project, so you can save a lot of time. In the entity class, some alternative methods can also be written to keep compatible with Application Identity, such as:

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 approach is effective for both types of IDs. Note that this class itself has these two methods, but there is no ID attribute. 8 buffer and Optimistic Transaction

Buffering is a highlight in JDO. Although the JDO specification does not strictly requires a JDO product to achieve what kind of buffer, almost every JDO product, especially commercial products, have a relatively perfect buffer system, this system is the focus of different JDO products. One.

The main JDO products include the following buffers:

1. PM connection pool. Buffering the PersistenceManager, similar to the JDBC connection pool, does not close it when calling PM.Close (), but waiting for the next call or timeout.

2. PreparedStatement buffer. If the JDO underlying finds that a JDOQL statement is the same as the previously used sentence, no new PREPAREDSTATEMENT is generated, but an existing statement in the buffer pool. The buffering of PreparedStatement is also a feature in the JDBC3.0 specification. The JDO underfielding finds that the driver buffer is used when configured in accordance with the Drive of the JDBC3.0 specification, otherwise you can use your own buffer.

3. ResultSet buffer. This kind of buffer implementation is not much JDO product, which is currently like only Kodojdo 2.5.0 Beta implementation. Its mechanism is if the second request performs the same JDOQL statement, the same parameter query, the JDO underlayer removes the collection from the previous execution result, directly returns, greatly enhanced performance. However, the resource is consumed because it is implemented in JDBC2.0.

Generally, when updating the database, we lock the database, set different isolation levels, can complete different levels of lock, such as lock records, lock fields, locks, locks, and more. The JDO can be set in the Vendor Extension marker of the specific JDO product. In addition, the JDO specification also provides a way to completely locked the database: javax.jdo.option.optimisticTransaction, it is an optional option, that is, it is not to force the JDO manufacturer to achieve it, but the main one Vendor's JDO products have realized this feature.

The mechanism principle of OptimisticTransaction is to add a transaction control field in the database record of each object, and then all object changes are completed in the Memory of the Java virtual machine. When submitted, check each changed object from Whether it is changed by other external programs after being removed in the database, which is done through this control field. The general implementation of this field has the following:

1. Store the time of the last change, the field name is more than "JDO_LAST_UPDATE_TIME"

2. The number of times that has been changed in history, and the field name is more than "jdo_version"

In a transaction of OptimisticTransaction, the underlying of the JDO does not lock the database, which guarantees that the TRANSACTION of the time span does not affect the execution of other threads (requests), just if the update is more, the access is relatively large. The chance of failing in Transaction will also become larger.

9 JDBC2.0 and JDBC3.0

JDO is just an object-level packaging, which is based on JDBC, both of which cannot be replaced with each other. In fact, JDBC's norms range from 1.0 to 2.0, and then 3.0 has been doing functional and performance improvements.

Of course, JDO products will not let these, a general JDO product, which detects which specification is in line with the JDBC driver of the underlying configuration, and will try to use the function of the drive itself to achieve a specific operation. For code developers, we can only master JDBC1.0 operations, and a small amount of 2.0 operation, only some of the master's master's advanced features in JDBC3.0. Therefore, 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 technology and database technologies are needed, such as Inner Join, Left / Right Outer Join, Batch Update, and more. These technical requirements for developers are high, and on the one hand, it is necessary to accurately understand the application scope of each technology and the precautions of actual use, and the other aspect is complicated. Therefore, since there are many experienced JDO manufacturers doing these things, why should we spend another effort?

Transfer from Sun2bin

转载请注明原文地址:https://www.9cbs.com/read-69280.html

New Post(0)