問合せの使用
Oracle NoSQL Databaseのアプリケーションに対して問合せを使用することについて学習します。
問合せを実行するには、NoSQLHandle.query()
APIを使用します。
SELECT
問合せを実行して表からデータを読み取るには、次のステップを実行します。/* QUERY a table named "users", using the primary key field "name".
* The table name is inferred from the query statement.
*/
QueryRequest queryRequest = new QueryRequest().
setStatement("SELECT * FROM users WHERE name = \"Taylor\"");
/* Queries can return partial results. It is necessary to loop,
* reissuing the request until it is "done"
*/
do {
QueryResult queryResult = handle.query(queryRequest);
/* process current set of results */
List<MapValue> results = queryResult.getResults();
for (MapValue qval : results) {
//handle result
}
} while (!queryRequest.isDone());
問合せを使用するときには、次の考慮事項に注意してください。
-
同じ問合せを複数回実行する場合は、準備された問合せを使用できます。準備された問合せを使用すると、問合せ文字列を毎回開始するよりも実行の効率が上がります。問合せ言語およびAPIは、再利用に役立つ問合せ変数をサポートしています。
たとえば、準備された文を使用して、SELECT
問合せを実行し、表からデータを読み取る場合は、次のようになります。
/* Perform the same query using a prepared statement. This is more
* efficient if the query is executed repeatedly and required if
* the query contains any bind variables.
*/
String query = "DECLARE $name STRING; " +
"SELECT * from users WHERE name = $name";
PrepareRequest prepReq = new PrepareRequest().setStatement(query);
/* prepare the statement */
PrepareResult prepRes = handle.prepare(prepReq);
/* set the bind variable and set the statement in the QueryRequest */
prepRes.getPreparedStatement()
.setVariable("$name", new StringValue("Taylor"));
QueryRequest queryRequest = new QueryRequest().setPreparedStatement(prepRes);
/* perform the query in a loop until done */
do {
QueryResult queryResult = handle.query(queryRequest);
/* handle result */
} while (!queryRequest.isDone());
borneo.NoSQLHandle.query()
メソッドを使用します。たとえば、SELECT問合せを実行して表からデータを読み取る場合、borneo.QueryResult
には結果のリストが含まれています。また、borneo.QueryRequest.is_done()
がFalseを返す場合、結果がより多くなる可能性があるため、通常、問合せはループで実行する必要があります。単一のリクエストでは結果が返されない可能性があり、問合せがまだ実行されないため、問合せループを続行する必要があることを示します。たとえば:from borneo import QueryRequest
# Query at table named 'users" using the field 'name' where name may match
# 0 or more rows in the table. The table name is inferred from the query
statement = 'select * from users where name = "Jane"'
request = QueryRequest().set_statement(statement)
# loop until request is done, handling results as they arrive
while True: result = handle.query(request)
# handle results
handle_results(result)
# do something with results
if request.is_done(): break
- Oracle NoSQL Databaseには、実行および再利用のための問合せを準備する機能があります。同じ問合せを複数回実行する場合は、準備した問合せを使用することをお薦めします。準備された問合せを使用すると、問合せ文字列を毎回開始するよりも実行の効率が上がります。問合せ言語およびAPIは、問合せの再利用に役立つ問合せ変数をサポートしています。
borneo.QueryRequest
を使用すると、問合せの読取り整合性を設定したり、単一のリクエストで使用されるリソース(読取りおよび書込み)の最大量を変更できます。あまりにも多くのリソースがあまりにも早く使用されるため、問合せが調整されないようにすることが重要です。
from borneo import PrepareRequest, QueryRequest
# Use a similar query to above but make the name a variable
statement = 'declare $name string
select * from users where name = $name'
prequest = PrepareRequest().set_statement(statement)
presult = handle.prepare(prequest)
# use the prepared statement, set the variable
pstatement = presult.get_prepared_statement()
pstatement.set_variable('$name', 'Jane')
qrequest = QueryRequest().set_prepared_statement(pstatement)
# loop until qrequest is done, handling results as they arrive
while True:
# use the prepared query in the query
request qresult = handle.query(qrequest)
# handle results
handle_results(qresult)
# do something with results
if qrequest.is_done(): break
# use a different variable value with the same prepared query
pstatement.set_variable('$name', 'another_name')
qrequest = QueryRequest().set_prepared_statement(pstatement)
# loop until qrequest is done, handling results as they arrive
while True:
# use the prepared query in the query
request qresult = handle.query(qrequest)
# handle results
handle_results(qresult)
# do something with results
if qrequest.is_done(): break
Client.Query
関数を使用します。たとえば、SELECT
問合せを実行して表からデータを読み取る場合:prepReq := &nosqldb.PrepareRequest{
Statement: "select * from users",
}
prepRes, err := client.Prepare(prepReq)
if err != nil {
fmt.Printf("Prepare failed: %v\n", err)
return
}
queryReq := &nosqldb.QueryRequest{
PreparedStatement: &prepRes.PreparedStatement,
}
var results []*types.MapValue
for {
queryRes, err := client.Query(queryReq)
if err != nil {
fmt.Printf("Query failed: %v\n", err)
return
}
res, err := queryRes.GetResults()
if err != nil {
fmt.Printf("GetResults() failed: %v\n", err)
return
}
results = append(results, res...)
if queryReq.IsDone() {
break
}
}
通常、問合せはループで実行し、QueryRequest.IsDone()
をチェックして問合せが完了したかどうかを判断します。1つのリクエストで結果を返さず、QueryRequest.IsDone()
がfalseに評価される可能性があり、問合せループが続行される必要があることを示します。
- Oracle NoSQL Databaseには、実行および再利用のための問合せを準備する機能があります。同じ問合せを複数回実行する場合は、準備した問合せを使用することをお薦めします。準備された問合せを使用すると、問合せ文字列を毎回開始するよりも実行の効率が上がります。問合せ言語およびAPIは、問合せの再利用に役立つ問合せ変数をサポートしています。
nosqldb.QueryRequest
を使用すると、(QueryRequest.Consistency
フィールドを介して)問合せの読取り整合性を設定したり、単一リクエストで使用されるリソースの最大量を変更できます(QueryRequest.MaxReadKB
およびQueryRequest.MaxWriteKB
フィールドを介して読取りおよび書込みを実行します)。あまりにも多くのリソースがあまりにも早く使用されるため、問合せが調整されないようにすることが重要です。
query
メソッドを使用します。このメソッドは、結果の行の配列および継続キーを含むプレーンJavaScriptオブジェクトであるQueryResult
のPromise
を返します。問合せによって返されるデータの量はシステム・デフォルトによって制限され、query
のopt引数にmaxReadKB
プロパティを設定することでさらに制限できます。これは、query
メソッドの1回の呼出しでは、使用可能なすべての結果が返されない可能性があることを意味します。この状況は、continuationKey
プロパティを使用して処理されます。nullでない継続キーは、より多くの問合せ結果を使用できることを意味します。つまり、通常、問合せはループで実行される必要があり、継続キーがnullになるまでループされます。行が空になる可能性があり、continuationKey
がnullでないことに注意してください。これは、問合せループを続行する必要があることを意味します。すべての結果を受信するには、ループでquery
をコールします。反復のたびに、QueryResult
でnull以外の継続キーが受信された場合は、次の反復のopt
引数にcontinuationKey
プロパティを設定します。const NoSQLClient = require('oracle-nosqldb').NoSQLClient;
.....
const client = new NoSQLClient('config.json');
async function queryUsersTable() {
const opt = {};
try {
do {
const result = await client.query('SELECT * FROM users', opt);
for(let row of result.rows) {
console.log(row);
}
opt.continuationKey = result.continuationKey;
} while(opt.continuationKey);
} catch(error) {
//handle errors
}
}
- Oracle NoSQL Databaseには、実行および再利用のための問合せを準備する機能があります。同じ問合せを複数回実行する場合は、準備した問合せを使用することをお薦めします。準備された問合せを使用すると、問合せ文字列を毎回開始するよりも実行の効率が上がります。問合せ言語およびAPIは、問合せの再利用に役立つ問合せ変数をサポートしています。
query
のopt引数を使用すると、問合せの読取り整合性を設定し、1回のコールで読み取るデータの最大量を変更できます。これは、問合せが調整されないようにするために重要です。
prepare
メソッドを使用します。このメソッドは、PreparedStatement
オブジェクトのPromiseを返します。setメソッドを使用して、問合せ変数をバインドします。準備済問合せを実行するには、問合せにPreparedStatement
を渡すか、文の文字列のかわりにqueryIterable
を渡します。const NoSQLClient = require('oracle-nosqldb').NoSQLClient;
.....
const client = new NoSQLClient('config.json');
async function queryUsersTable() {
const statement = 'DECLARE $name STRING; SELECT * FROM users WHERE ' +
'name = $name';
try {
let prepStatement = await client.prepare(statement);
const opt = {};
// Set value for $name variable
prepStatement.set('$name', 'Taylor');
do {
let result = await client.query(prepStatement);
for(let row of result.rows) {
console.log(row);
}
opt.continuationKey = result.continuationKey;
} while (opt.continuationKey);
// Set different value for $name and re-execute the query
prepStatement.set('$name', 'Jane');
do {
let result = await client.query(prepStatement);
for(let row of result.rows) {
console.log(row);
}
opt.continuationKey = result.continuationKey;
} while (opt.continuationKey);
} catch(error) {
//handle errors
}
}
QueryAsync
メソッドをコールするか、GetQueryAsyncEnumerable
メソッドをコールして、結果の非同期列挙可能性に対して反復処理します。これらの各メソッドにQueryOptionsとしてオプションを渡すことができます。QueryAsync
メソッドはTask<QueryResult<RecordValue>>
を返します。QueryResultには、RecordValueインスタンスのリストおよびその他の情報として問合せ結果が含まれています。問合せで完全な主キーが指定されている場合(またはINSERT文を実行している場合)、QueryAsync
を1回コールすれば十分です。var client = new NoSQLClient("config.json");
try {
var result = await client.QueryAsync(
"SELECT * FROM users WHERE id = 1");
// Because we select by primary key, there can be at most one record.
if (result.Rows.Count>0) {
Console.WriteLine("Got record: {0}.", result.Rows[0]);
}
else {
Console.WriteLine("Got no records.");
}
}
catch(Exception ex) {
// handle exceptions
}
問合せによって返されるデータ量は、システムによって制限されます。また、QueryOptions
のMaxReadKB
プロパティを設定して、さらに制限することもできます。つまり、QueryAsync
を1回起動しても、使用可能なすべての結果が返されるわけではありません。この状況は、継続キーを使用して処理されます。QueryResult
のnull以外のContinuationKeyは、より多くの問合せ結果を使用できることを意味します。つまり、通常、問合せはループで実行される必要があり、継続キーがnull
になるまでループされます。
QueryResult.Rows
は空)が返され、nullでない継続キーを持つ可能性があることに注意してください。つまり、問合せはループを続行する必要があることを意味します。問合せを続行するには、QueryAsync
への次のコールのためにQueryOptions
でContinuationKey
を設定し、継続キーがnullになるまでループします。次の例では、問合せが実行され、問合せ結果が出力されます。var client = new NoSQLClient("config.json");
var options = new QueryOptions();
try {
do {
var result = await client.QueryAsync(
"SELECT id, name FROM users ORDER BY name",
options);
foreach(var row of result.Rows) {
Console.WriteLine(row);
}
options.ContinuationKey = result.ContinuationKey;
}
while(options.ContinuationKey != null);
}
catch(Exception ex){
// handle exceptions
}
GetQueryAsyncEnumerable
を使用することです。反復可能なAsyncEnumerable<QueryResult>
のインスタンスを返します。各反復ステップでは、問合せ結果の一部がQueryResultとして返されます。var client = new NoSQLClient("config.json");
try {
await foreach(var result in client.GetQueryAsyncEnumerable(
"SELECT id, name FROM users ORDER BY name"))
{
foreach(var row of result.Rows) {
Console.WriteLine(row);
}
}
}
catch(Exception ex){
// handle exceptions
}
Oracle NoSQL Databaseには、実行および再利用のための問合せを準備する機能があります。同じ問合せを複数回実行する場合は、準備した問合せを使用することをお薦めします。準備された問合せを使用すると、SQL文を毎回開始するよりも実行の効率が上がります。問合せ言語およびAPIは、問合せの再利用に役立つ問合せ変数をサポートしています。
PrepareAsync
を使用して問合せを準備します。このメソッドはTask<PreparedStatement>
を返します。PreparedStatement
を使用すると、問合せ変数を設定できます。問合せメソッドQueryAsync
およびGetQueryAsyncEnumerable
には、SQL文のかわりにPreparedStatement
をパラメータとして取得することによって準備済問合せを実行するオーバーロードがあります。たとえば:var client = new NoSQLClient("config.json");
try {
var sql = "DECLARE $name STRING; SELECT * FROM users WHERE " +
"name = $name";
var preparedStatement = await client.PrepareAsync(sql);
// Set value for $name variable and execute the query
preparedStatement.Variables["$name"] = "Taylor";
await foreach(var result in client.GetQueryAsyncEnumerable(
preparedStatement)) {
foreach(var row of result.Rows) {
Console.WriteLine(row);
}
}
// Set different value for $name and re-execute the query.
preparedStatement.Variables["$name"] = "Jane";
await foreach(var result in client.GetQueryAsyncEnumerable(
preparedStatement)) {
foreach(var row of result.Rows) {
Console.WriteLine(row);
}
}
}
catch(Exception ex){
// handle exceptions
}
NosqlTemplate runQuery()
、runQueryJavaParams()
、runQueryNosqlParams()
を使用します。詳細は、SDK for Spring Data APIリファレンスを参照してください。
ノート:
まず、Oracle NoSQL Databaseの接続詳細を指定するために、AbstractNosqlConfiguration
クラスを拡張するAppConfig
クラスを作成します。詳細は、「NoSQL接続の取得」を参照してください。
この項では、導出問合せを使用します。導出問合せの詳細は、Spring Data SDK開発者ガイドの導出問合せを参照してください。
UsersRepository
インタフェースを作成します。このインタフェースは、NosqlRepository
インタフェースを拡張して、そのクラスの主キーのエンティティ・クラスとデータ型をパラメータ化された型としてNosqlRepository
インタフェースに提供します。NosqlRepository
インタフェースは、データベースからデータを取得するために使用されるメソッドを備えています。import com.oracle.nosql.spring.data.repository.NosqlRepository;
/* The Users is the entity class and Long is the data type of the primary key in the Users class.
This interface provides methods that return iterable instances of the Users class. */
public interface UsersRepository extends NosqlRepository<Users, Long> {
/* Search the Users table by the last name and return an iterable instance of the Users class.*/
Iterable<Users> findByLastName(String lastname);
}
Users
表から行を選択し、オブジェクトからの出力にこの値を出力します。@Autowired
private UsersRepository repo;
System.out.println("\nfindBylastName: Willard");
/* Use queries to find by the last Name. Search the Users table by the last name and return an iterable instance of the Users class.*/
allusers = repo.findByLastName("Willard");
for (Users s: allusers) {
System.out.println(" User: " + s);
}
findBylastName: Willard
User: Users{id=2, firstName=Angela, lastName=Willard}