SlideShare a Scribd company logo
1 of 41
Download to read offline
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. |
JDBC Next: A New
Asynchronous API for
Connecting to a Database
CON1491
Douglas Surber
JDBC Architect
Oracle Database Server Technologies
October 3, 2017
3
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. |
Safe Harbor Statement
The following is intended to outline our general product direction. It is intended for
information purposes only, and may not be incorporated into any contract. It is not a
commitment to deliver any material, code, or functionality, and should not be relied upon
in making purchasing decisions. The development, release, and timing of any features or
functionality described for Oracleā€™s products remains at the sole discretion of Oracle.
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. |
Program Agenda
Overview1
2
3
4
Confidential ā€“ Oracle Internal/Restricted/Highly Restricted 5
Code
Wrap-up
Q&A
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. |
Overview
6
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. |
Asynchronous Database Access
ā€¢ Java standard database access API that never blocks user threads
ā€¢ Developed by the JDBC Expert Group with community input
ā€¢ Targeted for a near future release, Java 10 or equivalent
ā€¢ Asynchronous apps have better throughput
ā€“ Fewer threads means less thread scheduling, less thread contention
ā€“ Database access is slow so blocked threads leave resources idle for a long time
ā€“ Simultaneous access to multiple databases, e.g. map/reduce, sharded databases
ā€“ Fire and forget, e.g. DMS, stored procedures
7
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. |
Goals
ā€¢ No user thread blocks ever
ā€“ Minimize the number of threads used for database access
ā€¢ Alternate API for database access
ā€“ Not an extension of the standard JDBC API
ā€“ Not a replacement for the standard JDBC API
ā€¢ Target high throughput apps
ā€“ Not a completely general purpose database access API
ā€“ The initial version will have a limited feature set
ā€¢ Build on the Java SE class library
8
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. |
Design Choices
ā€¢ Minimal or no reference to java.sql
ā€¢ Rigorous use of types
ā€¢ Builder pattern
ā€¢ Fluent API
ā€¢ Immutable after initialization
ā€¢ One way to do something is enough
ā€¢ Avoid SQL processing
ā€¢ Avoid callback hell
9
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. |
What About ā€¦ ?
ā€¢ Streams
ā€“ Java streams are inherently synchronous
ā€¢ ReactiveStreams
ā€“ Not integrated into the Java SE class library
ā€¢ NodeJS
ā€¢ ADBCJ
There are already multiple asynchronous/non-blocking database access APIs
10
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. |
Code
11
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. |
public void trivialInsert(DataSource ds) {
String sql = "insert into tab values (:id, :name, :answer)";
try (Connection conn = ds.getConnection()) {
conn.countOperation(sql)
.set("id", 1, JdbcType.NUMERIC)
.set("name", "Deep Thought", JdbcType.VARCHAR)
.set("answer", 42, JdbcType.NUMERIC)
.submit();
}
}
Trivial Insert
12
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. |
All SQL is Vendor Specific
ā€¢ No escape sequences
ā€¢ No specified parameter markers
ā€¢ Non vendor specific syntax requires processing by the driver
ā€“ Adds overhead
ā€“ Increases code complexity
ā€“ Minimal benefit as most apps are tied to a specific database regardless
Note: Code examples use parameter markers from a variety of databases including DB2
(:foo), MySQL (?), Oracle Database(:foo), PostgresSQL($1), and SQL Server (@foo).
13
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. |
public void trivialSelect(DataSource ds, List<Integer> result) {
String sql = "select id, name, answer " +
"from tab where answer = $1";
try (Connection conn = ds.getConnection()) {
conn.<List<Integer>>rowOperation(sql)
.set("1", 42, JdbcType.NUMERIC)
.rowAggregator( (ignore, row) -> {
result.add(row.get("id", Integer.class));
return null;
} )
.submit();
}
}
Trivial Select
14
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. |
Execution Model
ā€¢ Operations consist of
ā€“ SQL or other database operation
ā€“ Parameter assignments
ā€“ Result handling
ā€“ Submission and CompletableFuture
ā€¢ User thread creates and submits Operations
ā€“ Creating and submitting never blocks; user thread never blocks
ā€¢ Implementation executes those Operations asynchronously
ā€“ Performs round trip(s) to the database
ā€“ Executes result handling
ā€“ Completes CompletableFutures
15
Everything is an Operation
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. |
public DataSource getDataSource(String url, String user, String pass) {
return DataSourceFactory.forName("Oracle Database")
.builder()
.url("oracle:database:@//javaone.oracle.com:5521/javaone")
.username("scott")
.password("tiger")
.connectionProperty(JdbcConnectionProperty.TRANSACTION_ISOLATION,
TransactionIsolation.SERIALIZABLE)
.build();
}
Getting a DataSource
16
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. |
in interface DataSource:
public default Connection getConnection() {
return builder().build().connect();
}
in interface Connection:
public default Connection connect() {
holdForMoreMembers();
submit();
connectOperation().submit();
return this;
}
Getting a Connection
17
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. |
public Future<Integer> selectIdForAnswer(DataSource ds, int answer) {
String sql = "select id, name, answer from tab " +
"where answer = @target";
try (Connection conn = ds.getConnection()) {
return conn.<List<Integer>>rowOperation(sql)
.set("target", 42, JdbcType.NUMERIC)
.initialValue( () -> new ArrayList<>() )
.rowAggregator( (list, row) -> {
list.add(row.get("id", Integer.class));
return list;
} )
.submit()
.toCompletableFuture()
.thenApply( l -> l.get(0) );
}
}
Basic SELECT
18
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. |
public static class Item {
protected int id;
protected String name;
protected int answer;
@SqlColumns( { ā€œIDā€, ā€œUSERā€, ā€œRESPONSEā€ } )
public Item(int id, String name, int answer) {
this.id = id;
this.name = name;
this.answer = answer;
}
(cont.)
POJOs
19
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. |
@SqlParameter(marker=ā€idā€, sqlType="NUMERIC")
public int getId() {
return id;
}
@SqlParameter(marker=ā€nameā€, sqlType="VARCHAR")
public String getName() {
return name;
}
@SqlParameter(marker=ā€answerā€, sqlType="NUMERIC")
public int getAnswer() {
return answer;
}
}
POJOs (cont.)
20
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. |
public void insertListIndependent(List<Item> list, DataSource ds) {
String sql = "insert into tab values " +
"(:elem_id, :elem_name, :elem_answer)";
try (Connection conn = ds.getConnection()) {
BatchCountOperation batch = conn.batchCountOperation(sql);
list.forEach( (elem) -> {
batch.countOperation()
.set("elem_", elem)
.submit();
});
batch.submit();
}
}
Batch Insert
21
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. |
OperationGroup
ā€¢ OperationGroup has its own result handling and CompletableFuture
ā€¢ Members submitted to group. OperationGroup is submitted as a unit
ā€¢ Order of execution
ā€“ Sequential in order submitted
ā€“ Parallel, any order
ā€¢ Error response
ā€“ Dependent: remaining group members skipped
ā€“ Independent: remaining group members unaffected
ā€¢ Conditional or unconditional
ā€¢ Connection is an OperationGroup
ā€“ Sequential, dependent, unconditional by default
22
Operations can be grouped
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. |
public void insertListHold(List<Item> list, DataSource ds) {
String sql = "insert into tab " +
"values (@elem_id, @elem_name, @elem_answer)";
try (Connection conn = ds.getConnection()) {
OperationGroup group = conn.operationGroup()
.holdForMoreMembers()
.independent();
group.submit();
(cont.)
Independent INSERT
23
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. |
for (Item elem : list) {
group.countOperation(sql)
.set("elem_", elem)
.submit()
.toCompletableFuture()
.exceptionally( t -> {
System.out.println(elem.getId());
return null;
});
}
group.releaseProhibitingMoreMembers();
}
}
Independent Insert (cont.)
24
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. |
in interface Connection
public default void close() {
closeOperation().submit();
releaseProhibitingMoreMembers();
}
Note: A CloseOperation is never skipped.
Close
25
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. |
in interface Connection
public Connection activate();
public Connection deactivate();
public registerLifecycleListener(LifecycleListener listener);
Connection Pooling
26
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. |
public DataSource getDataSource(String url, String user, String pass) {
return DataSourceFactory.forName("Oracle Database")
.builder()
.url("oracle:database:@//javaone.oracle.com:5521/javaone")
.username("scott")
.password("tiger")
.connectionProperty(JdbcConnectionProperty.TRANSACTION_ISOLATION,
TransactionIsolation.SERIALIZABLE)
.connectionProperty(NLS_LANGUAGE, ā€œFrenchā€)
.build();
}
ConnectionProperties
27
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. |
public static class NlsLanguageProperty implements ConnectionProperty {
public static final ConnectionProperty NLS_LANGUAGE
= new NlsLanguageProperty();
private NlsLanguageProperty() {}
public String name() { return ā€œNLS_LANGUAGEā€; }
public Class range() { return String.class; }
public String defaultValue() { return ā€œAmericanā€; }
public boolean isSensitive() { return false; }
public Operation configureOperation(OperationGroup group, Object value) {
String sql = ā€œALTER SESSION SET NLS_LANGUAGE TO ā€œ + value;
return group.operation(sql);
}
ConnectionProperty
28
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. |
@SqlArray(elementSqlTypeName=ā€STUDENTā€)
public class Roster extends LinkedList<Student> {
public Roster() {};
}
@SqlStruct(sqlTypeName=ā€STUDENTā€, fields={
@Field(sqlFieldName=ā€NAMEā€, sqlTypeName=ā€VARCHAR(100)ā€, javaFieldName=ā€nameā€),
@Field(sqlFieldName=ā€EMAILā€, sqlTypeName=ā€VARCHAR(100)ā€,
javaFieldName=ā€emailā€)})
public class Student {
String name;
String email;
public void setName(String n) {name = n;}
public void setEmail(String e) {email = e;}
public String getName() {return name;}
public String getEmail() {return email;}
}
ARRAYs and STRUCTs
29
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. |
public void transfer(Connection conn,
double amount, int fromAccount, int toAccount) {
String sql = ā€œupdate account set balance=balance+@amount where id = @accountā€;
conn.countOperation(sql)
.set(ā€œamountā€, -amount, JdbcType.DECIMAL)
.set(ā€œaccountā€, fromAccount, JdbcType.INTEGER)
.submit();
conn.countOperation(sql)
.set(ā€œamountā€, amount, JdbcType.DECIMAL)
.set(ā€œaccountā€, toAccount, JdbcType.INTEGER)
.submit();
conn.commit();
}
Transactions
30
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. |
public void transfer(Connection conn,
double amount, int fromAccount, int toAccount) {
String sql = ā€œupdate account set balance=balance+@amount where id = @accountā€;
final Transaction tran = conn.getTransaction();
conn.countOperation(sql)
.set(ā€œamountā€, -amount, JdbcType.DECIMAL)
.set(ā€œaccountā€, fromAccount, JdbcType.INTEGER)
.onError( e -> tran.setRollbackOnly() )
.submit();
conn.countOperation(sql)
.set(ā€œamountā€, amount, JdbcType.DECIMAL)
.set(ā€œaccountā€, toAccount, JdbcType.INTEGER)
.onError( e -> tran.setRollbackOnly() )
.submit();
conn.commit();
}
Transactions (cont.)
31
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. |
public void paycheck(Connection conn, Employee emp) {
String sql = ā€œcall generate_paycheck(?, ?)ā€;
CompletableFuture<CheckDetail> details = conn.<CheckDetail>outOperation(sql)
.set(ā€œ1ā€, emp, JdbcType.STRUCT)
.outParameter(ā€œ2ā€, JdbcType.STRUCT)
.resultProcessor( m -> m.get(ā€œ2ā€, CheckDetail.class) )
.submit()
.toCompletableFuture();
conn.localOperation()
.onExecution( () -> { printPaycheck(details); return null; } )
.submit()
.toCompletableFuture()
.thenRun( () -> reportPrintSuccess(details) );
.exceptionally( t -> {reportPrintFailure(details); return null;} );
}
Local Operations
32
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. |
public void deposit(Connection conn, int accountId, double amount) {
String selectSql = ā€œselect balance from account where id = $1ā€;
CompletableFuture<Double> newBalanceF = conn <Double>rowOperation(selectSql)
.set(ā€œ1ā€, accountId, JdbcType.INTEGER)
.rowAggregator( (p, row) -> row.get(ā€œbalanceā€, Double.class) )
.submit()
.toCompletableFuture()
.thenApply( b -> b + amount );
String updateSql = ā€œupdate account set balance=$2 where id = $1ā€;
conn.countOperation(updateSql)
.set(ā€œ1ā€, accountId, JdbcType.INTEGER)
.set(ā€œ2ā€, newBalanceF, JdbcType.DOUBLE)
.submit();
}
Future Parameters
33
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. |
Wrap-up
34
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. |
Status
ā€¢ Everything is subject to change
ā€¢ Prototype Oracle Database driver implements much of the API
ā€“ Uses nio Selector so non-blocking all the way down
ā€¢ Developed by the JDBC Expert Group through the Java Community Process
ā€¢ Targeted for a near future release, Java 10 or equivalent
ā€¢ The API is available for download from OpenJDK at
http://oracle.com/goto/java-async-db
ā€¢ Send feedback to jdbc-spec-discuss@openjdk.java.net
35
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. |
Q&A
36
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | 37
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. |
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package test;
import java.sql2.BatchCountOperation;
import java.sql2.Connection;
import java.sql2.ConnectionProperty;
import java.sql2.DataSource;
import java.sql2.DataSourceFactory;
import java.sql2.JdbcConnectionProperty;
import java.sql2.JdbcConnectionProperty.TransactionIsolation;
import java.sql2.JdbcType;
import java.sql2.Operation;
import java.sql2.OperationGroup;
import java.sql2.SqlArray;
import java.sql2.SqlColumns;
import java.sql2.SqlParameter;
import java.sql2.SqlStruct;
import java.sql2.SqlStruct.Field;
import java.sql2.Transaction;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.function.Consumer;
/**
*
* Code from JavaOne 2017 slides: CON-1491
* JDBC Next: A New Asynchronous API for Connecting to a Database
*
*/
public class JavaOne {
public void trivialInsert(DataSource ds) {
String sql = "insert into tab values (:id, :name, :answer)";
try (Connection conn = ds.getConnection()) {
conn.countOperation(sql)
.set("id", 1, JdbcType.NUMERIC)
.set("name", "Deep Thought", JdbcType.VARCHAR)
.set("answer", 42, JdbcType.NUMERIC)
.submit();
}
}
public void trivialSelect(DataSource ds, List<Integer> result) {
String sql = "select id, name, answer "
+ "from tab where answer = $1";
try (Connection conn = ds.getConnection()) {
conn.<List<Integer>>rowOperation(sql)
.set("1", 42, JdbcType.NUMERIC)
.rowAggregator((ignore, row) -> {
result.add(row.get("id", Integer.class));
return null;
})
.submit();
}
}
public DataSource getDataSource(String url, String user, String pass) {
return DataSourceFactory.forName("Oracle Database")
.builder()
.url("oracle:database:@//javaone.oracle.com:5521/javaone")
.username("scott")
.password("tiger")
.connectionProperty(JdbcConnectionProperty.TRANSACTION_ISOLATION,
TransactionIsolation.SERIALIZABLE)
.build();
}
public Future<Integer> selectIdForAnswer(DataSource ds, int answer) {
String sql = "select id, name, answer from tab "
+ "where answer = @target";
try (Connection conn = ds.getConnection()) {
return conn.<List<Integer>>rowOperation(sql)
.set("target", 42, JdbcType.NUMERIC)
.initialValue(() -> new ArrayList<>())
.rowAggregator((list, row) -> {
list.add(row.get("id", Integer.class));
return list;
})
.submit()
.toCompletableFuture()
.thenApply(l -> l.get(0));
}
}
public void insertListIndependent(List<Item> list, DataSource ds) {
String sql = "insert into tab values "
+ "(:elem_id, :elem_name, :elem_answer)";
try (Connection conn = ds.getConnection()) {
BatchCountOperation batch = conn.batchCountOperation(sql);
list.forEach((elem) -> {
batch.countOperation()
.set("elem_", elem)
.submit();
});
batch.submit();
}
}
public void insertListHold(List<Item> list, DataSource ds) {
String sql = "insert into tab "
+ "values (@elem_id, @elem_name, @elem_answer)";
try (Connection conn = ds.getConnection()) {
OperationGroup group = conn.operationGroup()
.holdForMoreMembers()
.independent();
group.submit();
for (Item elem : list) {
group.countOperation(sql)
.set("elem_", elem)
.submit()
.toCompletableFuture()
.exceptionally(t -> {
System.out.println(elem.getId());
return null;
});
}
group.releaseProhibitingMoreMembers();
}
}
public DataSource getDataSource_2(String url, String user, String pass) {
return DataSourceFactory.forName("Oracle Database")
.builder()
.url("oracle:database:@//javaone.oracle.com:5521/javaone")
.username("scott")
.password("tiger")
.connectionProperty(JdbcConnectionProperty.TRANSACTION_ISOLATION,
TransactionIsolation.SERIALIZABLE)
.connectionProperty(NlsLanguageProperty.NLS_LANGUAGE, "French")
.build();
}
public void transfer(Connection conn,
double amount, int fromAccount, int toAccount) {
String sql = "update account set balance=balance+@amount where id =
@account";
conn.countOperation(sql)
.set("amount", -amount, JdbcType.DECIMAL)
.set("account", fromAccount, JdbcType.INTEGER)
.submit();
conn.countOperation(sql)
.set("amount", amount, JdbcType.DECIMAL)
.set("account", toAccount, JdbcType.INTEGER)
.submit();
conn.commit();
}
public void transfer_2(Connection conn,
double amount, int fromAccount, int toAccount) {
String sql = "update account set balance=balance+@amount where id =
@account";
final Transaction tran = conn.getTransaction();
conn.countOperation(sql)
.set("amount", -amount, JdbcType.DECIMAL)
.set("account", fromAccount, JdbcType.INTEGER)
.onError(e -> tran.setRollbackOnly())
.submit();
conn.countOperation(sql)
.set("amount", amount, JdbcType.DECIMAL)
.set("account", toAccount, JdbcType.INTEGER)
.onError(e -> tran.setRollbackOnly())
.submit();
conn.commit();
}
public void paycheck(Connection conn, Employee emp) {
String sql = "call generate_paycheck(?, ?)";
CompletableFuture<CheckDetail> details =
conn.<CheckDetail>outOperation(sql)
.set("1", emp, JdbcType.STRUCT)
.outParameter("2", JdbcType.STRUCT)
.resultProcessor(m -> m.get("2", CheckDetail.class))
.submit()
.toCompletableFuture();
conn.localOperation()
.onExecution(() -> {
printPaycheck(details);
return null;
})
.submit()
.toCompletableFuture()
.thenRun(() -> reportPrintSuccess(details))
.exceptionally(t -> {
reportPrintFailure(details);
return null;
});
}
Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. |
public void deposit(Connection conn, int accountId, double amount) {
String selectSql = "select balance from account where id = $1";
CompletableFuture<Double> newBalanceF =
conn.<Double>rowOperation(selectSql)
.set("1", accountId, JdbcType.INTEGER)
.rowAggregator((p, row) -> row.get("balance", Double.class))
.submit()
.toCompletableFuture()
.thenApply(b -> b + amount);
String updateSql = "update account set balance=$2 where id = $1";
conn.countOperation(updateSql)
.set("1", accountId, JdbcType.INTEGER)
.set("2", newBalanceF, JdbcType.DOUBLE)
.submit();
}
public static class Item {
protected int id;
protected String name;
protected int answer;
@SqlColumns({"ID", "USER", "RESPONSE"})
public Item(int id, String name, int answer) {
this.id = id;
this.name = name;
this.answer = answer;
}
@SqlParameter(marker = "id", sqlType = "NUMERIC")
public int getId() {
return id;
}
@SqlParameter(marker = "name", sqlType = "VARCHAR")
public String getName() {
return name;
}
@SqlParameter(marker = "answer", sqlType = "NUMERIC")
public int getAnswer() {
return answer;
}
}
public static class NlsLanguageProperty implements ConnectionProperty {
public static final ConnectionProperty NLS_LANGUAGE
= new NlsLanguageProperty();
private NlsLanguageProperty() {
}
@Override
public String name() {
return "NLS_LANGUAGE";
}
@Override
public Class range() {
return String.class;
}
@Override
public String defaultValue() {
return "American";
}
@Override
public boolean isSensitive() {
return false;
}
@Override
public Operation configureOperation(OperationGroup group, Object value) {
String sql = "ALTER SESSION SET NLS_LANGUAGE TO " + value;
return group.operation(sql);
}
}
@SqlArray(elementSqlTypeName = "STUDENT")
public static class Roster extends LinkedList<Student> {
public Roster() {
}
}
@SqlStruct(sqlTypeName = "STUDENT", fields = {
@Field(sqlFieldName = "NAME", sqlTypeName = "VARCHAR(100)", javaFieldName = "name"),
@Field(sqlFieldName = "EMAIL", sqlTypeName = "VARCHAR(100)", javaFieldName = "email")})
public class Student {
String name;
String email;
public void setName(String n) {
name = n;
}
public void setEmail(String e) {
email = e;
}
public String getName() {
return name;
}
public String getEmail() {
return email;
}
}
public class Employee {
}
public class CheckDetail {
}
private void printPaycheck(Future<CheckDetail> checkF) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of
generated methods, choose Tools | Templates.
}
private Consumer<? super Object> reportPrintSuccess(Future<CheckDetail> checkF) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of
generated methods, choose Tools | Templates.
}
private CompletableFuture<Void> reportPrintFailure(Future<CheckDetail> checkF) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of
generated methods, choose Tools | Templates.
}
}

