From 8e262912ef44c8f21c4ec204abf9a5af0a96363a Mon Sep 17 00:00:00 2001 From: juarezjuniorgithub Date: Fri, 10 May 2024 18:41:06 +0100 Subject: [PATCH 1/4] Code sample - 23ai Vector Search with JDBC --- java/23ai-jdbc-vector-search/README.md | 1 + java/23ai-jdbc-vector-search/pom.xml | 82 +++++++++ .../sql/23ai-jdbc-vector-search.sql | 10 + .../jdbc/OracleAIVectorSearchWithJava.java | 173 ++++++++++++++++++ 4 files changed, 266 insertions(+) create mode 100644 java/23ai-jdbc-vector-search/README.md create mode 100644 java/23ai-jdbc-vector-search/pom.xml create mode 100644 java/23ai-jdbc-vector-search/sql/23ai-jdbc-vector-search.sql create mode 100644 java/23ai-jdbc-vector-search/src/main/java/com/oracle/dev/jdbc/OracleAIVectorSearchWithJava.java diff --git a/java/23ai-jdbc-vector-search/README.md b/java/23ai-jdbc-vector-search/README.md new file mode 100644 index 00000000..c12c9d59 --- /dev/null +++ b/java/23ai-jdbc-vector-search/README.md @@ -0,0 +1 @@ +[Oracle AI Vector Search for Java Developers with the Oracle Database 23ai](https://juarezjunior.medium.com/oracle-ai-vector-search-for-java-developers-with-the-oracle-database-23ai-e29321d23fa0) \ No newline at end of file diff --git a/java/23ai-jdbc-vector-search/pom.xml b/java/23ai-jdbc-vector-search/pom.xml new file mode 100644 index 00000000..3ed3f917 --- /dev/null +++ b/java/23ai-jdbc-vector-search/pom.xml @@ -0,0 +1,82 @@ + + + + 4.0.0 + + com.oracle.dev.jdbc + 23ai-jdbc-vector-search + 1.0-SNAPSHOT + + 23ai-jdbc-vector-search + Oracle AI Vector Search for Java Developers with the Oracle + Database 23ai + + https://juarezjunior.medium.com/oracle-ai-vector-search-for-java-developers-with-the-oracle-database-23ai-e29321d23fa0 + + + UTF-8 + 21 + 21 + + + + + com.oracle.database.jdbc + ojdbc11 + 23.4.0.24.05 + + + com.oracle.database.jdbc + ucp + 23.4.0.24.05 + + + + + + + maven-clean-plugin + 3.1.0 + + + maven-site-plugin + 3.7.1 + + + maven-project-info-reports-plugin + 3.0.0 + + + + maven-resources-plugin + 3.0.2 + + + maven-compiler-plugin + 3.8.0 + + + maven-surefire-plugin + 2.22.1 + + + maven-jar-plugin + 3.0.2 + + + maven-install-plugin + 2.5.2 + + + maven-deploy-plugin + 2.8.2 + + + + + + diff --git a/java/23ai-jdbc-vector-search/sql/23ai-jdbc-vector-search.sql b/java/23ai-jdbc-vector-search/sql/23ai-jdbc-vector-search.sql new file mode 100644 index 00000000..fa50b4a8 --- /dev/null +++ b/java/23ai-jdbc-vector-search/sql/23ai-jdbc-vector-search.sql @@ -0,0 +1,10 @@ +CREATE USER VECTOR_USER IDENTIFIED BY QUOTA UNLIMITED ON USERS; +GRANT DB_DEVELOPER_ROLE TO VECTOR_USER; +GRANT CREATE SESSION TO VECTOR_USER; +GRANT SELECT ANY TABLE ON SCHEMA VECTOR_USER TO VECTOR_USER; +GRANT SELECT ANY TABLE ON SCHEMA VECTOR_USER TO VECTOR_USER; +GRANT SELECT ANY TABLE ON SCHEMA VECTOR_USER TO VECTOR_USER; +GRANT SELECT ANY TABLE ON SCHEMA VECTOR_USER TO VECTOR_USER; +ALTER SESSION SET CURRENT_SCHEMA = VECTOR_USER; +CREATE TABLE VECTOR_USER.ORACLE_AI_VECTOR_SEARCH_DEMO (ID NUMBER PRIMARY KEY, VECTOR_DATA VECTOR(3, FLOAT64)); +COMMIT; \ No newline at end of file diff --git a/java/23ai-jdbc-vector-search/src/main/java/com/oracle/dev/jdbc/OracleAIVectorSearchWithJava.java b/java/23ai-jdbc-vector-search/src/main/java/com/oracle/dev/jdbc/OracleAIVectorSearchWithJava.java new file mode 100644 index 00000000..f845864c --- /dev/null +++ b/java/23ai-jdbc-vector-search/src/main/java/com/oracle/dev/jdbc/OracleAIVectorSearchWithJava.java @@ -0,0 +1,173 @@ +/* + Copyright (c) 2024, Oracle and/or its affiliates. + This software is dual-licensed to you under the Universal Permissive License + (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl or Apache License + 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose + either license. + Licensed 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 + https://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. +*/ + +package com.oracle.dev.jdbc; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.Properties; +import java.util.concurrent.ThreadLocalRandom; + +import oracle.jdbc.OracleType; +import oracle.ucp.jdbc.PoolDataSource; +import oracle.ucp.jdbc.PoolDataSourceFactory; + +public class OracleAIVectorSearchWithJava { + + private final static String URL = ""; + private final static String USERNAME = ""; + private final static String PASSWORD = ""; + + private String insertSql = "INSERT INTO ORACLE_AI_VECTOR_SEARCH_DEMO (ID, VECTOR_DATA) VALUES (?, ?)"; + private String querySql = "SELECT ID, VECTOR_DATA FROM ORACLE_AI_VECTOR_SEARCH_DEMO"; + private String querySqlWithBind = "SELECT ID, VECTOR_DATA FROM ORACLE_AI_VECTOR_SEARCH_DEMO ORDER BY VECTOR_DISTANCE(VECTOR_DATA, ?, DOT)"; + + public static void main(String[] args) throws SQLException { + OracleAIVectorSearchWithJava oracleAIVectorSearch = new OracleAIVectorSearchWithJava(); + oracleAIVectorSearch.execute(); + } + + private void execute() throws SQLException { + + System.out.println("Starting JDBC connection with PooledDataSource..."); + try (Connection conn = getConnectionFromPooledDataSource()) { + System.out.println("Connected to Oracle Database 23ai! " + "\n"); + + System.out.println("Inserting VECTOR with oracle.jdbc.OracleType.VECTOR..."); + insertVector(conn); + System.out.println("VECTOR with oracle.jdbc.OracleType.VECTOR inserted!" + "\n"); + + System.out.println("Inserting VECTOR with oracle.jdbc.OracleType.VARCHAR2..."); + insertVectorWithVarChar2(conn); + System.out.println("VECTOR with oracle.jdbc.OracleType.VARCHAR2 inserted!" + "\n"); + + System.out.println("Inserting VECTOR with Batch API..."); + insertVectorWithBatchAPI(conn); + System.out.println("VECTOR with Batch API inserted!" + "\n"); + + System.out.println("Retrieving VECTOR as double array..."); + retrieveVectorAsArray(conn); + System.out.println("VECTOR retrieved!" + "\n"); + + System.out.println("Retrieving VECTOR as String..."); + retrieveVectorAsString(conn); + System.out.println("VECTOR retrieved!" + "\n"); + + System.out.println("Retrieving VECTOR with bound VECTOR (L2 - Euclidean distance)..."); + retrieveVectorWithBoundVector(conn); + System.out.println("VECTOR retrieved!"); + + } + } + + private void insertVector(Connection connection) throws SQLException { + PreparedStatement insertStatement = connection.prepareStatement(insertSql); + double[] vector = { 1.1, 2.2, 3.3 }; + System.out.println("SQL DML: " + insertSql); + System.out.println("VECTOR to be inserted: " + Arrays.toString(vector)); + insertStatement.setInt(1, randomize()); + insertStatement.setObject(2, vector, OracleType.VECTOR); + insertStatement.executeUpdate(); + } + + private void insertVectorWithVarChar2(Connection connection) throws SQLException { + PreparedStatement insertStatement = connection.prepareStatement(insertSql); + double[] vector = { 1.1, 2.2, 3.3 }; + System.out.println("SQL DML: " + insertSql); + System.out.println("VECTOR to be inserted: " + Arrays.toString(vector)); + insertStatement.setInt(1, randomize()); + insertStatement.setObject(2, Arrays.toString(vector), OracleType.VARCHAR2); + insertStatement.executeUpdate(); + } + + private void insertVectorWithBatchAPI(Connection connection) throws SQLException { + double[][] vectors = { { 1.1, 2.2, 3.3 }, { 1.3, 7.2, 4.3 }, { 5.9, 5.2, 7.3 } }; + System.out.println("SQL DML: " + insertSql); + System.out.println("VECTORs to be inserted as a batch: " + Arrays.toString(vectors[0]) + ", " + + Arrays.toString(vectors[1]) + ", " + Arrays.toString(vectors[2])); + try (PreparedStatement insertStatement = connection.prepareStatement(insertSql)) { + for (double[] vector : vectors) { + insertStatement.setInt(1, randomize()); + insertStatement.setObject(2, vector, OracleType.VECTOR); + insertStatement.addBatch(); + } + insertStatement.executeBatch(); + } + } + + private void retrieveVectorAsArray(Connection connection) throws SQLException { + PreparedStatement queryStatement = connection.prepareStatement(querySql); + System.out.println("SQL DML: " + querySql); + ResultSet resultSet = queryStatement.executeQuery(); + double[] vector = null; + while (resultSet.next()) { + vector = resultSet.getObject(2, double[].class); + } + System.out.println("Retrieved VECTOR: " + Arrays.toString(vector)); + } + + private void retrieveVectorAsString(Connection connection) throws SQLException { + PreparedStatement queryStatement = connection.prepareStatement(querySql); + System.out.println("SQL DML: " + querySql); + ResultSet resultSet = queryStatement.executeQuery(); + String vector = null; + while (resultSet.next()) { + vector = (String) resultSet.getObject(2); + } + System.out.println("Retrieved VECTOR: " + vector); + } + + private void retrieveVectorWithBoundVector(Connection connection) throws SQLException { + // Bind a Vector to a select + PreparedStatement queryStatement = connection.prepareStatement(querySqlWithBind); + double[] inputVector = { 1.0, 2.2, 3.3 }; + System.out.println("SQL DML: " + querySqlWithBind); + System.out.println("Bound VECTOR: " + Arrays.toString(inputVector)); + queryStatement.setObject(1, inputVector, OracleType.VECTOR); + ResultSet resultSet = queryStatement.executeQuery(); + resultSet.next(); + double[] outputVector = resultSet.getObject(2, double[].class); + System.out.println("Retrieved VECTOR: " + Arrays.toString(outputVector)); + } + + private Connection getConnectionFromPooledDataSource() throws SQLException { + // Create pool-enabled data source instance + PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource(); + // set connection properties on the data source + pds.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource"); + pds.setURL(URL); + pds.setUser(USERNAME); + pds.setPassword(PASSWORD); + // Configure pool properties with a Properties instance + Properties prop = new Properties(); + prop.setProperty("oracle.jdbc.vectorDefaultGetObjectType", "String"); + pds.setConnectionProperties(prop); + // Override any pool properties directly + pds.setInitialPoolSize(10); + // Get a database connection from the pool-enabled data source + Connection conn = pds.getConnection(); + return conn; + } + + private int randomize() { + return ThreadLocalRandom.current().nextInt(); + } + +} From ce82ff2925fd5fe42bb7fb09f28b6cf495b5650e Mon Sep 17 00:00:00 2001 From: juarezjuniorgithub Date: Tue, 2 Jul 2024 00:40:11 +0100 Subject: [PATCH 2/4] indentation adjustments --- java/23ai-jdbc-vector-search/pom.xml | 144 ++++----- .../jdbc/OracleAIVectorSearchWithJava.java | 289 +++++++++--------- 2 files changed, 223 insertions(+), 210 deletions(-) diff --git a/java/23ai-jdbc-vector-search/pom.xml b/java/23ai-jdbc-vector-search/pom.xml index 3ed3f917..a6dfb830 100644 --- a/java/23ai-jdbc-vector-search/pom.xml +++ b/java/23ai-jdbc-vector-search/pom.xml @@ -1,82 +1,82 @@ - 4.0.0 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 - com.oracle.dev.jdbc - 23ai-jdbc-vector-search - 1.0-SNAPSHOT + com.oracle.dev.jdbc + 23ai-jdbc-vector-search + 1.0-SNAPSHOT - 23ai-jdbc-vector-search - Oracle AI Vector Search for Java Developers with the Oracle - Database 23ai - - https://juarezjunior.medium.com/oracle-ai-vector-search-for-java-developers-with-the-oracle-database-23ai-e29321d23fa0 + 23ai-jdbc-vector-search + Oracle AI Vector Search for Java Developers with the Oracle + Database 23ai + + https://juarezjunior.medium.com/oracle-ai-vector-search-for-java-developers-with-the-oracle-database-23ai-e29321d23fa0 - - UTF-8 - 21 - 21 - + + UTF-8 + 21 + 21 + - - - com.oracle.database.jdbc - ojdbc11 - 23.4.0.24.05 - - - com.oracle.database.jdbc - ucp - 23.4.0.24.05 - - - - - - - maven-clean-plugin - 3.1.0 - - - maven-site-plugin - 3.7.1 - - - maven-project-info-reports-plugin - 3.0.0 - - - - maven-resources-plugin - 3.0.2 - - - maven-compiler-plugin - 3.8.0 - - - maven-surefire-plugin - 2.22.1 - - - maven-jar-plugin - 3.0.2 - - - maven-install-plugin - 2.5.2 - - - maven-deploy-plugin - 2.8.2 - - - - + + + maven-clean-plugin + 3.1.0 + + + maven-site-plugin + 3.7.1 + + + maven-project-info-reports-plugin + 3.0.0 + + + + maven-resources-plugin + 3.0.2 + + + maven-compiler-plugin + 3.8.0 + + + maven-surefire-plugin + 2.22.1 + + + maven-jar-plugin + 3.0.2 + + + maven-install-plugin + 2.5.2 + + + maven-deploy-plugin + 2.8.2 + + + + diff --git a/java/23ai-jdbc-vector-search/src/main/java/com/oracle/dev/jdbc/OracleAIVectorSearchWithJava.java b/java/23ai-jdbc-vector-search/src/main/java/com/oracle/dev/jdbc/OracleAIVectorSearchWithJava.java index f845864c..38872258 100644 --- a/java/23ai-jdbc-vector-search/src/main/java/com/oracle/dev/jdbc/OracleAIVectorSearchWithJava.java +++ b/java/23ai-jdbc-vector-search/src/main/java/com/oracle/dev/jdbc/OracleAIVectorSearchWithJava.java @@ -31,143 +31,156 @@ public class OracleAIVectorSearchWithJava { - private final static String URL = ""; - private final static String USERNAME = ""; - private final static String PASSWORD = ""; - - private String insertSql = "INSERT INTO ORACLE_AI_VECTOR_SEARCH_DEMO (ID, VECTOR_DATA) VALUES (?, ?)"; - private String querySql = "SELECT ID, VECTOR_DATA FROM ORACLE_AI_VECTOR_SEARCH_DEMO"; - private String querySqlWithBind = "SELECT ID, VECTOR_DATA FROM ORACLE_AI_VECTOR_SEARCH_DEMO ORDER BY VECTOR_DISTANCE(VECTOR_DATA, ?, DOT)"; - - public static void main(String[] args) throws SQLException { - OracleAIVectorSearchWithJava oracleAIVectorSearch = new OracleAIVectorSearchWithJava(); - oracleAIVectorSearch.execute(); - } - - private void execute() throws SQLException { - - System.out.println("Starting JDBC connection with PooledDataSource..."); - try (Connection conn = getConnectionFromPooledDataSource()) { - System.out.println("Connected to Oracle Database 23ai! " + "\n"); - - System.out.println("Inserting VECTOR with oracle.jdbc.OracleType.VECTOR..."); - insertVector(conn); - System.out.println("VECTOR with oracle.jdbc.OracleType.VECTOR inserted!" + "\n"); - - System.out.println("Inserting VECTOR with oracle.jdbc.OracleType.VARCHAR2..."); - insertVectorWithVarChar2(conn); - System.out.println("VECTOR with oracle.jdbc.OracleType.VARCHAR2 inserted!" + "\n"); - - System.out.println("Inserting VECTOR with Batch API..."); - insertVectorWithBatchAPI(conn); - System.out.println("VECTOR with Batch API inserted!" + "\n"); - - System.out.println("Retrieving VECTOR as double array..."); - retrieveVectorAsArray(conn); - System.out.println("VECTOR retrieved!" + "\n"); - - System.out.println("Retrieving VECTOR as String..."); - retrieveVectorAsString(conn); - System.out.println("VECTOR retrieved!" + "\n"); - - System.out.println("Retrieving VECTOR with bound VECTOR (L2 - Euclidean distance)..."); - retrieveVectorWithBoundVector(conn); - System.out.println("VECTOR retrieved!"); - - } - } - - private void insertVector(Connection connection) throws SQLException { - PreparedStatement insertStatement = connection.prepareStatement(insertSql); - double[] vector = { 1.1, 2.2, 3.3 }; - System.out.println("SQL DML: " + insertSql); - System.out.println("VECTOR to be inserted: " + Arrays.toString(vector)); - insertStatement.setInt(1, randomize()); - insertStatement.setObject(2, vector, OracleType.VECTOR); - insertStatement.executeUpdate(); - } - - private void insertVectorWithVarChar2(Connection connection) throws SQLException { - PreparedStatement insertStatement = connection.prepareStatement(insertSql); - double[] vector = { 1.1, 2.2, 3.3 }; - System.out.println("SQL DML: " + insertSql); - System.out.println("VECTOR to be inserted: " + Arrays.toString(vector)); - insertStatement.setInt(1, randomize()); - insertStatement.setObject(2, Arrays.toString(vector), OracleType.VARCHAR2); - insertStatement.executeUpdate(); - } - - private void insertVectorWithBatchAPI(Connection connection) throws SQLException { - double[][] vectors = { { 1.1, 2.2, 3.3 }, { 1.3, 7.2, 4.3 }, { 5.9, 5.2, 7.3 } }; - System.out.println("SQL DML: " + insertSql); - System.out.println("VECTORs to be inserted as a batch: " + Arrays.toString(vectors[0]) + ", " - + Arrays.toString(vectors[1]) + ", " + Arrays.toString(vectors[2])); - try (PreparedStatement insertStatement = connection.prepareStatement(insertSql)) { - for (double[] vector : vectors) { - insertStatement.setInt(1, randomize()); - insertStatement.setObject(2, vector, OracleType.VECTOR); - insertStatement.addBatch(); - } - insertStatement.executeBatch(); - } - } - - private void retrieveVectorAsArray(Connection connection) throws SQLException { - PreparedStatement queryStatement = connection.prepareStatement(querySql); - System.out.println("SQL DML: " + querySql); - ResultSet resultSet = queryStatement.executeQuery(); - double[] vector = null; - while (resultSet.next()) { - vector = resultSet.getObject(2, double[].class); - } - System.out.println("Retrieved VECTOR: " + Arrays.toString(vector)); - } - - private void retrieveVectorAsString(Connection connection) throws SQLException { - PreparedStatement queryStatement = connection.prepareStatement(querySql); - System.out.println("SQL DML: " + querySql); - ResultSet resultSet = queryStatement.executeQuery(); - String vector = null; - while (resultSet.next()) { - vector = (String) resultSet.getObject(2); - } - System.out.println("Retrieved VECTOR: " + vector); - } - - private void retrieveVectorWithBoundVector(Connection connection) throws SQLException { - // Bind a Vector to a select - PreparedStatement queryStatement = connection.prepareStatement(querySqlWithBind); - double[] inputVector = { 1.0, 2.2, 3.3 }; - System.out.println("SQL DML: " + querySqlWithBind); - System.out.println("Bound VECTOR: " + Arrays.toString(inputVector)); - queryStatement.setObject(1, inputVector, OracleType.VECTOR); - ResultSet resultSet = queryStatement.executeQuery(); - resultSet.next(); - double[] outputVector = resultSet.getObject(2, double[].class); - System.out.println("Retrieved VECTOR: " + Arrays.toString(outputVector)); - } - - private Connection getConnectionFromPooledDataSource() throws SQLException { - // Create pool-enabled data source instance - PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource(); - // set connection properties on the data source - pds.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource"); - pds.setURL(URL); - pds.setUser(USERNAME); - pds.setPassword(PASSWORD); - // Configure pool properties with a Properties instance - Properties prop = new Properties(); - prop.setProperty("oracle.jdbc.vectorDefaultGetObjectType", "String"); - pds.setConnectionProperties(prop); - // Override any pool properties directly - pds.setInitialPoolSize(10); - // Get a database connection from the pool-enabled data source - Connection conn = pds.getConnection(); - return conn; - } - - private int randomize() { - return ThreadLocalRandom.current().nextInt(); - } + private final static String URL = ""; + private final static String USERNAME = ""; + private final static String PASSWORD = ""; + + private String insertSql = "INSERT INTO ORACLE_AI_VECTOR_SEARCH_DEMO (ID, VECTOR_DATA) VALUES (?, ?)"; + private String querySql = "SELECT ID, VECTOR_DATA FROM ORACLE_AI_VECTOR_SEARCH_DEMO"; + private String querySqlWithBind = "SELECT ID, VECTOR_DATA FROM ORACLE_AI_VECTOR_SEARCH_DEMO ORDER BY VECTOR_DISTANCE(VECTOR_DATA, ?, DOT)"; + + public static void main(String[] args) throws SQLException { + OracleAIVectorSearchWithJava oracleAIVectorSearch = new OracleAIVectorSearchWithJava(); + oracleAIVectorSearch.execute(); + } + + private void execute() throws SQLException { + + System.out.println("Starting JDBC connection with PooledDataSource..."); + try (Connection conn = getConnectionFromPooledDataSource()) { + System.out.println("Connected to Oracle Database 23ai! " + "\n"); + + System.out + .println("Inserting VECTOR with oracle.jdbc.OracleType.VECTOR..."); + insertVector(conn); + System.out.println( + "VECTOR with oracle.jdbc.OracleType.VECTOR inserted!" + "\n"); + + System.out + .println("Inserting VECTOR with oracle.jdbc.OracleType.VARCHAR2..."); + insertVectorWithVarChar2(conn); + System.out.println( + "VECTOR with oracle.jdbc.OracleType.VARCHAR2 inserted!" + "\n"); + + System.out.println("Inserting VECTOR with Batch API..."); + insertVectorWithBatchAPI(conn); + System.out.println("VECTOR with Batch API inserted!" + "\n"); + + System.out.println("Retrieving VECTOR as double array..."); + retrieveVectorAsArray(conn); + System.out.println("VECTOR retrieved!" + "\n"); + + System.out.println("Retrieving VECTOR as String..."); + retrieveVectorAsString(conn); + System.out.println("VECTOR retrieved!" + "\n"); + + System.out.println( + "Retrieving VECTOR with bound VECTOR (L2 - Euclidean distance)..."); + retrieveVectorWithBoundVector(conn); + System.out.println("VECTOR retrieved!"); + + } + } + + private void insertVector(Connection connection) throws SQLException { + PreparedStatement insertStatement = connection.prepareStatement(insertSql); + double[] vector = {1.1, 2.2, 3.3}; + System.out.println("SQL DML: " + insertSql); + System.out.println("VECTOR to be inserted: " + Arrays.toString(vector)); + insertStatement.setInt(1, randomize()); + insertStatement.setObject(2, vector, OracleType.VECTOR); + insertStatement.executeUpdate(); + } + + private void insertVectorWithVarChar2(Connection connection) + throws SQLException { + PreparedStatement insertStatement = connection.prepareStatement(insertSql); + double[] vector = {1.1, 2.2, 3.3}; + System.out.println("SQL DML: " + insertSql); + System.out.println("VECTOR to be inserted: " + Arrays.toString(vector)); + insertStatement.setInt(1, randomize()); + insertStatement.setObject(2, Arrays.toString(vector), OracleType.VARCHAR2); + insertStatement.executeUpdate(); + } + + private void insertVectorWithBatchAPI(Connection connection) + throws SQLException { + double[][] vectors = {{1.1, 2.2, 3.3}, {1.3, 7.2, 4.3}, {5.9, 5.2, 7.3}}; + System.out.println("SQL DML: " + insertSql); + System.out.println("VECTORs to be inserted as a batch: " + + Arrays.toString(vectors[0]) + ", " + Arrays.toString(vectors[1]) + + ", " + Arrays.toString(vectors[2])); + try (PreparedStatement insertStatement = connection + .prepareStatement(insertSql)) { + for (double[] vector : vectors) { + insertStatement.setInt(1, randomize()); + insertStatement.setObject(2, vector, OracleType.VECTOR); + insertStatement.addBatch(); + } + insertStatement.executeBatch(); + } + } + + private void retrieveVectorAsArray(Connection connection) + throws SQLException { + PreparedStatement queryStatement = connection.prepareStatement(querySql); + System.out.println("SQL DML: " + querySql); + ResultSet resultSet = queryStatement.executeQuery(); + double[] vector = null; + while (resultSet.next()) { + vector = resultSet.getObject(2, double[].class); + } + System.out.println("Retrieved VECTOR: " + Arrays.toString(vector)); + } + + private void retrieveVectorAsString(Connection connection) + throws SQLException { + PreparedStatement queryStatement = connection.prepareStatement(querySql); + System.out.println("SQL DML: " + querySql); + ResultSet resultSet = queryStatement.executeQuery(); + String vector = null; + while (resultSet.next()) { + vector = (String) resultSet.getObject(2); + } + System.out.println("Retrieved VECTOR: " + vector); + } + + private void retrieveVectorWithBoundVector(Connection connection) + throws SQLException { + // Bind a Vector to a select + PreparedStatement queryStatement = connection + .prepareStatement(querySqlWithBind); + double[] inputVector = {1.0, 2.2, 3.3}; + System.out.println("SQL DML: " + querySqlWithBind); + System.out.println("Bound VECTOR: " + Arrays.toString(inputVector)); + queryStatement.setObject(1, inputVector, OracleType.VECTOR); + ResultSet resultSet = queryStatement.executeQuery(); + resultSet.next(); + double[] outputVector = resultSet.getObject(2, double[].class); + System.out.println("Retrieved VECTOR: " + Arrays.toString(outputVector)); + } + + private Connection getConnectionFromPooledDataSource() throws SQLException { + // Create pool-enabled data source instance + PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource(); + // set connection properties on the data source + pds.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource"); + pds.setURL(URL); + pds.setUser(USERNAME); + pds.setPassword(PASSWORD); + // Configure pool properties with a Properties instance + Properties prop = new Properties(); + prop.setProperty("oracle.jdbc.vectorDefaultGetObjectType", "String"); + pds.setConnectionProperties(prop); + // Override any pool properties directly + pds.setInitialPoolSize(10); + // Get a database connection from the pool-enabled data source + Connection conn = pds.getConnection(); + return conn; + } + + private int randomize() { + return ThreadLocalRandom.current().nextInt(); + } } From 2994de395fb1557d686a94778e6649b6bb42b494 Mon Sep 17 00:00:00 2001 From: juarezjuniorgithub Date: Tue, 2 Jul 2024 00:50:06 +0100 Subject: [PATCH 3/4] try-with-resources --- .../jdbc/OracleAIVectorSearchWithJava.java | 86 +++++++++++-------- 1 file changed, 48 insertions(+), 38 deletions(-) diff --git a/java/23ai-jdbc-vector-search/src/main/java/com/oracle/dev/jdbc/OracleAIVectorSearchWithJava.java b/java/23ai-jdbc-vector-search/src/main/java/com/oracle/dev/jdbc/OracleAIVectorSearchWithJava.java index 38872258..6789c8eb 100644 --- a/java/23ai-jdbc-vector-search/src/main/java/com/oracle/dev/jdbc/OracleAIVectorSearchWithJava.java +++ b/java/23ai-jdbc-vector-search/src/main/java/com/oracle/dev/jdbc/OracleAIVectorSearchWithJava.java @@ -83,24 +83,29 @@ private void execute() throws SQLException { } private void insertVector(Connection connection) throws SQLException { - PreparedStatement insertStatement = connection.prepareStatement(insertSql); - double[] vector = {1.1, 2.2, 3.3}; - System.out.println("SQL DML: " + insertSql); - System.out.println("VECTOR to be inserted: " + Arrays.toString(vector)); - insertStatement.setInt(1, randomize()); - insertStatement.setObject(2, vector, OracleType.VECTOR); - insertStatement.executeUpdate(); + try (PreparedStatement insertStatement = connection + .prepareStatement(insertSql);) { + double[] vector = {1.1, 2.2, 3.3}; + System.out.println("SQL DML: " + insertSql); + System.out.println("VECTOR to be inserted: " + Arrays.toString(vector)); + insertStatement.setInt(1, randomize()); + insertStatement.setObject(2, vector, OracleType.VECTOR); + insertStatement.executeUpdate(); + } } private void insertVectorWithVarChar2(Connection connection) throws SQLException { - PreparedStatement insertStatement = connection.prepareStatement(insertSql); - double[] vector = {1.1, 2.2, 3.3}; - System.out.println("SQL DML: " + insertSql); - System.out.println("VECTOR to be inserted: " + Arrays.toString(vector)); - insertStatement.setInt(1, randomize()); - insertStatement.setObject(2, Arrays.toString(vector), OracleType.VARCHAR2); - insertStatement.executeUpdate(); + try (PreparedStatement insertStatement = connection + .prepareStatement(insertSql);) { + double[] vector = {1.1, 2.2, 3.3}; + System.out.println("SQL DML: " + insertSql); + System.out.println("VECTOR to be inserted: " + Arrays.toString(vector)); + insertStatement.setInt(1, randomize()); + insertStatement.setObject(2, Arrays.toString(vector), + OracleType.VARCHAR2); + insertStatement.executeUpdate(); + } } private void insertVectorWithBatchAPI(Connection connection) @@ -123,41 +128,46 @@ private void insertVectorWithBatchAPI(Connection connection) private void retrieveVectorAsArray(Connection connection) throws SQLException { - PreparedStatement queryStatement = connection.prepareStatement(querySql); - System.out.println("SQL DML: " + querySql); - ResultSet resultSet = queryStatement.executeQuery(); - double[] vector = null; - while (resultSet.next()) { - vector = resultSet.getObject(2, double[].class); + try (PreparedStatement queryStatement = connection + .prepareStatement(querySql);) { + System.out.println("SQL DML: " + querySql); + ResultSet resultSet = queryStatement.executeQuery(); + double[] vector = null; + while (resultSet.next()) { + vector = resultSet.getObject(2, double[].class); + } + System.out.println("Retrieved VECTOR: " + Arrays.toString(vector)); } - System.out.println("Retrieved VECTOR: " + Arrays.toString(vector)); } private void retrieveVectorAsString(Connection connection) throws SQLException { - PreparedStatement queryStatement = connection.prepareStatement(querySql); - System.out.println("SQL DML: " + querySql); - ResultSet resultSet = queryStatement.executeQuery(); - String vector = null; - while (resultSet.next()) { - vector = (String) resultSet.getObject(2); + try (PreparedStatement queryStatement = connection + .prepareStatement(querySql);) { + System.out.println("SQL DML: " + querySql); + ResultSet resultSet = queryStatement.executeQuery(); + String vector = null; + while (resultSet.next()) { + vector = (String) resultSet.getObject(2); + } + System.out.println("Retrieved VECTOR: " + vector); } - System.out.println("Retrieved VECTOR: " + vector); } private void retrieveVectorWithBoundVector(Connection connection) throws SQLException { // Bind a Vector to a select - PreparedStatement queryStatement = connection - .prepareStatement(querySqlWithBind); - double[] inputVector = {1.0, 2.2, 3.3}; - System.out.println("SQL DML: " + querySqlWithBind); - System.out.println("Bound VECTOR: " + Arrays.toString(inputVector)); - queryStatement.setObject(1, inputVector, OracleType.VECTOR); - ResultSet resultSet = queryStatement.executeQuery(); - resultSet.next(); - double[] outputVector = resultSet.getObject(2, double[].class); - System.out.println("Retrieved VECTOR: " + Arrays.toString(outputVector)); + try (PreparedStatement queryStatement = connection + .prepareStatement(querySqlWithBind);) { + double[] inputVector = {1.0, 2.2, 3.3}; + System.out.println("SQL DML: " + querySqlWithBind); + System.out.println("Bound VECTOR: " + Arrays.toString(inputVector)); + queryStatement.setObject(1, inputVector, OracleType.VECTOR); + ResultSet resultSet = queryStatement.executeQuery(); + resultSet.next(); + double[] outputVector = resultSet.getObject(2, double[].class); + System.out.println("Retrieved VECTOR: " + Arrays.toString(outputVector)); + } } private Connection getConnectionFromPooledDataSource() throws SQLException { From 432273ba936874dc7837350a416a1c9e569a5c12 Mon Sep 17 00:00:00 2001 From: juarezjuniorgithub Date: Mon, 4 Nov 2024 18:00:14 +0000 Subject: [PATCH 4/4] remove randomized ID and use autogenerated ID instead --- .../sql/23ai-jdbc-vector-search.sql | 23 +++- .../jdbc/OracleAIVectorSearchWithJava.java | 113 ++++++++---------- 2 files changed, 70 insertions(+), 66 deletions(-) diff --git a/java/23ai-jdbc-vector-search/sql/23ai-jdbc-vector-search.sql b/java/23ai-jdbc-vector-search/sql/23ai-jdbc-vector-search.sql index fa50b4a8..01092479 100644 --- a/java/23ai-jdbc-vector-search/sql/23ai-jdbc-vector-search.sql +++ b/java/23ai-jdbc-vector-search/sql/23ai-jdbc-vector-search.sql @@ -1,10 +1,29 @@ +SELECT * FROM V$VERSION; + CREATE USER VECTOR_USER IDENTIFIED BY QUOTA UNLIMITED ON USERS; GRANT DB_DEVELOPER_ROLE TO VECTOR_USER; GRANT CREATE SESSION TO VECTOR_USER; + GRANT SELECT ANY TABLE ON SCHEMA VECTOR_USER TO VECTOR_USER; GRANT SELECT ANY TABLE ON SCHEMA VECTOR_USER TO VECTOR_USER; GRANT SELECT ANY TABLE ON SCHEMA VECTOR_USER TO VECTOR_USER; GRANT SELECT ANY TABLE ON SCHEMA VECTOR_USER TO VECTOR_USER; + ALTER SESSION SET CURRENT_SCHEMA = VECTOR_USER; -CREATE TABLE VECTOR_USER.ORACLE_AI_VECTOR_SEARCH_DEMO (ID NUMBER PRIMARY KEY, VECTOR_DATA VECTOR(3, FLOAT64)); -COMMIT; \ No newline at end of file + +CREATE TABLE VECTOR_USER.ORACLE_AI_VECTOR_SEARCH_DEMO (ID NUMBER GENERATED ALWAYS as IDENTITY(START with 1 INCREMENT by 1) PRIMARY KEY, VECTOR_DATA VECTOR(3, FLOAT64)); +COMMIT; + +DESCRIBE VECTOR_USER.ORACLE_AI_VECTOR_SEARCH_DEMO; + +SELECT * FROM VECTOR_USER.ORACLE_AI_VECTOR_SEARCH_DEMO; + +DELETE FROM VECTOR_USER.ORACLE_AI_VECTOR_SEARCH_DEMO; +COMMIT; + +DROP TABLE VECTOR_USER.ORACLE_AI_VECTOR_SEARCH_DEMO PURGE; + + + + + diff --git a/java/23ai-jdbc-vector-search/src/main/java/com/oracle/dev/jdbc/OracleAIVectorSearchWithJava.java b/java/23ai-jdbc-vector-search/src/main/java/com/oracle/dev/jdbc/OracleAIVectorSearchWithJava.java index 6789c8eb..d2106e18 100644 --- a/java/23ai-jdbc-vector-search/src/main/java/com/oracle/dev/jdbc/OracleAIVectorSearchWithJava.java +++ b/java/23ai-jdbc-vector-search/src/main/java/com/oracle/dev/jdbc/OracleAIVectorSearchWithJava.java @@ -23,7 +23,6 @@ import java.sql.SQLException; import java.util.Arrays; import java.util.Properties; -import java.util.concurrent.ThreadLocalRandom; import oracle.jdbc.OracleType; import oracle.ucp.jdbc.PoolDataSource; @@ -31,13 +30,13 @@ public class OracleAIVectorSearchWithJava { - private final static String URL = ""; - private final static String USERNAME = ""; - private final static String PASSWORD = ""; + private final static String URL = "jdbc:oracle:thin:@localhost:1521/FREEPDB1"; + private final static String USERNAME = System.getenv("DB_23AI_USERNAME"); + private final static String PASSWORD = System.getenv("DB_23AI_PASSWORD"); - private String insertSql = "INSERT INTO ORACLE_AI_VECTOR_SEARCH_DEMO (ID, VECTOR_DATA) VALUES (?, ?)"; + private String insertSql = "INSERT INTO ORACLE_AI_VECTOR_SEARCH_DEMO (VECTOR_DATA) VALUES (?)"; private String querySql = "SELECT ID, VECTOR_DATA FROM ORACLE_AI_VECTOR_SEARCH_DEMO"; - private String querySqlWithBind = "SELECT ID, VECTOR_DATA FROM ORACLE_AI_VECTOR_SEARCH_DEMO ORDER BY VECTOR_DISTANCE(VECTOR_DATA, ?, DOT)"; + private String querySqlWithBind = "SELECT ID, VECTOR_DATA FROM ORACLE_AI_VECTOR_SEARCH_DEMO ORDER BY VECTOR_DISTANCE(VECTOR_DATA, ?, COSINE)"; public static void main(String[] args) throws SQLException { OracleAIVectorSearchWithJava oracleAIVectorSearch = new OracleAIVectorSearchWithJava(); @@ -83,43 +82,39 @@ private void execute() throws SQLException { } private void insertVector(Connection connection) throws SQLException { - try (PreparedStatement insertStatement = connection - .prepareStatement(insertSql);) { - double[] vector = {1.1, 2.2, 3.3}; - System.out.println("SQL DML: " + insertSql); - System.out.println("VECTOR to be inserted: " + Arrays.toString(vector)); - insertStatement.setInt(1, randomize()); - insertStatement.setObject(2, vector, OracleType.VECTOR); - insertStatement.executeUpdate(); - } + PreparedStatement insertStatement = connection.prepareStatement(insertSql, + new String[]{"ID"}); + float[] vector = {1.1f, 2.2f, 3.3f}; + System.out.println("SQL DML: " + insertSql); + System.out.println("VECTOR to be inserted: " + Arrays.toString(vector)); + insertStatement.setObject(1, vector, OracleType.VECTOR_FLOAT64); + insertStatement.executeUpdate(); } private void insertVectorWithVarChar2(Connection connection) throws SQLException { - try (PreparedStatement insertStatement = connection - .prepareStatement(insertSql);) { - double[] vector = {1.1, 2.2, 3.3}; - System.out.println("SQL DML: " + insertSql); - System.out.println("VECTOR to be inserted: " + Arrays.toString(vector)); - insertStatement.setInt(1, randomize()); - insertStatement.setObject(2, Arrays.toString(vector), - OracleType.VARCHAR2); - insertStatement.executeUpdate(); - } + PreparedStatement insertStatement = connection.prepareStatement(insertSql, + new String[]{"ID"}); + float[] vector = {1.1f, 2.2f, 3.3f}; + System.out.println("SQL DML: " + insertSql); + System.out.println("VECTOR to be inserted: " + Arrays.toString(vector)); + insertStatement.setObject(1, Arrays.toString(vector), OracleType.VARCHAR2); + insertStatement.executeUpdate(); } private void insertVectorWithBatchAPI(Connection connection) throws SQLException { - double[][] vectors = {{1.1, 2.2, 3.3}, {1.3, 7.2, 4.3}, {5.9, 5.2, 7.3}}; + + float[][] vectors = {{1.1f, 2.2f, 3.3f}, {1.3f, 7.2f, 4.3f}, + {5.9f, 5.2f, 7.3f}}; System.out.println("SQL DML: " + insertSql); System.out.println("VECTORs to be inserted as a batch: " + Arrays.toString(vectors[0]) + ", " + Arrays.toString(vectors[1]) + ", " + Arrays.toString(vectors[2])); try (PreparedStatement insertStatement = connection - .prepareStatement(insertSql)) { - for (double[] vector : vectors) { - insertStatement.setInt(1, randomize()); - insertStatement.setObject(2, vector, OracleType.VECTOR); + .prepareStatement(insertSql, new String[]{"ID"})) { + for (float[] vector : vectors) { + insertStatement.setObject(1, vector, OracleType.VECTOR_FLOAT64); insertStatement.addBatch(); } insertStatement.executeBatch(); @@ -128,46 +123,40 @@ private void insertVectorWithBatchAPI(Connection connection) private void retrieveVectorAsArray(Connection connection) throws SQLException { - try (PreparedStatement queryStatement = connection - .prepareStatement(querySql);) { - System.out.println("SQL DML: " + querySql); - ResultSet resultSet = queryStatement.executeQuery(); - double[] vector = null; - while (resultSet.next()) { - vector = resultSet.getObject(2, double[].class); - } - System.out.println("Retrieved VECTOR: " + Arrays.toString(vector)); + PreparedStatement queryStatement = connection.prepareStatement(querySql); + System.out.println("SQL DML: " + querySql); + ResultSet resultSet = queryStatement.executeQuery(); + float[] vector = null; + while (resultSet.next()) { + vector = resultSet.getObject(2, float[].class); } + System.out.println("Retrieved VECTOR: " + Arrays.toString(vector)); } private void retrieveVectorAsString(Connection connection) throws SQLException { - try (PreparedStatement queryStatement = connection - .prepareStatement(querySql);) { - System.out.println("SQL DML: " + querySql); - ResultSet resultSet = queryStatement.executeQuery(); - String vector = null; - while (resultSet.next()) { - vector = (String) resultSet.getObject(2); - } - System.out.println("Retrieved VECTOR: " + vector); + PreparedStatement queryStatement = connection.prepareStatement(querySql); + System.out.println("SQL DML: " + querySql); + ResultSet resultSet = queryStatement.executeQuery(); + String vector = null; + while (resultSet.next()) { + vector = (String) resultSet.getObject(2); } + System.out.println("Retrieved VECTOR: " + vector); } private void retrieveVectorWithBoundVector(Connection connection) throws SQLException { - // Bind a Vector to a select - try (PreparedStatement queryStatement = connection - .prepareStatement(querySqlWithBind);) { - double[] inputVector = {1.0, 2.2, 3.3}; - System.out.println("SQL DML: " + querySqlWithBind); - System.out.println("Bound VECTOR: " + Arrays.toString(inputVector)); - queryStatement.setObject(1, inputVector, OracleType.VECTOR); - ResultSet resultSet = queryStatement.executeQuery(); - resultSet.next(); - double[] outputVector = resultSet.getObject(2, double[].class); - System.out.println("Retrieved VECTOR: " + Arrays.toString(outputVector)); - } + PreparedStatement queryStatement = connection + .prepareStatement(querySqlWithBind); + float[] inputVector = {1.0f, 2.2f, 3.3f}; + System.out.println("SQL DML: " + querySqlWithBind); + System.out.println("Bound VECTOR: " + Arrays.toString(inputVector)); + queryStatement.setObject(1, inputVector, OracleType.VECTOR_FLOAT64); + ResultSet resultSet = queryStatement.executeQuery(); + resultSet.next(); + float[] outputVector = resultSet.getObject(2, float[].class); + System.out.println("Retrieved VECTOR: " + Arrays.toString(outputVector)); } private Connection getConnectionFromPooledDataSource() throws SQLException { @@ -189,8 +178,4 @@ private Connection getConnectionFromPooledDataSource() throws SQLException { return conn; } - private int randomize() { - return ThreadLocalRandom.current().nextInt(); - } - }