// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements.  See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License.  You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
= JDBC Client Driver
:javaFile: {javaCodeDir}/JDBCClientDriver.java

JDBC Client Driver interacts with the cluster by means of a client node.

== JDBC Client Driver

The JDBC Client Driver connects to the cluster by using a lclient node connection. You must provide a complete Spring XML configuration as part of the JDBC connection string, and copy all the JAR files mentioned below to the classpath of your application or SQL tool:

- All the JARs under `{IGNITE_HOME}\libs` directory.
- All the JARs under `{IGNITE_HOME}\ignite-indexing` and `{IGNITE_HOME}\ignite-spring` directories.

The driver itself is more robust, and might not support the latest SQL features of Ignite. However, because it uses the client node connection underneath, it can execute and distribute queries, and aggregate their results directly from the application side.

The JDBC connection URL has the following pattern:

[source,shell]
----
jdbc:ignite:cfg://[<params>@]<config_url>
----

Where:

- `<config_url>` is required and must represent a valid URL that points to the configuration file for the client node. This node will be started within the Ignite JDBC Client Driver when it (the JDBC driver) tries to establish a connection with the cluster.
- `<params>` is optional and has the following format:

[source,text]
----
param1=value1:param2=value2:...:paramN=valueN
----


The name of the driver's class is `org.apache.ignite.IgniteJdbcDriver`. For example, here's how to open a JDBC connection to the Ignite cluster:

[source,java]
----
include::{javaFile}[tags=register, indent=0]
----

[NOTE]
====
[discrete]
=== Securing Connection

For information on how to secure the JDBC client driver connection, you can refer to the link:security/ssl-tls[Security documentation].
====

=== Supported Parameters

[width="100%",cols="20%,60%,20%"]
|=======================================================================
|Parameter |Description |Default Value

|`cache`

|Cache name. If it is not defined, then the default cache will be used. Note that the cache name is case sensitive.
| None.

|`nodeId`

|ID of node where query will be executed. Useful for querying through local caches.
| None.

|`local`

|Query will be executed only on a local node. Use this parameter with the `nodeId` parameter in order to limit data set by specified node.

|`false`

|`collocated`

|Flag that is used for optimization purposes. Whenever Ignite executes a distributed query, it sends sub-queries to individual cluster members. If you know in advance that the elements of your query selection are colocated together on the same node, Ignite can make significant performance and network optimizations.

|`false`

|`distributedJoins`

|Allows use of distributed joins for non-colocated data.

|`false`

|`streaming`

|Turns on bulk data load mode via INSERT statements for this connection. Refer to the <<Streaming Mode>> section for more details.

|`false`

|`streamingAllowOverwrite`

|Tells Ignite to overwrite values for existing keys on duplication instead of skipping them. Refer to the <<Streaming Mode>> section for more details.

|`false`

|`streamingFlushFrequency`

|Timeout, in milliseconds, that data streamer should use to flush data. By default, the data is flushed on connection close. Refer to the <<Streaming Mode>> section for more details.

|`0`

|`streamingPerNodeBufferSize`

|Data streamer's per node buffer size. Refer to the <<Streaming Mode>> section for more details.

|`1024`

|`streamingPerNodeParallelOperations`

|Data streamer's per node parallel operations number. Refer to the <<Streaming Mode>> section for more details.

|`16`

|`transactionsAllowed`

|Presently ACID Transactions are supported, but only at the key-value API level. At the SQL level, Ignite supports atomic, but not transactional consistency.

This means that the JDBC driver might throw a `Transactions are not supported` exception if you try to use this functionality.

However, in cases when you need transactional syntax to work (even without transactional semantics), e.g. some BI tools might force the transactional behavior, set this parameter to `true` to prevent exceptions from being thrown.

|`false`

|`multipleStatementsAllowed`

|JDBC driver will be able to process multiple SQL statements at a time, returning multiple `ResultSet` objects. If the parameter is disabled, the query with multiple statements fails.

|`false`

|`lazy`

|Lazy query execution.

By default, Ignite attempts to fetch the whole query result set to memory and send it to the client. For small and medium result sets, this provides optimal performance and minimizes the duration of internal database locks, thus increasing concurrency.

However, if the result set is too big to fit in the available memory, it can lead to excessive GC pauses and even `OutOfMemoryError` errors. Use this flag to tell Ignite to fetch the result set lazily, thus minimizing memory consumption at the cost of a moderate performance hit.