More Related Content

What's hot

How many ways to monitor oracle golden gate - OOW14
How many ways to monitor oracle golden gate - OOW14How many ways to monitor oracle golden gate - OOW14
How many ways to monitor oracle golden gate - OOW14Bobby Curtis
Ā 
Enable GoldenGate Monitoring with OEM 12c/JAgent
Enable GoldenGate Monitoring with OEM 12c/JAgentEnable GoldenGate Monitoring with OEM 12c/JAgent
Enable GoldenGate Monitoring with OEM 12c/JAgentBobby Curtis
Ā 
How easy (or hard) it is to monitor your graph ql service performance
How easy (or hard) it is to monitor your graph ql service performanceHow easy (or hard) it is to monitor your graph ql service performance
How easy (or hard) it is to monitor your graph ql service performanceLuca Mattia Ferrari
Ā 
R2DBC JEEConf 2019 by Igor Lozynskyi
R2DBC JEEConf 2019 by Igor LozynskyiR2DBC JEEConf 2019 by Igor Lozynskyi
R2DBC JEEConf 2019 by Igor LozynskyiIgor Lozynskyi
Ā 
How and why to upgrade to java 16 or 17
How and why to upgrade to java 16 or 17How and why to upgrade to java 16 or 17
How and why to upgrade to java 16 or 17Johan Janssen
Ā 
Extreme replication at IOUG Collaborate 15
Extreme replication at IOUG Collaborate 15Extreme replication at IOUG Collaborate 15
Extreme replication at IOUG Collaborate 15Bobby Curtis
Ā 
Oracle GoldenGate and Baseball - 5 Keys for Moving to the Cloud
Oracle GoldenGate and Baseball - 5 Keys for Moving to the CloudOracle GoldenGate and Baseball - 5 Keys for Moving to the Cloud
Oracle GoldenGate and Baseball - 5 Keys for Moving to the CloudBobby Curtis
Ā 
Exachk and oem12c
Exachk and oem12cExachk and oem12c
Exachk and oem12cBobby Curtis
Ā 
Oracle GoldenGate 18c - REST API Examples
Oracle GoldenGate 18c - REST API ExamplesOracle GoldenGate 18c - REST API Examples
Oracle GoldenGate 18c - REST API ExamplesBobby Curtis
Ā 
MV2ADB - Move to Oracle Autonomous Database in One-click
MV2ADB - Move to Oracle Autonomous Database in One-clickMV2ADB - Move to Oracle Autonomous Database in One-click
MV2ADB - Move to Oracle Autonomous Database in One-clickRuggero Citton
Ā 
Continuous DB Changes Delivery With Liquibase
Continuous DB Changes Delivery With LiquibaseContinuous DB Changes Delivery With Liquibase
Continuous DB Changes Delivery With LiquibaseAidas Dragūnas
Ā 
Oracle GoldenGate on Docker
Oracle GoldenGate on DockerOracle GoldenGate on Docker
Oracle GoldenGate on DockerBobby Curtis
Ā 
Terraform & Oracle Cloud Infrastructure
Terraform & Oracle Cloud InfrastructureTerraform & Oracle Cloud Infrastructure
Terraform & Oracle Cloud InfrastructureBobby Curtis
Ā 
R2DBC Reactive Relational Database Connectivity
R2DBC Reactive Relational Database ConnectivityR2DBC Reactive Relational Database Connectivity
R2DBC Reactive Relational Database ConnectivityMaarten Smeets
Ā 
Migrating to Spark 2.0 - Part 2
Migrating to Spark 2.0 - Part 2Migrating to Spark 2.0 - Part 2
Migrating to Spark 2.0 - Part 2datamantra
Ā 
Database Migrations with Gradle and Liquibase
Database Migrations with Gradle and LiquibaseDatabase Migrations with Gradle and Liquibase
Database Migrations with Gradle and LiquibaseDan Stine
Ā 
12 Factor App: Best Practices for JVM Deployment
12 Factor App: Best Practices for JVM Deployment12 Factor App: Best Practices for JVM Deployment
12 Factor App: Best Practices for JVM DeploymentJoe Kutner
Ā 
Oem12c patching -OOW13
Oem12c patching -OOW13Oem12c patching -OOW13
Oem12c patching -OOW13Bobby Curtis
Ā 
Extreme Replication - RMOUG Presentation
Extreme Replication - RMOUG PresentationExtreme Replication - RMOUG Presentation
Extreme Replication - RMOUG PresentationBobby Curtis
Ā 

