Skip to content

Commit 9f2b4a0

Browse files
authoredMar 17, 2025
Code sample - 23c JDBC Reactive Extensions (#317)
* Code sample - 23c JDBC Reactive Extensions * code sample adjustments * code sample adjustments * code sample adjustments * changed to make the explanation release-agnostic * updated to driver 23.6.0.24.10 as requested * updated to driver 23.7.0.25.01, added Statements for DDL, added OraclePreparedStatement for DML, added new queries including select (streaming) example method, added sql file, added DB connection config.properties file
1 parent 2146193 commit 9f2b4a0

File tree

5 files changed

+412
-0
lines changed

5 files changed

+412
-0
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<project xmlns="http://maven.apache.org/POM/4.0.0"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
6+
<modelVersion>4.0.0</modelVersion>
7+
8+
<groupId>com.oracle.jdbc.reactive</groupId>
9+
<artifactId>jdbc-reactive-extensions-intro</artifactId>
10+
<version>1.0-SNAPSHOT</version>
11+
<name>jdbc-reactive-extensions-intro</name>
12+
13+
<properties>
14+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
15+
<maven.compiler.source>21</maven.compiler.source>
16+
<maven.compiler.target>21</maven.compiler.target>
17+
</properties>
18+
19+
<dependencies>
20+
<dependency>
21+
<groupId>com.oracle.database.jdbc</groupId>
22+
<artifactId>ojdbc17-production</artifactId>
23+
<version>23.7.0.25.01</version>
24+
<type>pom</type>
25+
</dependency>
26+
</dependencies>
27+
28+
<build>
29+
<pluginManagement><!-- lock down plugins versions to avoid using Maven
30+
defaults (may be moved to parent pom) -->
31+
<plugins>
32+
<plugin>
33+
<artifactId>maven-clean-plugin</artifactId>
34+
<version>3.1.0</version>
35+
</plugin>
36+
<plugin>
37+
<artifactId>maven-site-plugin</artifactId>
38+
<version>3.7.1</version>
39+
</plugin>
40+
<plugin>
41+
<artifactId>maven-project-info-reports-plugin</artifactId>
42+
<version>3.0.0</version>
43+
</plugin>
44+
<!-- see
45+
http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
46+
<plugin>
47+
<artifactId>maven-resources-plugin</artifactId>
48+
<version>3.0.2</version>
49+
</plugin>
50+
<plugin>
51+
<artifactId>maven-compiler-plugin</artifactId>
52+
<version>3.8.0</version>
53+
</plugin>
54+
<plugin>
55+
<artifactId>maven-surefire-plugin</artifactId>
56+
<version>2.22.1</version>
57+
</plugin>
58+
<plugin>
59+
<artifactId>maven-jar-plugin</artifactId>
60+
<version>3.0.2</version>
61+
</plugin>
62+
<plugin>
63+
<artifactId>maven-install-plugin</artifactId>
64+
<version>2.5.2</version>
65+
</plugin>
66+
<plugin>
67+
<artifactId>maven-deploy-plugin</artifactId>
68+
<version>2.8.2</version>
69+
</plugin>
70+
</plugins>
71+
</pluginManagement>
72+
</build>
73+
74+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
/*
2+
Copyright (c) 2024, Oracle and/or its affiliates.
3+
4+
This software is dual-licensed to you under the Universal Permissive License
5+
(UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl or Apache License
6+
2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
7+
either license.
8+
9+
Licensed under the Apache License, Version 2.0 (the "License");
10+
you may not use this file except in compliance with the License.
11+
You may obtain a copy of the License at
12+
13+
https://www.apache.org/licenses/LICENSE-2.0
14+
15+
Unless required by applicable law or agreed to in writing, software
16+
distributed under the License is distributed on an "AS IS" BASIS,
17+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18+
See the License for the specific language governing permissions and
19+
limitations under the License.
20+
*/
21+
22+
package com.oracle.jdbc.reactive;
23+
24+
import oracle.jdbc.OracleConnection;
25+
import oracle.jdbc.pool.OracleDataSource;
26+
27+
import java.io.IOException;
28+
import java.nio.file.Files;
29+
import java.nio.file.Path;
30+
import java.sql.SQLException;
31+
import java.util.Properties;
32+
33+
public class DatabaseConfig {
34+
35+
private static final ConfigData CONFIG_DATA = loadConfig();
36+
37+
private static ConfigData loadConfig() {
38+
Properties properties = new Properties();
39+
try {
40+
var fileStream = Files.newInputStream(Path.of("src/main/resources/config.properties"));
41+
properties.load(fileStream);
42+
return new ConfigData(properties.getProperty("DRIVER"), properties.getProperty("USER"),
43+
properties.getProperty("PASSWORD"), properties.getProperty("HOST"),
44+
Integer.parseInt(properties.getProperty("PORT")), properties.getProperty("DATABASE"),
45+
properties.getProperty("DB_TABLE_NAME"));
46+
} catch (IOException e) {
47+
e.printStackTrace();
48+
return null;
49+
}
50+
}
51+
52+
public static OracleDataSource getDataSource() throws SQLException {
53+
if (CONFIG_DATA == null) {
54+
throw new IllegalStateException("Configuration data is not available, check file path.");
55+
}
56+
OracleDataSource dataSource = new OracleDataSource();
57+
dataSource
58+
.setURL("jdbc:oracle:thin:@" + CONFIG_DATA.host() + ":" + CONFIG_DATA.port() + "/" + CONFIG_DATA.database());
59+
dataSource.setUser(CONFIG_DATA.user());
60+
dataSource.setPassword(CONFIG_DATA.password());
61+
return dataSource;
62+
}
63+
64+
public static OracleConnection getConnection() throws SQLException {
65+
return (OracleConnection) getDataSource().getConnection();
66+
}
67+
68+
public static String getDbTableName() {
69+
if (CONFIG_DATA == null) {
70+
throw new IllegalStateException("Configuration could not be loaded.");
71+
}
72+
return CONFIG_DATA.dbTableName();
73+
}
74+
75+
public static String getDriver() {
76+
if (CONFIG_DATA == null) {
77+
throw new IllegalStateException("Configuration could not be loaded.");
78+
}
79+
return CONFIG_DATA.driver();
80+
}
81+
82+
public static String getUser() {
83+
if (CONFIG_DATA == null) {
84+
throw new IllegalStateException("Configuration could not be loaded.");
85+
}
86+
return CONFIG_DATA.user();
87+
}
88+
89+
public static String getPassword() {
90+
if (CONFIG_DATA == null) {
91+
throw new IllegalStateException("Configuration could not be loaded.");
92+
}
93+
return CONFIG_DATA.password();
94+
}
95+
96+
public static String getHost() {
97+
if (CONFIG_DATA == null) {
98+
throw new IllegalStateException("Configuration could not be loaded.");
99+
}
100+
return CONFIG_DATA.host();
101+
}
102+
103+
public static int getPort() {
104+
if (CONFIG_DATA == null) {
105+
throw new IllegalStateException("Configuration could not be loaded.");
106+
}
107+
return CONFIG_DATA.port();
108+
}
109+
110+
public static String getDatabase() {
111+
if (CONFIG_DATA == null) {
112+
throw new IllegalStateException("Configuration could not be loaded.");
113+
}
114+
return CONFIG_DATA.database();
115+
}
116+
117+
private record ConfigData(String driver, String user, String password, String host, int port, String database,
118+
String dbTableName) {
119+
}
120+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
/*
2+
Copyright (c) 2024, Oracle and/or its affiliates.
3+
4+
This software is dual-licensed to you under the Universal Permissive License
5+
(UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl or Apache License
6+
2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
7+
either license.
8+
9+
Licensed under the Apache License, Version 2.0 (the "License");
10+
you may not use this file except in compliance with the License.
11+
You may obtain a copy of the License at
12+
13+
https://www.apache.org/licenses/LICENSE-2.0
14+
15+
Unless required by applicable law or agreed to in writing, software
16+
distributed under the License is distributed on an "AS IS" BASIS,
17+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18+
See the License for the specific language governing permissions and
19+
limitations under the License.
20+
*/
21+
22+
package com.oracle.jdbc.reactive;
23+
24+
import java.sql.SQLException;
25+
import java.util.concurrent.Flow;
26+
import java.util.concurrent.SubmissionPublisher;
27+
import java.util.stream.IntStream;
28+
29+
import oracle.jdbc.OracleConnection;
30+
import oracle.jdbc.OraclePreparedStatement;
31+
import oracle.jdbc.OracleResultSet;
32+
import oracle.jdbc.OracleStatement;
33+
34+
public class SQLStatementWithAsynchronousJDBC {
35+
36+
public static void main(String[] args) throws InterruptedException {
37+
SQLStatementWithAsynchronousJDBC asyncSQL = new SQLStatementWithAsynchronousJDBC();
38+
try (OracleConnection conn = DatabaseConfig.getConnection()) {
39+
asyncSQL.createTable(conn);
40+
IntStream.rangeClosed(0, 3).forEach(i -> asyncSQL.insertData(conn, i, "Java " + i, "Duke " + i));
41+
asyncSQL.readData(conn);
42+
Thread.sleep(5000);
43+
asyncSQL.dropTable(conn);
44+
} catch (SQLException e) {
45+
e.printStackTrace();
46+
}
47+
}
48+
49+
private Flow.Publisher<Boolean> insertData(OracleConnection connection, int id, String firstName, String lastName) {
50+
try {
51+
final OraclePreparedStatement insertStatement = (OraclePreparedStatement) connection
52+
.prepareStatement("INSERT INTO employee_names (id, first_name, last_name) VALUES (?, ?, ?)");
53+
insertStatement.setInt(1, id);
54+
insertStatement.setString(2, firstName);
55+
insertStatement.setString(3, lastName);
56+
57+
Flow.Publisher<Boolean> insertPublisher = insertStatement.unwrap(OraclePreparedStatement.class)
58+
.executeAsyncOracle();
59+
60+
insertPublisher.subscribe(new Flow.Subscriber<Boolean>() {
61+
private Flow.Subscription subscription;
62+
63+
public void onSubscribe(Flow.Subscription subscription) {
64+
this.subscription = subscription;
65+
subscription.request(1L);
66+
}
67+
68+
public void onNext(Boolean item) {
69+
}
70+
71+
public void onError(Throwable throwable) {
72+
closeStatement();
73+
throwable.printStackTrace();
74+
}
75+
76+
public void onComplete() {
77+
closeStatement();
78+
}
79+
80+
void closeStatement() {
81+
try {
82+
if (insertStatement != null && !insertStatement.isClosed()) {
83+
insertStatement.close();
84+
}
85+
} catch (SQLException closeException) {
86+
closeException.printStackTrace();
87+
}
88+
}
89+
});
90+
91+
return insertPublisher;
92+
} catch (SQLException e) {
93+
e.printStackTrace();
94+
SubmissionPublisher<Boolean> publisher = new SubmissionPublisher<>();
95+
publisher.close();
96+
return publisher;
97+
}
98+
}
99+
100+
public Flow.Publisher<OracleResultSet> readData(OracleConnection connection) {
101+
try {
102+
final OraclePreparedStatement readStatement = (OraclePreparedStatement) connection
103+
.prepareStatement("SELECT * FROM employee_names WHERE first_name LIKE ?");
104+
readStatement.setString(1, "Jav%");
105+
106+
Flow.Publisher<OracleResultSet> readPublisher = readStatement.unwrap(OraclePreparedStatement.class)
107+
.executeQueryAsyncOracle();
108+
109+
readPublisher.subscribe(new Flow.Subscriber<OracleResultSet>() {
110+
private Flow.Subscription subscription;
111+
112+
public void onSubscribe(Flow.Subscription subscription) {
113+
this.subscription = subscription;
114+
subscription.request(Long.MAX_VALUE);
115+
}
116+
117+
public void onNext(OracleResultSet resultSet) {
118+
try {
119+
while (resultSet.next()) {
120+
int id = resultSet.getInt("id");
121+
String firstName = resultSet.getString("first_name");
122+
String lastName = resultSet.getString("last_name");
123+
System.out.println("ID: " + id + ", First Name: " + firstName + ", Last Name: " + lastName);
124+
}
125+
System.out.println("Finished receiving stream data successfully. \nPreparing to drop table...");
126+
} catch (SQLException e) {
127+
onError(e);
128+
}
129+
}
130+
131+
public void onError(Throwable throwable) {
132+
closeStatement();
133+
throwable.printStackTrace();
134+
}
135+
136+
public void onComplete() {
137+
closeStatement();
138+
}
139+
140+
void closeStatement() {
141+
try {
142+
if (readStatement != null && !readStatement.isClosed()) {
143+
readStatement.close();
144+
}
145+
} catch (SQLException closeException) {
146+
closeException.printStackTrace();
147+
}
148+
}
149+
});
150+
return readPublisher;
151+
} catch (SQLException e) {
152+
e.printStackTrace();
153+
SubmissionPublisher<OracleResultSet> publisher = new SubmissionPublisher<>();
154+
publisher.close();
155+
return publisher;
156+
}
157+
}
158+
159+
private void createTable(OracleConnection connection) {
160+
String createTableSQL = "CREATE TABLE employee_names (id NUMBER PRIMARY KEY, first_name VARCHAR2(50), last_name VARCHAR2(50))";
161+
try (OracleStatement createTableStatement = (OracleStatement) connection.createStatement()) {
162+
createTableStatement.execute(createTableSQL);
163+
System.out.println("Table 'employee_names' created successfully.");
164+
} catch (SQLException e) {
165+
e.printStackTrace();
166+
}
167+
}
168+
169+
private void dropTable(OracleConnection connection) {
170+
String dropTableSQL = "DROP TABLE employee_names";
171+
try (OracleStatement dropTableStatement = (OracleStatement) connection.createStatement()) {
172+
dropTableStatement.execute(dropTableSQL);
173+
System.out.println("Table 'employee_names' dropped successfully.");
174+
} catch (SQLException e) {
175+
e.printStackTrace();
176+
}
177+
}
178+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
HOST=<YOUR_DB_HOST_NAME>
2+
PORT=<YOUR_DB_PORT>
3+
DATABASE=<YOUR_DB_NAME>
4+
USER=<YOUR_DB_USER
5+
PASSWORD=<YOUR_DB_PASSWORD>
6+
SCHEMA=<YOUR_DB_SCHEMA>
7+
DB_TABLE_NAME=employee_names

0 commit comments

Comments
 (0)
Failed to load comments.