|`false`

|`skipReducerOnUpdate`

|Enables server side update feature.

When Ignite executes a DML operation, it first fetches all of the affected intermediate rows for analysis to the query initiator (also known as reducer), and then prepares batches of updated values to be sent to remote nodes.

This approach might impact performance and saturate the network if a DML operation has to move many entries over it.

Use this flag as a hint for Ignite to perform all intermediate rows analysis and updates "in-place" on the corresponding remote data nodes.

Defaults to `false`, meaning that intermediate results will be fetched to the query initiator first.
|`false`


|=======================================================================

[NOTE]
====
[discrete]
=== Cross-Cache Queries

The cache to which the driver is connected is treated as the default schema. To query across multiple caches, you can use Cross-Cache queries.
====

=== Streaming Mode

It's feasible to add data into a cluster in streaming mode (bulk mode) using the JDBC driver. In this mode, the driver instantiates `IgniteDataStreamer` internally and feeds data to it. To activate this mode, add the `streaming` parameter set to `true` to a JDBC connection string:

[source,java]
----
// Register JDBC driver.
Class.forName("org.apache.ignite.IgniteJdbcDriver");

// Opening connection in the streaming mode.
Connection conn = DriverManager.getConnection("jdbc:ignite:cfg://streaming=true@file:///etc/config/ignite-jdbc.xml");
----

Presently, streaming mode is supported only for INSERT operations. This is useful in cases when you want to achieve fast data preloading into a cache. The JDBC driver defines multiple connection parameters that affect the behavior of the streaming mode. These parameters are listed in the parameters table above.

[WARNING]
====
[discrete]
=== Cache Name

Make sure you specify a target cache for streaming as an argument to the `cache=` parameter in the JDBC connection string. If a cache is not specified or does not match the table used in streaming DML statements, updates will be ignored.
====

The parameters cover almost all of the settings of a general `IgniteDataStreamer` and allow you to tune the streamer according to your needs. Please refer to the link:data-streaming[Data Streaming] section for more information on how to configure the streamer.

[NOTE]
====
[discrete]
=== Time Based Flushing

By default, the data is flushed when either a connection is closed or `streamingPerNodeBufferSize` is met. If you need to flush the data more frequently, adjust the `streamingFlushFrequency` parameter.
====

[source,java]
----
include::{javaFile}[tags=time-based-flushing, indent=0]
----

== Example

To start processing the data located in the cluster, you need to create a JDBC `Connection` object using one of the methods below:

[source,java]
----
// Register JDBC driver.
Class.forName("org.apache.ignite.IgniteJdbcDriver");

// Open JDBC connection (cache name is not specified, which means that we use default cache).
Connection conn = DriverManager.getConnection("jdbc:ignite:cfg://file:///etc/config/ignite-jdbc.xml");
----

Right after that you can execute your SQL `SELECT` queries:

[source,java]
----
// Query names of all people.
ResultSet rs = conn.createStatement().executeQuery("select name from Person");

while (rs.next()) {
    String name = rs.getString(1);
}

----

[source,java]
----
// Query people with specific age using prepared statement.
PreparedStatement stmt = conn.prepareStatement("select name, age from Person where age = ?");

stmt.setInt(1, 30);

ResultSet rs = stmt.executeQuery();

while (rs.next()) {
    String name = rs.getString("name");
    int age = rs.getInt("age");
}
----

You can use DML statements to modify the data.

=== INSERT
[source,java]
----
// Insert a Person with a Long key.
PreparedStatement stmt = conn.prepareStatement("INSERT INTO Person(_key, name, age) VALUES(CAST(? as BIGINT), ?, ?)");

stmt.setInt(1, 1);
stmt.setString(2, "John Smith");
stmt.setInt(3, 25);

stmt.execute();
----

=== MERGE
[source,java]
----
// Merge a Person with a Long key.
PreparedStatement stmt = conn.prepareStatement("MERGE INTO Person(_key, name, age) VALUES(CAST(? as BIGINT), ?, ?)");

stmt.setInt(1, 1);
stmt.setString(2, "John Smith");
stmt.setInt(3, 25);

stmt.executeUpdate();
----

=== UPDATE

[source,java]
----
// Update a Person.
conn.createStatement().
  executeUpdate("UPDATE Person SET age = age + 1 WHERE age = 25");
----

=== DELETE

[source,java]
----
conn.createStatement().execute("DELETE FROM Person WHERE age = 25");
----