What's hot (20)

How many ways to monitor oracle golden gate - OOW14
How many ways to monitor oracle golden gate - OOW14How many ways to monitor oracle golden gate - OOW14
How many ways to monitor oracle golden gate - OOW14
Ā 
Enable GoldenGate Monitoring with OEM 12c/JAgent
Enable GoldenGate Monitoring with OEM 12c/JAgentEnable GoldenGate Monitoring with OEM 12c/JAgent
Enable GoldenGate Monitoring with OEM 12c/JAgent
Ā 
How easy (or hard) it is to monitor your graph ql service performance
How easy (or hard) it is to monitor your graph ql service performanceHow easy (or hard) it is to monitor your graph ql service performance
How easy (or hard) it is to monitor your graph ql service performance
Ā 
R2DBC JEEConf 2019 by Igor Lozynskyi
R2DBC JEEConf 2019 by Igor LozynskyiR2DBC JEEConf 2019 by Igor Lozynskyi
R2DBC JEEConf 2019 by Igor Lozynskyi
Ā 
How and why to upgrade to java 16 or 17
How and why to upgrade to java 16 or 17How and why to upgrade to java 16 or 17
How and why to upgrade to java 16 or 17
Ā 
Extreme replication at IOUG Collaborate 15
Extreme replication at IOUG Collaborate 15Extreme replication at IOUG Collaborate 15
Extreme replication at IOUG Collaborate 15
Ā 
Oracle GoldenGate and Baseball - 5 Keys for Moving to the Cloud
Oracle GoldenGate and Baseball - 5 Keys for Moving to the CloudOracle GoldenGate and Baseball - 5 Keys for Moving to the Cloud
Oracle GoldenGate and Baseball - 5 Keys for Moving to the Cloud
Ā 
Exachk and oem12c
Exachk and oem12cExachk and oem12c
Exachk and oem12c
Ā 
Oracle GoldenGate 18c - REST API Examples
Oracle GoldenGate 18c - REST API ExamplesOracle GoldenGate 18c - REST API Examples
Oracle GoldenGate 18c - REST API Examples
Ā 
MV2ADB - Move to Oracle Autonomous Database in One-click
MV2ADB - Move to Oracle Autonomous Database in One-clickMV2ADB - Move to Oracle Autonomous Database in One-click
MV2ADB - Move to Oracle Autonomous Database in One-click
Ā 
Continuous DB Changes Delivery With Liquibase
Continuous DB Changes Delivery With LiquibaseContinuous DB Changes Delivery With Liquibase
Continuous DB Changes Delivery With Liquibase
Ā 
Oracle GoldenGate on Docker
Oracle GoldenGate on DockerOracle GoldenGate on Docker
Oracle GoldenGate on Docker
Ā 
Terraform & Oracle Cloud Infrastructure
Terraform & Oracle Cloud InfrastructureTerraform & Oracle Cloud Infrastructure
Terraform & Oracle Cloud Infrastructure
Ā 
R2DBC Reactive Relational Database Connectivity
R2DBC Reactive Relational Database ConnectivityR2DBC Reactive Relational Database Connectivity
R2DBC Reactive Relational Database Connectivity
Ā 
Migrating to Spark 2.0 - Part 2
Migrating to Spark 2.0 - Part 2Migrating to Spark 2.0 - Part 2
Migrating to Spark 2.0 - Part 2
Ā 
Database Migrations with Gradle and Liquibase
Database Migrations with Gradle and LiquibaseDatabase Migrations with Gradle and Liquibase
Database Migrations with Gradle and Liquibase
Ā 
12 Factor App: Best Practices for JVM Deployment
12 Factor App: Best Practices for JVM Deployment12 Factor App: Best Practices for JVM Deployment
12 Factor App: Best Practices for JVM Deployment
Ā 
Oem12c patching -OOW13
Oem12c patching -OOW13Oem12c patching -OOW13
Oem12c patching -OOW13
Ā 
Reactors.io
Reactors.ioReactors.io
Reactors.io
Ā 
Extreme Replication - RMOUG Presentation
Extreme Replication - RMOUG PresentationExtreme Replication - RMOUG Presentation
Extreme Replication - RMOUG Presentation
Ā 

