Java 8が数年間到着しました。データベースを操作します。
データを処理する機能的方法
Java 8は、機能的なサポートを追加するだけでなく、通常、Javaが大量のデータを処理すると、大量のサイクルとイテレーターが必要です。
たとえば、コレクションのコレクションがあるとします:顧客:顧客:
Collection <customer> customers;
ベルギーの顧客のみに興味がある場合は、すべての顧客オブジェクトをつま先に持ち、必要なものだけを保存します。
collection <customer> belgians = new arrayList <()(for(customer c:customer){if(c.getCountry()。これは、5行のコードであるだけでなく、1000万個のオブジェクトを使用してすべてのオブジェクトを使用している場合はどうなりますか?すべてのコードを書き換えるためのスレッドコード。
Java 8を使用すると、同じ機能をサポートすることにより、Java 8のみを作成して、どの顧客(オブジェクト)に興味があるかを示すことができ、その関数を使用してセットを設定できます。ろ過するだけです。
customers.stream()。
上記のJava 8バージョンは、より短いものではありません(サイクルまたは反復剤など)解釈サイクルのコードの解釈に時間を無駄にして、データに対して何をしているのかを理解します。
このコードを同時に実行する場合はどうすればよいですか?
customers.parallelstream()。
さらにエキサイティングなのは、この機能スタイルコードがデータベースにも適用できることです
データベースで関数メソッドを使用します
従来、プログラマーは特別なデータベースを使用してステートメントを照会して、たとえば、ベルギーの顧客を見つけるためのJDBCコードです。
preatedStatement s = con.preparestatement(custor c " +" from c.country =? ");
これらのコードのほとんどは、コンパイラがエラーを見つけられないようにしますデータベースクエリ言語を提供すると、間違ったチェックとセキュリティの問題を解決できます。 または、オブジェクト関係マッピングツールを使用して、多数の退屈なコードを避けますが、複雑なクエリが必要な場合にのみ使用できます。
Java 8を使用して、関数APIでデータベースを照会します。たとえば、JINQはオープンソースプロジェクトであり、それが探求する将来のデータベースAPIが機能的なプログラミングを可能にすることができます。 JINQを使用したデータベースクエリは次のとおりです。
customers.where(c-> c.getcountry()。equals( "Belgium");
このコードは、ストリーミングAPIを使用したコードとほぼ同じです。 コードが実行されると、JINQは、以前のJDBCクエリと同様に、データベースクエリコードに自動的に変換されます。
この場合、新しいデータベースクエリ言語を学習していなくても、効率的なデータベースクエリを書くことができます。同じスタイルのコードを使用して、Javaで収集できます。特別なJavaコンパイラや仮想マシンは必要ありません。すべてのコードコンパイルと通常のJava 8 JDKで実行されています。コードが間違っている場合、コンパイラはそれらを見つけて、通常のJavaコードのようにあなたに報告します。
JINQは、SQL92と同じ複雑なクエリをサポートし、投影(プロジェクション)、結合(接続)、およびサブクエールの問い合わせをサポートしています。翻訳Javaコードのアルゴリズムは、データベースクエリへのアルゴリズムが非常に柔軟です。それを受け入れることができる限り、翻訳できます。たとえば、JINQは複雑ですが、以下のデータベースクエリを翻訳できます。
顧客(c-> c.getCountry()。等しい( "ベルギー") ctctctctctct彼の役割作業作業ワークワークワークワークワークワークワークワークワーカー()<2 * c.getDebt();});
ご覧のとおり、Java 8の機能プログラミングは、データベースクエリに非常に適しています。そして、クエリはコンパクトであり、複雑な問い合わせでさえ有能になる可能性があります。
内部操作
しかし、どのように働きますか?通常のJavaコンパイラは、Javaコードをデータベースクエリにどのように変換できますか?これを可能にするためにJava 8の特別な点は何ですか?
これらの機能をサポートするこれらの新しいデータベースPIをサポートするための鍵は、「Symbolic実行」と呼ばれるバイトコード解析方法です。コードは通常のJavaコンパイラによってコンパイルされ、通常のJava仮想マシンで実行されますが、JINQはJavaコードをコンパイルしたときにデータベースクエリを分析および構築できます。 Java 8 Streams APIを使用する場合、短い関数を分析する場合、シンボリック実行の作業効果が最適であることがよくあります。
この象徴的な実行がどのように機能するかを理解するために、最も簡単な方法は例を使用することです。次のクエリがJINQによってSQLクエリ言語に変換される方法を確認しましょう。
顧客.where(c-> c.getcountry()。equals( "Belgium"))))))
当初、変数の顧客はコレクションであり、それに対応するデータベースクエリは次のとおりです。
select * from Customers c
次に、where()メソッドが呼び出され、関数が渡されます。 Where()メソッドでは、JINQがこの関数の.classファイルを開き、分析のためにこの関数によってコンパイルされたバイトコードを取得します。この例では、実際のバイトコードを使用しないでください。この関数のバイトコードを表すために、いくつかの簡単な指示を使用してみましょう。
d = c.getcountry()e = "belgium" e = d. equals(e)return e
ここでは、この関数がJavaコンパイラによってこれらの4つの指示にコンパイルされていると仮定します。 where()メソッドが呼び出されると、Jinqはこれらを見ます。 JINQはこれらのコードをどのように理解できますか?
JINQは、コードを実行することにより分析されます。しかし、JINQはコードを直接実行しません。これは「抽象的な」操作コードです。実際の変数と実際の値がない場合、JINQはシンボルを使用してコードを実行するときにすべての値を示します。これが、この分析が「シンボリック実行」と呼ばれる理由です。
JINQは各命令を実行し、プログラム状態中にすべての副作用またはコードが変更されるすべてを追跡します。以下は、JINQがシンボリック実行で4行のコードを実行したときに見つかったすべての副作用を示すチャートです。
シンボリック実行の例
図では、最初の命令が実行された後、JINQが2つの副作用を発見したことがわかります。変数Dが変更され、Method customer.getCountry()が呼び出されました。それは象徴的な実行であるため、変数Dは、c.getCountry()の象徴的な値に割り当てられる「米国」や「デンマーク」などの実際の価値を与えません。
これらすべての指示が実行された後、JINQは副作用を合理化しました。変数dとeは局所変数であるため、関数が終了した後に変数は破棄されるため、これらの副作用は無視できます。 Jinqはまた、customer.getCountry()およびString.Equals()が変数を変更したり、出力を表示したりしないため、これらのメソッドを無視できることも知っています。その結果、JINQは、この関数が1つの役割のみを生み出し、C.GetCountry()を返すと結論付けることができます。
JINQがwhere()メソッドでそれに渡された関数を理解すると、データベースクエリの知識を混ぜて、顧客コレクションに新しいデータベースクエリを提供できます。
データベースクエリを生成します
これが、JINQがコードからデータベースクエリを生成する方法です。シンボリック実行の使用は、この方法が異なるJavaコンパイラの異なるコードモードに対して非常に強力であることを意味します。 JINQが遭遇したコードには、データベースクエリに変換できない副作用がある場合、JINQはコードを変更しません。すべてが通常のJavaコードで記述されているため、JINQはこれらのコードを直接実行でき、コードは予想される結果が生成されます。
この単純な翻訳の例では、翻訳が機能する方法を理解できるようにする必要があります。これらのアルゴリズムがコードからデータベースクエリを正しく生成できることを確認できます。
美しい見通し
Java 8がJavaのJava 8が提起した新しい方法を味わってもらいたいと思います。 Java 8でサポートされている機能プログラミングを使用すると、データベースのコードを作成してJavaコレクションのコードを書き込むことができます。これらのタイプのクエリをサポートするために、既存のデータベースAPIが拡張されることが期待されています。