Realize SELECT function functions in Java
- Realize the selection, filtering, and sorting of an array or collection through a simple mechanism
David rappoport
Summary
In "Filter Collections", David Raspoport describes a simple way of filtering a collection object. In this article, he expanded his thoughts and showed how to implement it, just like the table in the table in the SQL SELECT processing relational database. He describes the general mechanism for selecting, filtrating, sorting team-shaped or collections. With this mechanism, SQL SELECT function functions can be implemented on the Java object array or collection. (
2004-11-22
).
Suppose you want to display the data in the array or collection in the form of a table, such as a set of columns, and want to select the displayed properties. In addition, you also want to display only data subsets that meet certain conditions, and you want to sort data with the sorting criteria for custom order.
This type of function is provided by SQL SELECT functions: In the SQL statement, you can define data sources (specified by from); you can define the returned attribute (by specifying a column after select); you can add conditions (WHERE clause ); And the order of data display (ORDER BY clause) can be defined.
This article tells some classes and interfaces that enable you to use these functions in any type of object array and collection. In order to implement these function functions, the mechanism describes some design patterns. The method proposed in this article has some benefits:
1. With the code (you can download ...), you can display data in different ways without affecting the original data.
2. Sort, filtering, and selecting the properties are very simple, and the result can be quickly obtained.
3. Through these classes and interfaces, you can independently consider the part of the SELECT statement, so that you can generate pure, reused, scalable code.
However, you may also guess that the mechanism uses a universal interface. If you don't understand it, it may abuse it.
Mechanism and interface
The following list gives a short description of the classes and interfaces we need. In the following, you will see how they collaborate and implement the design. Each class and interface are very simple, only one to two functions.
1. Interface Invoker contains unique functions: Public Boolean Invoke (Object O). With this interface, you can package the function call and return the function result. You will see how he is using later.
2. Interface Condition also contains only one function: Public Boolean Passes (Object O). With this function, you can detect whether any type of condition satisfies any type of condition and returns TRUE or FALSE. Similarly, you will also see the use of this interface later.
3. Class SelectStatement represents the entire SELECT statement, contains SELECT, FROM, WHERE, and ORDER BY.
4. Class SelectInstruction represents a single part in the SELECT clause, selects columns and specifies the name of the column when displaying. A complete SELECT clause represents an array of SelectInstruction objects.
5. Class ORDERINSTRUCTION represents a single part of the ORDER BY clause, the entire ORDER BY clause consists of an array of OrderInstruction objects.
6. Class EXECUTOR executes SelectStatement that contains the entire execution logic.
7. Class ResultTable represents the result set returned after executing SelectStatement. It organizes results data in the form of Object [] [], so that data can be easily converted and displayed. How to collaborate in these classes and interfaces below. The class diagram shows the association between them.
A SelectStatement contains an object collection or array (because the collection and arrays contain only the unified type objects, the type of object is not related; an array of SelectInstruction objects; a Condition object array; and an ORDERInstruction object array. Then pass the SelectStatement object to the Excuter object where this statement is executed and returns a resulttable.
The next question is, SELECTINSTRUCTION, CONDITION, ORDERINSTRUCTION, and RESULTTABLE, what are these classes do? Why do we need them? First, don't look at them, this may make you confused. One point, every class is easy to understand and use.
Each SelectInstruction represents a column you want to appear in the result set (or an attribute of the object). You define a name and Invoker for him. The name will appear as a column header, and the Invoker will trigger on each object in the collection. After a subject triggered, the Invoker returns the corresponding attribute of the object in the corresponding column. This function function makes it a SELECT clause, in which the displayed properties can be defined, and the column name (such as Select Speed As Max_Speed) is defined with the AS. Note: You can also have only one SelectInstruction, where the column name is *. In this case, all the getter () methods in the class are covered by Invoker, and the results appear in the resultset.
Each Condition represents a condition that each object in the source data collection needs to meet this condition. This class corresponds to the WHERE clause, which can eliminate any number of rows through a given condition. Note: If you want to display all objects, you only need to pass empty Condintion [].
Each ORDERINSTRUction represents a rule of how to sort the data, which consists of an Invoker and a Comparator. Invoker's Invoke (Object O) method (when an object in the object collection) will return a result and compare the results returned to other objects in the collection, thereby determining the order of the resulting data. Comparer (if implemented) Compares the results returned under the INVOKE effect. If the Comparator is not implemented, the results are compared based on their respective CompareTo (Object O) methods (assuming that they all implement java.lang, comparatable).
The order between the orderstruction in the array is also very important: the earlier the ORDERINSTRUCTION object appears in the array, the higher it. That is to say, you can determine the priority by applying the first ORDERINSTRUCTION. The ORDERINSTRUCTION class corresponds to the Order By clause in the SELECT statement. Note: If you don't need to sort the results, just simply pass empty orderinstrument [].
Finally, Executor uses SelectStatement as an input, based on the Condition [] filtering object, the ORDERINSTRUCTION [] is sorted, and then the properties you want to display are selected using SelectInstuction []. In order to facilitate delivery, the result data is placed in ResultTable. ResultTable has a simple interface: it defines a public string [] getColumnNames () method, and returns all column names in order. It also defines a public object [] [] getResultData () method, returns selection, filtration, and rantric data after sorting.
Why use universal interfaces?
As mentioned earlier, the solutions of this paper depends on some universal ways to call - the Invoker's Invoke (ObjDec O) method. Why do we need them? What can they do?
Due to our solution equality to treat a collection or array, it is not targeted for specific object types; additional, selection, filtering, and sorting are based on object itself, we have only two: reflection or general interface. Reflection allows us to find the object's method, and specify the name of the call method. However, it is usually not used in the product environment, as this will cause problems to be postponed to run during compilation, and the performance of the reflection is generally better than compiling formation code. Instead of the reflection, the selection is used using a general interface: the generic interface is suitable for all types of objects, and the object is mapped to the corresponding class, and the object is handled according to the category. This is the Invoker interface: it makes the EXECUTOR allows the INVOKER call type-related approach, thereby processing all types of objects. The Condition interface uses the same idea.
Note: The agreed API of the Apache Fund defines a Predicate that implements the same function as the Condition interface in this article, defines a Clouser interface, corresponding to the Invoker interface of this article. The author believes that these interface names are not very good, and they are actually inspired by this API.
Design mode involved in this program
The solutions of this paper use the chain mode: the condition objects and sort objects are sequentially used in the collection object. An object is only handled by the condition objects that satisfy the previous conditions; only the previous ORDERINSTRUCTION object cannot be sorted, the following ORDERINSTRUCTION object will work.
This article also uses aggregation mode. The sort () method of the Java.util.collection class is only using a List and a Comparator for parameters. However, we hope to compare objects based on a Compareor array. Create a CMPARATOR in the internal order by creating a COMPARATOR. If you dare to be interested in this way, please check the source code.
Simple example: Using our class
Let us look at an example: Class Car has three properties: String Color, Double MaxSpeed, Boolean FourwheelDrive.
In your application, you can support a search based on the three properties of the above: Users can enter your favorite color queries, or specify the maximum expected maximum speed.
You may want to display only color and maximum speed, may wish to sort by maximum speed, the second sort is color. (In fact, you usually need to let users decide what to choose, how to sort.)
Below is the step of implementing the above functions:
1. Define an object array or a collection and fill the object from the data source.
Object [] data = getDataFromsomewhere (); or:
Collection data = getdatafromsomewhere ();
2. Select the property definition SelectInstruction:
// define the color column
Invoker colorinvoker = new invoker () {
... Public Object Invoke (Object O) {
... Return ((car) o) .getcolor ();
...}
}
SelectInstruction ColorSelectInstruction = New SelectInstruction ("Color", ColorInvoker;
// define the maxspeed column
Invoker speedinvoker = new invoker () {
... Public Object Invoke (Object O) {
... Return New Integer ((CAR) O) .getmaxSpeed ());
...}
}
SelectInstruction MaxSpeedselectInstruction = New SelectInstruction ("Maximum_Speed", SpeedInvoker;
Then add these two SelectInstruction objects to selectInstruction []:
SelectInstruction [] instructions = new selectinstruction [2];
INSTRUCTIONS [0] = ColorSelectInstruction;
Instructions [1] = maxSpeedselectInstruction;
3. Create two conditional objects, respectively correspond to the conditions for users:
Final Color Color = getColorFromuserInput ();
Condition colorcondition = new condition {
Public Boolean Pass (Object O) {
Return ((car) o) .Getcolor (). Equals (color);
}
}
Final Int MaxSpeed = getSpeedFromuserInput ();
Condition MaxSpeedcondition = new condition {
Public Boolean Pass (Object O) {
Return ((car) o) .getmaxSpeed ()> = maxSpeed;
}
}
Then add these Condition objects to a condition []:
Condition [] Conditions = New Condition [2];
CONDitions [0] = ColorCondition;
Conditions [1] = MaxSpeedCondition;
4. Create two ORDERINSTRUCTION objects, respectively correspond to each sort standard:
// NOTE: WE Supply a null comparator for this Orderinstruction, Since
// The default ordering behavior of string suits out.
// We can also reuse the invokers we defined for the selectinstructions.
ORDERINSTRUCTION colorOrderinstruction = new Orderinstruction (colorinvoker, null); // NOTE: WE Supply A Custom Comparator for this Orderinstruction, Since The
// default Order Behavior of Integer (Lower Number First) Does Not Suit Our Purposes.
// We want to show the higher speed at the top! (This corresponds to specify desc for order by
// in sql.)
Orderinstruction SpeedorderInstruction = New Orderinstruction (SpeedInvoker, New Comparetor () {
Public int Compa (Object O1, Object O2) {
IF (O1 == NULL && O2 == NULL) RETURN 0;
IF (O1 == NULL) RETURN - 1;
IF (O2 == NULL) RETURN 1;
// by Comparing O2 To O1, We get the opposite Order.
Return (Integer) O2.Compareto (O1);
}
});
Then add these ORDERINSTRUCTION objects to Orderinstruciton []:
ORDERINSTRUCTION [] ORDERINSTRUCTION = New Orderinstruction [2];
ORDERINSTRUCTIONS [0] = colorOrderinstruction;
Orderinstruments [1] = SpeedorderInStruction;
5. Add Select Instructions, Data, Conditions, and Sort Instructions to SelectStatement:
SelectStatement SelectStatement = New SelectStatement (SelectInstructions, Data,
Conditions, Orderinstructions;
6. Execute this StateMment and get the return result:
ResultTable ResultTable = New Executor (). EXECUTE (SelectStatement);
7. Level of the resulting operation. such as:
System.out.print ("Column:");
For (int i = 0; i System.out.print ("/ t"); System.out.print (ResultTable.getColumnNames () [i]); } Object []] r = resultTable.getResultData (); For (int i = 0; i SYSTEM.OUT.PRINTLN (); System.out.print ("ROW" i ":"); For (int E = 0; E System.out.print ("/ t"); system.out.print (ResultData [i] [e]); } } This is too complicated, help me! What should I do if you just want to display all the properties provided by public getter ()? Just like the following code: SelectInstruction [] SelectInstructions = New SelectInstruction [] {new selectinstruction}; ResultTable ResultTable = New Executor (). Execute (SelectInstructions, DATA); As you can see, build a simple Java Select Statement as it is easy to build a short SQL Statement, the more features you want to use, the more complicated the problem. However, you can use Invoker, Conditions, and Comparator to implement the SQL Statement unable to achieve things. After all, this is why you are a programmer instead of a database designer. Some problems that belong to readers This article only provides solutions to implement SELECT function functions and is limited to operations for individual arrays or collections. What should I do if we need to operate multiple arrays and data? How to implement INSERT, UPDATE and DELETE? Write a parser, use SQL Statement as an input, create an object description, and what will be applied to multi-proportion? If there is a complete SQL API in Java, you can use the Java to process the database object like the SQL processing database! right now. These problems and some other problems are the readers' practice!