Similar to JDBC Next: A New Asynchronous API for Connecting to a Database

Silicon Valley JUG meetup July 18, 2018
Silicon Valley JUG meetup July 18, 2018Silicon Valley JUG meetup July 18, 2018
Silicon Valley JUG meetup July 18, 2018Oracle Developers
Ā 
Reactive Java Programming: A new Asynchronous Database Access API by Kuassi M...
Reactive Java Programming: A new Asynchronous Database Access API by Kuassi M...Reactive Java Programming: A new Asynchronous Database Access API by Kuassi M...
Reactive Java Programming: A new Asynchronous Database Access API by Kuassi M...Oracle Developers
Ā 
ADBA (Asynchronous Database Access)
ADBA (Asynchronous Database Access)ADBA (Asynchronous Database Access)
ADBA (Asynchronous Database Access)Logico
Ā 
War of the Indices- SQL vs. Oracle
War of the Indices-  SQL vs. OracleWar of the Indices-  SQL vs. Oracle
War of the Indices- SQL vs. OracleKellyn Pot'Vin-Gorman
Ā 
Data access
Data accessData access
Data accessJoshua Yoon
Ā 
Lambdas & Streams
Lambdas & StreamsLambdas & Streams
Lambdas & StreamsC4Media
Ā 
Lambdas and-streams-s ritter-v3
Lambdas and-streams-s ritter-v3Lambdas and-streams-s ritter-v3
Lambdas and-streams-s ritter-v3Simon Ritter
Ā 
Functional Programming With Lambdas and Streams in JDK8
 Functional Programming With Lambdas and Streams in JDK8 Functional Programming With Lambdas and Streams in JDK8
