Java 8 has finally arrived! After a few years of waiting, Java programmers can finally get functional programming support in Java. Functional programming supports the existing code and provides strong capabilities for Java. The most important thing about the new features is the way Java programmers operate the database. Functional programming brings an exciting and simple and efficient database API. Java 8 will support new databases that can compete with language such as C#linq Access method.
The functional method of processing data
Java 8 not only adds functional support, it also expands the collection class by new function processing data. Usually, when Java processing a large amount of data requires a large amount of cycle and iterators.
For example, suppose you have a collection of COLLECTION: Customer: Customer:
Collection <customer> Customers;
If you are only interested in customers from Belgium, you will have toe all the Customer objects and only save what you need.
Collection <Customer> Belgians = New ArrayList <() (); for (Customer C: Customers) {if (C.GetCountry (). Equals ("Belgium")) Belgians.add (C);}This not only costs 5 lines of code, but it is not very abstract. What if you have 10 million objects? Will you use two threads to filter all objects to speed up? Then you will have to use a lot of dangerous dangers Multi -threaded code to rewrite all code.
With Java 8, only one line of code can achieve the same features. By supporting functional programming, Java 8 can let you write only one function to indicate which customer (object) you are interested in and then use that function to set the set. Just make filtration. Java 8's new Steams API supports you to do this:
Customers.stream (). Filter (C-> C.getCountry (). Equals ("Belgium");The code of the Java 8 version above is not only shorter, but also easier to understand. It has almost no torment (cycle or iterator, etc.). The code calls the Filter () method. Well. You don't need to waste time in the interpretation of the code in the interpretation cycle to understand what it is doing for its data.
What should I do if you want to execute this code concurrently? You only need to use another type of stream
Customers.parallelstream (). Filter (C-> C.getCountry (). Equals ("Belgium");What is more exciting is that this functional style code is also applicable to the database
Use a function method on the database
Traditionally, programmers need to use a special database to query statement to access the data of the database. For example, the following is the JDBC code to find customers from Belgium:
PreparedStatement s = con.preparestatement ("Select *" + "From Customer C" + "where c.Country =?"); S.SetString ();Most of these code are string, which will make the compiler not find errors and this hasty code will cause security problems. There are also these large amounts of model code to make the access code access code very redundant. By using a special Java library to provide database query language, you can solve wrong checks and security problems. Or use the object relationship mapping tool to avoid a large number of boring code, but they can only be used in general access to inquiries. If complex query is required, special database query language is still required.
Use Java 8 to query the database by functional API. For example, Jinq is an open source project, and what future database API it explores can make functional programming possible. Here is a database query using jinq:
Customers.Where (C-> C.GetCountry (). Equals ("Belgium");This code is almost the same as the code using a streaming API. In fact, the future JINQ version can allow you to write a database query directly with a streaming API. When the code runs, Jinq will automatically translate into a database query code, just like the JDBC query before.
In this case, even if you haven't learned some new database query language, you can write an efficient database query. You can use the same style of code to collect on Java. You don't need a special Java compiler or virtual machine. All code compilation and running on ordinary Java 8 JDK. If your code is wrong, the compiler will find them and report it to you, just like an ordinary Java code.
JinQ supports the same complex query as SQL92. SELECTION, Projection (projection), Joins (connected), and subqual inquiries support it. The algorithm of the translation Java code into a database query is very flexible, as long as it can accept it, it can translate. For example, Jinq can translate the database query below, although it is complicated.
Customers .Where (C-> C.getCountry (). Equals ("Belgium") .Where (c-> {if (c.getsalarly () <100000) Return c.getsALALALALALALALALALALALALAALAAALAAAALAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA a his a a onectctctctctctctctct his his role work work work work work work work work work work work work work wor work work work worker. else return c.getsalar () <2 * c.getdebt ();});As you can see, the functional programming of Java 8 is very suitable for database query. And the query is compact and even complicated inquiries can be competent.
Internal operation
But how do you work? How can ordinary Java compilers convert Java code into database query? What's special about Java 8 to make this possible?
The key to supporting these new database PIs that support these functions is a bytecode analysis method called "symbolic execution". Although your code is compiled by an ordinary Java compiler and runs in an ordinary Java virtual machine, JinQ can analyze and build a database query from it when you are compiled Java code. When using the Java 8 Streams API, it is often found that when analyzing short functions, the work effect of symbolic execution is the best.
To understand how this symbolic execution works, the easiest way is to use an example. Let's check how the following queries are converted to SQL query language by JINQ:
Customers .Where (C-> C.GetCountry (). Equals ("Belgium")))))) Initially, variables Customers is a collection, and its corresponding database query is:
Select * From Customers C
Then, the where () method is called, and a function is passed to it. In the where () method, Jinq opens the .class file of this function to obtain the byte code compiled by this function for analysis. In this example, do not use the real byte code, let us use some simple instructions to represent the byte code of this function:
d = c.getcountry () e = "Belgium" e = d.equals (e) Return e
Here, we assume that the function has been compiled by the Java compiler into these four instructions. When the where () method is called, Jinq sees these. How can JINQ understand these code?
JinQ is analyzed by executing code. But Jinq does not run the code directly. It is a "abstract" operation code: without real variables and real values, Jinq uses symbols to indicate all the values when executing code. This is why this analysis is called "symbolic execution".
Jinq executes each instruction and tracks everything that all side effects or code changes during the program state. The following is a chart that shows all the side effects found when JINQ performs the four lines of code in symbolic execution.
Example of symbolic execution
In the figure, you can see that after the first instruction is running, Jinq discovered two side effects: Variable D has changed, and the method Customer.getCountry () was called. Because it is symbolic execution, variable D does not give a real value of a real, such as "USA" or "Denmark", which is assigned to a symbolic value of C.GetCountry ().
After all these instructions are executed, JinQ streamlined side effects. Because variable D and E are local variables, any variables will be discarded after the function exits, so these side effects can be ignored. Jinq also knows that Customer.getCountry () and String.equals () does not modify any variables or display any output, so these methods can be ignored. As a result, Jinq can conclude that this function will only produce one role, and it will return c.getCountry (). Equals ("Belgium").
Once Jinq has understood the functions passed to it in the where () method, it can mix the knowledge of database query and give a new database query in the Customers collection.
Generate database query
This is how Jinq generates a database query from your code. The use of symbolic execution means that this method is quite powerful for different code modes out of different Java compilers. If the code encountered by Jinq has the side effects that cannot be converted into a database query, JinQ will keep your code unchanged. Because everything is written in normal Java code, jinq can run those code directly, and your code will produce the expected results.
This simple translation example should let you understand how to query translation works. You can be sure that these algorithms can correctly generate database queries from your code.
Beautiful prospect
I hope I have let you taste a new way of database work brought by Java 8 in Java. The functional programming supported by Java 8 allows you to write code for the database to write code for Java collection. It is hoped that the existing database APIs will be extended to support these types of query.