Functional Programming With Lambdas and Streams in JDK8IndicThreads
Ā 
MySQL 8.0 Optimizer Guide
MySQL 8.0 Optimizer GuideMySQL 8.0 Optimizer Guide
MySQL 8.0 Optimizer GuideMorgan Tocker
Ā 
The Power of Relationships in Your Big Data
The Power of Relationships in Your Big DataThe Power of Relationships in Your Big Data
The Power of Relationships in Your Big DataPaulo Fagundes
Ā 
Oracle NoSQL Database release 3.0 overview
Oracle NoSQL Database release 3.0 overviewOracle NoSQL Database release 3.0 overview
Oracle NoSQL Database release 3.0 overviewDave Segleau
Ā 
Project Lambda: Functional Programming Constructs in Java - Simon Ritter (Ora...
Project Lambda: Functional Programming Constructs in Java - Simon Ritter (Ora...Project Lambda: Functional Programming Constructs in Java - Simon Ritter (Ora...
Project Lambda: Functional Programming Constructs in Java - Simon Ritter (Ora...jaxLondonConference
Ā 
JAX-RS 2.0: RESTful Web Services
JAX-RS 2.0: RESTful Web ServicesJAX-RS 2.0: RESTful Web Services
JAX-RS 2.0: RESTful Web ServicesArun Gupta
Ā 
20171104 hk-py con-mysql-documentstore_v1
20171104 hk-py con-mysql-documentstore_v120171104 hk-py con-mysql-documentstore_v1
20171104 hk-py con-mysql-documentstore_v1Ivan Ma
Ā 
20180420 hk-the powerofmysql8
20180420 hk-the powerofmysql820180420 hk-the powerofmysql8
20180420 hk-the powerofmysql8Ivan Ma
Ā 
What's New MySQL 8.0?
What's New MySQL 8.0?What's New MySQL 8.0?
What's New MySQL 8.0?OracleMySQL
Ā 
Advanced SQL - Database Access from Programming Languages
Advanced SQL - Database Access  from Programming LanguagesAdvanced SQL - Database Access  from Programming Languages
Advanced SQL - Database Access from Programming LanguagesS.Shayan Daneshvar
Ā 
Optimizer percona live_ams2015
Optimizer percona live_ams2015Optimizer percona live_ams2015
Optimizer percona live_ams2015Manyi Lu
Ā 

Similar to JDBC Next: A New Asynchronous API for Connecting to a Database (20)

Silicon Valley JUG meetup July 18, 2018
Silicon Valley JUG meetup July 18, 2018Silicon Valley JUG meetup July 18, 2018
Silicon Valley JUG meetup July 18, 2018
Ā 
Reactive Java Programming: A new Asynchronous Database Access API by Kuassi M...
Reactive Java Programming: A new Asynchronous Database Access API by Kuassi M...Reactive Java Programming: A new Asynchronous Database Access API by Kuassi M...
Reactive Java Programming: A new Asynchronous Database Access API by Kuassi M...
Ā 
ADBA (Asynchronous Database Access)
ADBA (Asynchronous Database Access)ADBA (Asynchronous Database Access)
ADBA (Asynchronous Database Access)
Ā 
War of the Indices- SQL vs. Oracle
War of the Indices-  SQL vs. OracleWar of the Indices-  SQL vs. Oracle
War of the Indices- SQL vs. Oracle
Ā 
Data access
Data accessData access
Data access
Ā 
Lambdas & Streams
Lambdas & StreamsLambdas & Streams
Lambdas & Streams
Ā 
MySQL Quick Dive
MySQL Quick DiveMySQL Quick Dive
MySQL Quick Dive
Ā 
Lambdas and-streams-s ritter-v3
Lambdas and-streams-s ritter-v3Lambdas and-streams-s ritter-v3
Lambdas and-streams-s ritter-v3
Ā 
Functional Programming With Lambdas and Streams in JDK8
 Functional Programming With Lambdas and Streams in JDK8 Functional Programming With Lambdas and Streams in JDK8
Functional Programming With Lambdas and Streams in JDK8
Ā 
MySQL 8.0 Optimizer Guide
MySQL 8.0 Optimizer GuideMySQL 8.0 Optimizer Guide
MySQL 8.0 Optimizer Guide
Ā 
The Power of Relationships in Your Big Data
The Power of Relationships in Your Big DataThe Power of Relationships in Your Big Data
The Power of Relationships in Your Big Data
Ā 
Oracle NoSQL Database release 3.0 overview
Oracle NoSQL Database release 3.0 overviewOracle NoSQL Database release 3.0 overview
Oracle NoSQL Database release 3.0 overview
Ā 
Project Lambda: Functional Programming Constructs in Java - Simon Ritter (Ora...
Project Lambda: Functional Programming Constructs in Java - Simon Ritter (Ora...Project Lambda: Functional Programming Constructs in Java - Simon Ritter (Ora...
Project Lambda: Functional Programming Constructs in Java - Simon Ritter (Ora...
Ā 
JAX-RS 2.0: RESTful Web Services
JAX-RS 2.0: RESTful Web ServicesJAX-RS 2.0: RESTful Web Services
JAX-RS 2.0: RESTful Web Services
Ā 
20171104 hk-py con-mysql-documentstore_v1
20171104 hk-py con-mysql-documentstore_v120171104 hk-py con-mysql-documentstore_v1
20171104 hk-py con-mysql-documentstore_v1
Ā 
20180420 hk-the powerofmysql8
20180420 hk-the powerofmysql820180420 hk-the powerofmysql8
20180420 hk-the powerofmysql8
Ā 
What's New MySQL 8.0?
What's New MySQL 8.0?What's New MySQL 8.0?
What's New MySQL 8.0?
Ā 
Advanced SQL - Database Access from Programming Languages
Advanced SQL - Database Access  from Programming LanguagesAdvanced SQL - Database Access  from Programming Languages
Advanced SQL - Database Access from Programming Languages
Ā 
Java ee7 1hour
Java ee7 1hourJava ee7 1hour
Java ee7 1hour
Ā 
Optimizer percona live_ams2015
Optimizer percona live_ams2015Optimizer percona live_ams2015
Optimizer percona live_ams2015
Ā 

More from Yolande Poirier

Social Media Secrets
Social Media Secrets Social Media Secrets
Social Media Secrets Yolande Poirier
Ā 
Way to Ally for Women in Java
Way to Ally for Women in Java Way to Ally for Women in Java
Way to Ally for Women in Java Yolande Poirier
Ā 
Way to Ally for Women in Technology!
Way to Ally for Women in Technology! Way to Ally for Women in Technology!
Way to Ally for Women in Technology! Yolande Poirier
Ā 
Twitter for developers
Twitter for developers  Twitter for developers
Twitter for developers Yolande Poirier
Ā 
More java community insider secrets
More java community insider secretsMore java community insider secrets
More java community insider secretsYolande Poirier
Ā 
Java Community and Overview Track - July 2015
Java Community and Overview Track - July 2015 Java Community and Overview Track - July 2015
Java Community and Overview Track - July 2015 Yolande Poirier
Ā 
Java Community and Overview Track - March 2016
Java Community and Overview Track - March 2016Java Community and Overview Track - March 2016
Java Community and Overview Track - March 2016Yolande Poirier
Ā 
Java Community News - September 2015
Java Community News - September 2015Java Community News - September 2015
Java Community News - September 2015Yolande Poirier
Ā 
Oracle Academy and ThinkQuest - Java Summer Workshop 2011
Oracle Academy and ThinkQuest - Java Summer Workshop 2011Oracle Academy and ThinkQuest - Java Summer Workshop 2011
Oracle Academy and ThinkQuest - Java Summer Workshop 2011Yolande Poirier
Ā 
Java summer workshop
Java summer workshop Java summer workshop
Java summer workshop Yolande Poirier
Ā 

More from Yolande Poirier (11)

Social Media Secrets
Social Media Secrets Social Media Secrets
Social Media Secrets
Ā 
Way to Ally for Women in Java
Way to Ally for Women in Java Way to Ally for Women in Java
Way to Ally for Women in Java
Ā 
Way to Ally for Women in Technology!
Way to Ally for Women in Technology! Way to Ally for Women in Technology!
Way to Ally for Women in Technology!
Ā 
Twitter for developers
Twitter for developers  Twitter for developers
Twitter for developers
Ā 
Java us tour 2017
Java us tour 2017Java us tour 2017
Java us tour 2017
Ā 
More java community insider secrets
More java community insider secretsMore java community insider secrets
More java community insider secrets
Ā 
Java Community and Overview Track - July 2015
Java Community and Overview Track - July 2015 Java Community and Overview Track - July 2015
Java Community and Overview Track - July 2015
Ā 
Java Community and Overview Track - March 2016
Java Community and Overview Track - March 2016Java Community and Overview Track - March 2016
Java Community and Overview Track - March 2016
Ā 
Java Community News - September 2015
Java Community News - September 2015Java Community News - September 2015
Java Community News - September 2015
Ā 
Oracle Academy and ThinkQuest - Java Summer Workshop 2011
Oracle Academy and ThinkQuest - Java Summer Workshop 2011Oracle Academy and ThinkQuest - Java Summer Workshop 2011
Oracle Academy and ThinkQuest - Java Summer Workshop 2011
Ā 
Java summer workshop
Java summer workshop Java summer workshop
Java summer workshop
Ā 

Recently uploaded

šŸ¬ The future of MySQL is Postgres šŸ˜
šŸ¬  The future of MySQL is Postgres   šŸ˜šŸ¬  The future of MySQL is Postgres   šŸ˜
šŸ¬ The future of MySQL is Postgres šŸ˜RTylerCroy
Ā 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
Ā 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
Ā 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
Ā 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
Ā 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
Ā 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
Ā 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
Ā 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
Ā 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
Ā 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
Ā 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
Ā 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
Ā 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessPixlogix Infotech
Ā 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
Ā 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
Ā 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
Ā 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
Ā 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
Ā 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
Ā 

Recently uploaded (20)

šŸ¬ The future of MySQL is Postgres šŸ˜
šŸ¬  The future of MySQL is Postgres   šŸ˜šŸ¬  The future of MySQL is Postgres   šŸ˜
šŸ¬ The future of MySQL is Postgres šŸ˜
Ā 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
Ā 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Ā 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
Ā 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
Ā 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Ā 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Ā 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
Ā 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
Ā 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
Ā 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
Ā 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
Ā 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
Ā 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
Ā 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
Ā 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Ā 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Ā 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
Ā 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
Ā 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
Ā 

JDBC Next: A New Asynchronous API for Connecting to a Database

  • 1.
  • 2.
  • 3. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | JDBC Next: A New Asynchronous API for Connecting to a Database CON1491 Douglas Surber JDBC Architect Oracle Database Server Technologies October 3, 2017 3
  • 4. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | Safe Harbor Statement The following is intended to outline our general product direction. It is intended for information purposes only, and may not be incorporated into any contract. It is not a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. The development, release, and timing of any features or functionality described for Oracleā€™s products remains at the sole discretion of Oracle.
  • 5. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | Program Agenda Overview1 2 3 4 Confidential ā€“ Oracle Internal/Restricted/Highly Restricted 5 Code Wrap-up Q&A
  • 6. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | Overview 6
  • 7. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | Asynchronous Database Access ā€¢ Java standard database access API that never blocks user threads ā€¢ Developed by the JDBC Expert Group with community input ā€¢ Targeted for a near future release, Java 10 or equivalent ā€¢ Asynchronous apps have better throughput ā€“ Fewer threads means less thread scheduling, less thread contention ā€“ Database access is slow so blocked threads leave resources idle for a long time ā€“ Simultaneous access to multiple databases, e.g. map/reduce, sharded databases ā€“ Fire and forget, e.g. DMS, stored procedures 7
  • 8. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | Goals ā€¢ No user thread blocks ever ā€“ Minimize the number of threads used for database access ā€¢ Alternate API for database access ā€“ Not an extension of the standard JDBC API ā€“ Not a replacement for the standard JDBC API ā€¢ Target high throughput apps ā€“ Not a completely general purpose database access API ā€“ The initial version will have a limited feature set ā€¢ Build on the Java SE class library 8
  • 9. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | Design Choices ā€¢ Minimal or no reference to java.sql ā€¢ Rigorous use of types ā€¢ Builder pattern ā€¢ Fluent API ā€¢ Immutable after initialization ā€¢ One way to do something is enough ā€¢ Avoid SQL processing ā€¢ Avoid callback hell 9
  • 10. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | What About ā€¦ ? ā€¢ Streams ā€“ Java streams are inherently synchronous ā€¢ ReactiveStreams ā€“ Not integrated into the Java SE class library ā€¢ NodeJS ā€¢ ADBCJ There are already multiple asynchronous/non-blocking database access APIs 10
  • 11. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | Code 11
  • 12. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | public void trivialInsert(DataSource ds) { String sql = "insert into tab values (:id, :name, :answer)"; try (Connection conn = ds.getConnection()) { conn.countOperation(sql) .set("id", 1, JdbcType.NUMERIC) .set("name", "Deep Thought", JdbcType.VARCHAR) .set("answer", 42, JdbcType.NUMERIC) .submit(); } } Trivial Insert 12
  • 13. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | All SQL is Vendor Specific ā€¢ No escape sequences ā€¢ No specified parameter markers ā€¢ Non vendor specific syntax requires processing by the driver ā€“ Adds overhead ā€“ Increases code complexity ā€“ Minimal benefit as most apps are tied to a specific database regardless Note: Code examples use parameter markers from a variety of databases including DB2 (:foo), MySQL (?), Oracle Database(:foo), PostgresSQL($1), and SQL Server (@foo). 13
  • 14. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | public void trivialSelect(DataSource ds, List<Integer> result) { String sql = "select id, name, answer " + "from tab where answer = $1"; try (Connection conn = ds.getConnection()) { conn.<List<Integer>>rowOperation(sql) .set("1", 42, JdbcType.NUMERIC) .rowAggregator( (ignore, row) -> { result.add(row.get("id", Integer.class)); return null; } ) .submit(); } } Trivial Select 14
  • 15. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | Execution Model ā€¢ Operations consist of ā€“ SQL or other database operation ā€“ Parameter assignments ā€“ Result handling ā€“ Submission and CompletableFuture ā€¢ User thread creates and submits Operations ā€“ Creating and submitting never blocks; user thread never blocks ā€¢ Implementation executes those Operations asynchronously ā€“ Performs round trip(s) to the database ā€“ Executes result handling ā€“ Completes CompletableFutures 15 Everything is an Operation
  • 16. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | public DataSource getDataSource(String url, String user, String pass) { return DataSourceFactory.forName("Oracle Database") .builder() .url("oracle:database:@//javaone.oracle.com:5521/javaone") .username("scott") .password("tiger") .connectionProperty(JdbcConnectionProperty.TRANSACTION_ISOLATION, TransactionIsolation.SERIALIZABLE) .build(); } Getting a DataSource 16
  • 17. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | in interface DataSource: public default Connection getConnection() { return builder().build().connect(); } in interface Connection: public default Connection connect() { holdForMoreMembers(); submit(); connectOperation().submit(); return this; } Getting a Connection 17
  • 18. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | public Future<Integer> selectIdForAnswer(DataSource ds, int answer) { String sql = "select id, name, answer from tab " + "where answer = @target"; try (Connection conn = ds.getConnection()) { return conn.<List<Integer>>rowOperation(sql) .set("target", 42, JdbcType.NUMERIC) .initialValue( () -> new ArrayList<>() ) .rowAggregator( (list, row) -> { list.add(row.get("id", Integer.class)); return list; } ) .submit() .toCompletableFuture() .thenApply( l -> l.get(0) ); } } Basic SELECT 18
  • 19. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | public static class Item { protected int id; protected String name; protected int answer; @SqlColumns( { ā€œIDā€, ā€œUSERā€, ā€œRESPONSEā€ } ) public Item(int id, String name, int answer) { this.id = id; this.name = name; this.answer = answer; } (cont.) POJOs 19
  • 20. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | @SqlParameter(marker=ā€idā€, sqlType="NUMERIC") public int getId() { return id; } @SqlParameter(marker=ā€nameā€, sqlType="VARCHAR") public String getName() { return name; } @SqlParameter(marker=ā€answerā€, sqlType="NUMERIC") public int getAnswer() { return answer; } } POJOs (cont.) 20
  • 21. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | public void insertListIndependent(List<Item> list, DataSource ds) { String sql = "insert into tab values " + "(:elem_id, :elem_name, :elem_answer)"; try (Connection conn = ds.getConnection()) { BatchCountOperation batch = conn.batchCountOperation(sql); list.forEach( (elem) -> { batch.countOperation() .set("elem_", elem) .submit(); }); batch.submit(); } } Batch Insert 21
  • 22. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | OperationGroup ā€¢ OperationGroup has its own result handling and CompletableFuture ā€¢ Members submitted to group. OperationGroup is submitted as a unit ā€¢ Order of execution ā€“ Sequential in order submitted ā€“ Parallel, any order ā€¢ Error response ā€“ Dependent: remaining group members skipped ā€“ Independent: remaining group members unaffected ā€¢ Conditional or unconditional ā€¢ Connection is an OperationGroup ā€“ Sequential, dependent, unconditional by default 22 Operations can be grouped
  • 23. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | public void insertListHold(List<Item> list, DataSource ds) { String sql = "insert into tab " + "values (@elem_id, @elem_name, @elem_answer)"; try (Connection conn = ds.getConnection()) { OperationGroup group = conn.operationGroup() .holdForMoreMembers() .independent(); group.submit(); (cont.) Independent INSERT 23
  • 24. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | for (Item elem : list) { group.countOperation(sql) .set("elem_", elem) .submit() .toCompletableFuture() .exceptionally( t -> { System.out.println(elem.getId()); return null; }); } group.releaseProhibitingMoreMembers(); } } Independent Insert (cont.) 24
  • 25. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | in interface Connection public default void close() { closeOperation().submit(); releaseProhibitingMoreMembers(); } Note: A CloseOperation is never skipped. Close 25
  • 26. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | in interface Connection public Connection activate(); public Connection deactivate(); public registerLifecycleListener(LifecycleListener listener); Connection Pooling 26
  • 27. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | public DataSource getDataSource(String url, String user, String pass) { return DataSourceFactory.forName("Oracle Database") .builder() .url("oracle:database:@//javaone.oracle.com:5521/javaone") .username("scott") .password("tiger") .connectionProperty(JdbcConnectionProperty.TRANSACTION_ISOLATION, TransactionIsolation.SERIALIZABLE) .connectionProperty(NLS_LANGUAGE, ā€œFrenchā€) .build(); } ConnectionProperties 27
  • 28. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | public static class NlsLanguageProperty implements ConnectionProperty { public static final ConnectionProperty NLS_LANGUAGE = new NlsLanguageProperty(); private NlsLanguageProperty() {} public String name() { return ā€œNLS_LANGUAGEā€; } public Class range() { return String.class; } public String defaultValue() { return ā€œAmericanā€; } public boolean isSensitive() { return false; } public Operation configureOperation(OperationGroup group, Object value) { String sql = ā€œALTER SESSION SET NLS_LANGUAGE TO ā€œ + value; return group.operation(sql); } ConnectionProperty 28
  • 29. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | @SqlArray(elementSqlTypeName=ā€STUDENTā€) public class Roster extends LinkedList<Student> { public Roster() {}; } @SqlStruct(sqlTypeName=ā€STUDENTā€, fields={ @Field(sqlFieldName=ā€NAMEā€, sqlTypeName=ā€VARCHAR(100)ā€, javaFieldName=ā€nameā€), @Field(sqlFieldName=ā€EMAILā€, sqlTypeName=ā€VARCHAR(100)ā€, javaFieldName=ā€emailā€)}) public class Student { String name; String email; public void setName(String n) {name = n;} public void setEmail(String e) {email = e;} public String getName() {return name;} public String getEmail() {return email;} } ARRAYs and STRUCTs 29
  • 30. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | public void transfer(Connection conn, double amount, int fromAccount, int toAccount) { String sql = ā€œupdate account set balance=balance+@amount where id = @accountā€; conn.countOperation(sql) .set(ā€œamountā€, -amount, JdbcType.DECIMAL) .set(ā€œaccountā€, fromAccount, JdbcType.INTEGER) .submit(); conn.countOperation(sql) .set(ā€œamountā€, amount, JdbcType.DECIMAL) .set(ā€œaccountā€, toAccount, JdbcType.INTEGER) .submit(); conn.commit(); } Transactions 30
  • 31. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | public void transfer(Connection conn, double amount, int fromAccount, int toAccount) { String sql = ā€œupdate account set balance=balance+@amount where id = @accountā€; final Transaction tran = conn.getTransaction(); conn.countOperation(sql) .set(ā€œamountā€, -amount, JdbcType.DECIMAL) .set(ā€œaccountā€, fromAccount, JdbcType.INTEGER) .onError( e -> tran.setRollbackOnly() ) .submit(); conn.countOperation(sql) .set(ā€œamountā€, amount, JdbcType.DECIMAL) .set(ā€œaccountā€, toAccount, JdbcType.INTEGER) .onError( e -> tran.setRollbackOnly() ) .submit(); conn.commit(); } Transactions (cont.) 31
  • 32. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | public void paycheck(Connection conn, Employee emp) { String sql = ā€œcall generate_paycheck(?, ?)ā€; CompletableFuture<CheckDetail> details = conn.<CheckDetail>outOperation(sql) .set(ā€œ1ā€, emp, JdbcType.STRUCT) .outParameter(ā€œ2ā€, JdbcType.STRUCT) .resultProcessor( m -> m.get(ā€œ2ā€, CheckDetail.class) ) .submit() .toCompletableFuture(); conn.localOperation() .onExecution( () -> { printPaycheck(details); return null; } ) .submit() .toCompletableFuture() .thenRun( () -> reportPrintSuccess(details) ); .exceptionally( t -> {reportPrintFailure(details); return null;} ); } Local Operations 32
  • 33. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | public void deposit(Connection conn, int accountId, double amount) { String selectSql = ā€œselect balance from account where id = $1ā€; CompletableFuture<Double> newBalanceF = conn <Double>rowOperation(selectSql) .set(ā€œ1ā€, accountId, JdbcType.INTEGER) .rowAggregator( (p, row) -> row.get(ā€œbalanceā€, Double.class) ) .submit() .toCompletableFuture() .thenApply( b -> b + amount ); String updateSql = ā€œupdate account set balance=$2 where id = $1ā€; conn.countOperation(updateSql) .set(ā€œ1ā€, accountId, JdbcType.INTEGER) .set(ā€œ2ā€, newBalanceF, JdbcType.DOUBLE) .submit(); } Future Parameters 33
  • 34. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | Wrap-up 34
  • 35. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | Status ā€¢ Everything is subject to change ā€¢ Prototype Oracle Database driver implements much of the API ā€“ Uses nio Selector so non-blocking all the way down ā€¢ Developed by the JDBC Expert Group through the Java Community Process ā€¢ Targeted for a near future release, Java 10 or equivalent ā€¢ The API is available for download from OpenJDK at http://oracle.com/goto/java-async-db ā€¢ Send feedback to jdbc-spec-discuss@openjdk.java.net 35
  • 36. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | Q&A 36
  • 37. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | 37
  • 38.
  • 39.
  • 40. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | /* * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package test; import java.sql2.BatchCountOperation; import java.sql2.Connection; import java.sql2.ConnectionProperty; import java.sql2.DataSource; import java.sql2.DataSourceFactory; import java.sql2.JdbcConnectionProperty; import java.sql2.JdbcConnectionProperty.TransactionIsolation; import java.sql2.JdbcType; import java.sql2.Operation; import java.sql2.OperationGroup; import java.sql2.SqlArray; import java.sql2.SqlColumns; import java.sql2.SqlParameter; import java.sql2.SqlStruct; import java.sql2.SqlStruct.Field; import java.sql2.Transaction; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; import java.util.function.Consumer; /** * * Code from JavaOne 2017 slides: CON-1491 * JDBC Next: A New Asynchronous API for Connecting to a Database * */ public class JavaOne { public void trivialInsert(DataSource ds) { String sql = "insert into tab values (:id, :name, :answer)"; try (Connection conn = ds.getConnection()) { conn.countOperation(sql) .set("id", 1, JdbcType.NUMERIC) .set("name", "Deep Thought", JdbcType.VARCHAR) .set("answer", 42, JdbcType.NUMERIC) .submit(); } } public void trivialSelect(DataSource ds, List<Integer> result) { String sql = "select id, name, answer " + "from tab where answer = $1"; try (Connection conn = ds.getConnection()) { conn.<List<Integer>>rowOperation(sql) .set("1", 42, JdbcType.NUMERIC) .rowAggregator((ignore, row) -> { result.add(row.get("id", Integer.class)); return null; }) .submit(); } } public DataSource getDataSource(String url, String user, String pass) { return DataSourceFactory.forName("Oracle Database") .builder() .url("oracle:database:@//javaone.oracle.com:5521/javaone") .username("scott") .password("tiger") .connectionProperty(JdbcConnectionProperty.TRANSACTION_ISOLATION, TransactionIsolation.SERIALIZABLE) .build(); } public Future<Integer> selectIdForAnswer(DataSource ds, int answer) { String sql = "select id, name, answer from tab " + "where answer = @target"; try (Connection conn = ds.getConnection()) { return conn.<List<Integer>>rowOperation(sql) .set("target", 42, JdbcType.NUMERIC) .initialValue(() -> new ArrayList<>()) .rowAggregator((list, row) -> { list.add(row.get("id", Integer.class)); return list; }) .submit() .toCompletableFuture() .thenApply(l -> l.get(0)); } } public void insertListIndependent(List<Item> list, DataSource ds) { String sql = "insert into tab values " + "(:elem_id, :elem_name, :elem_answer)"; try (Connection conn = ds.getConnection()) { BatchCountOperation batch = conn.batchCountOperation(sql); list.forEach((elem) -> { batch.countOperation() .set("elem_", elem) .submit(); }); batch.submit(); } } public void insertListHold(List<Item> list, DataSource ds) { String sql = "insert into tab " + "values (@elem_id, @elem_name, @elem_answer)"; try (Connection conn = ds.getConnection()) { OperationGroup group = conn.operationGroup() .holdForMoreMembers() .independent(); group.submit(); for (Item elem : list) { group.countOperation(sql) .set("elem_", elem) .submit() .toCompletableFuture() .exceptionally(t -> { System.out.println(elem.getId()); return null; }); } group.releaseProhibitingMoreMembers(); } } public DataSource getDataSource_2(String url, String user, String pass) { return DataSourceFactory.forName("Oracle Database") .builder() .url("oracle:database:@//javaone.oracle.com:5521/javaone") .username("scott") .password("tiger") .connectionProperty(JdbcConnectionProperty.TRANSACTION_ISOLATION, TransactionIsolation.SERIALIZABLE) .connectionProperty(NlsLanguageProperty.NLS_LANGUAGE, "French") .build(); } public void transfer(Connection conn, double amount, int fromAccount, int toAccount) { String sql = "update account set balance=balance+@amount where id = @account"; conn.countOperation(sql) .set("amount", -amount, JdbcType.DECIMAL) .set("account", fromAccount, JdbcType.INTEGER) .submit(); conn.countOperation(sql) .set("amount", amount, JdbcType.DECIMAL) .set("account", toAccount, JdbcType.INTEGER) .submit(); conn.commit(); } public void transfer_2(Connection conn, double amount, int fromAccount, int toAccount) { String sql = "update account set balance=balance+@amount where id = @account"; final Transaction tran = conn.getTransaction(); conn.countOperation(sql) .set("amount", -amount, JdbcType.DECIMAL) .set("account", fromAccount, JdbcType.INTEGER) .onError(e -> tran.setRollbackOnly()) .submit(); conn.countOperation(sql) .set("amount", amount, JdbcType.DECIMAL) .set("account", toAccount, JdbcType.INTEGER) .onError(e -> tran.setRollbackOnly()) .submit(); conn.commit(); } public void paycheck(Connection conn, Employee emp) { String sql = "call generate_paycheck(?, ?)"; CompletableFuture<CheckDetail> details = conn.<CheckDetail>outOperation(sql) .set("1", emp, JdbcType.STRUCT) .outParameter("2", JdbcType.STRUCT) .resultProcessor(m -> m.get("2", CheckDetail.class)) .submit() .toCompletableFuture(); conn.localOperation() .onExecution(() -> { printPaycheck(details); return null; }) .submit() .toCompletableFuture() .thenRun(() -> reportPrintSuccess(details)) .exceptionally(t -> { reportPrintFailure(details); return null; }); }
  • 41. Copyright Ā© 2017, Oracle and/or its affiliates. All rights reserved. | public void deposit(Connection conn, int accountId, double amount) { String selectSql = "select balance from account where id = $1"; CompletableFuture<Double> newBalanceF = conn.<Double>rowOperation(selectSql) .set("1", accountId, JdbcType.INTEGER) .rowAggregator((p, row) -> row.get("balance", Double.class)) .submit() .toCompletableFuture() .thenApply(b -> b + amount); String updateSql = "update account set balance=$2 where id = $1"; conn.countOperation(updateSql) .set("1", accountId, JdbcType.INTEGER) .set("2", newBalanceF, JdbcType.DOUBLE) .submit(); } public static class Item { protected int id; protected String name; protected int answer; @SqlColumns({"ID", "USER", "RESPONSE"}) public Item(int id, String name, int answer) { this.id = id; this.name = name; this.answer = answer; } @SqlParameter(marker = "id", sqlType = "NUMERIC") public int getId() { return id; } @SqlParameter(marker = "name", sqlType = "VARCHAR") public String getName() { return name; } @SqlParameter(marker = "answer", sqlType = "NUMERIC") public int getAnswer() { return answer; } } public static class NlsLanguageProperty implements ConnectionProperty { public static final ConnectionProperty NLS_LANGUAGE = new NlsLanguageProperty(); private NlsLanguageProperty() { } @Override public String name() { return "NLS_LANGUAGE"; } @Override public Class range() { return String.class; } @Override public String defaultValue() { return "American"; } @Override public boolean isSensitive() { return false; } @Override public Operation configureOperation(OperationGroup group, Object value) { String sql = "ALTER SESSION SET NLS_LANGUAGE TO " + value; return group.operation(sql); } } @SqlArray(elementSqlTypeName = "STUDENT") public static class Roster extends LinkedList<Student> { public Roster() { } } @SqlStruct(sqlTypeName = "STUDENT", fields = { @Field(sqlFieldName = "NAME", sqlTypeName = "VARCHAR(100)", javaFieldName = "name"), @Field(sqlFieldName = "EMAIL", sqlTypeName = "VARCHAR(100)", javaFieldName = "email")}) public class Student { String name; String email; public void setName(String n) { name = n; } public void setEmail(String e) { email = e; } public String getName() { return name; } public String getEmail() { return email; } } public class Employee { } public class CheckDetail { } private void printPaycheck(Future<CheckDetail> checkF) { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } private Consumer<? super Object> reportPrintSuccess(Future<CheckDetail> checkF) { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } private CompletableFuture<Void> reportPrintFailure(Future<CheckDetail> checkF) { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } }