Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion JavaCon/JDBC/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc11</artifactId>
<version>21.21.0.0</version>
<version>23.26.1.0.0</version>
</dependency>

</dependencies>
Expand Down
163 changes: 163 additions & 0 deletions JavaCon/JDBC/src/main/java/MyRowSet/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
# MyRowSet β€” running the demos

The demos under `MyRowSet/Types/` connect to an Oracle DB at
`jdbc:oracle:thin:@localhost:1521/FREE` with user `system` and password
`98989`. Bring up a local Oracle FREE container, seed a couple of tables, run
the demo.

## 1. Start Oracle Free in Docker

```bash
docker run -d --name oracle-free \
-p 1521:1521 \
-e ORACLE_PASSWORD=98989 \
gvenzl/oracle-free:slim
```

Wait until the log says `DATABASE IS READY TO USE`:

```bash
docker logs -f oracle-free
```

Service name is `FREE` (not the legacy SID `orcl`). The demos already use
`jdbc:oracle:thin:@localhost:1521/FREE` β€” keep that connection string when
running locally.

## 2. Seed the schema

Connect with SQL\*Plus inside the container:

```bash
docker exec -it oracle-free sqlplus system/98989@//localhost:1521/FREE
```

Then run:

```sql
CREATE TABLE emp (
emp_id NUMBER,
emp_fname VARCHAR2(50),
emp_lname VARCHAR2(50),
emp_dob DATE,
emp_salary NUMBER
);

INSERT INTO emp VALUES (1, 'Sam', 'Smith', DATE '1987-11-24', 6400);
INSERT INTO emp VALUES (2, 'Kevin', 'Patel', DATE '1990-02-10', 7100);

CREATE TABLE person (
p_fname VARCHAR2(50),
p_lname VARCHAR2(50),
accno NUMBER
);

CREATE TABLE bank (
accno NUMBER,
income NUMBER
);

INSERT INTO person VALUES ('Sam', 'Smith', 1001);
INSERT INTO bank VALUES (1001, 50000);

COMMIT;
EXIT;
```

`emp` is enough for `CachedRowSetDemo`, `WebRowSetDemo`, `JdbcRowSetDemo`,
`FilteredRowSetDemo`. `person` + `bank` are required for `JoinRowSetDemo`.

## 3. Browse the DB from IntelliJ (optional, but handy)

IntelliJ Ultimate / DataGrip ship a Database tool window that talks to
the same container β€” useful for seeding rows, inspecting state between
demo runs, or running ad-hoc SQL without re-opening `sqlplus`.

1. **Open the tool window** β€” `View` β†’ `Tool Windows` β†’ `Database` (or
βŒ˜β‡§A β†’ "Database").
2. **Add data source** β€” click `+` β†’ `Data Source` β†’ `Oracle`.
3. **Connection settings** β€” pick the `Service` tab (not SID):

| Field | Value |
|----------|------------------------|
| Host | `localhost` |
| Port | `1521` |
| Service | `FREE` |
| User | `system` |
| Password | `98989` |
| URL type | `Service name` |

The generated URL should read
`jdbc:oracle:thin:@//localhost:1521/FREE` β€” same coordinates the demos
use.
4. **Driver** β€” first time, IntelliJ prompts to download the Oracle JDBC
driver. Click `Download driver files`. (Don't reuse the project's
`ojdbc11` jar; the IDE manages its own copy.)
5. **Test Connection** β†’ `Apply` β†’ `OK`. If the test fails with
`ORA-12541`, the container isn't ready yet β€” wait for
`DATABASE IS READY TO USE` (step 1).
6. **Run the seed SQL** β€” right-click the data source β†’ `New` β†’ `Query
Console`, paste the `CREATE TABLE` / `INSERT` block from step 2, then
⌘⏎ to execute. Expand the source in the tree and the new tables show
up under `FREE` β†’ `SYSTEM` β†’ `Tables`.

After a demo runs, refresh the table (⌘F5 on `emp`) to see updated
rows. The Database tool window also surfaces the rowsets the demo
serialises β€” open `${java.io.tmpdir}/emp.xml` directly in the editor to
verify XML output from `WebRowSetDemo`.

## 4. Run a demo

From repo root:

```bash
cd JavaCon/JDBC
mvn -q compile exec:java \
-Dexec.mainClass="MyRowSet.Types.CachedRowSetDemo" \
-Dexec.classpathScope="compile"
```

Swap the main class for the demo you want:

| Demo | Main class |
|-------------------------|-----------------------------------------|
| Cached, serialised RS | `MyRowSet.Types.CachedRowSetDemo` |
| WebRowSet β†’ XML | `MyRowSet.Types.WebRowSetDemo` |
| Connected JDBC RowSet | `MyRowSet.Types.JdbcRowSetDemo` |
| Filter via Predicate | `MyRowSet.Types.FilteredRowSetDemo` |
| Join two CachedRowSets | `MyRowSet.Types.JoinRowSetDemo` |

In IntelliJ: open the demo, right-click β†’ **Run**.

## 5. Output files

`CachedRowSetDemo` writes the serialised rowset to
`${java.io.tmpdir}/cached_rowset.bin`, and `WebRowSetDemo` writes the XML
dump to `${java.io.tmpdir}/emp.xml`. Inspect with:

```bash
ls "$(printf '%s' "$TMPDIR")cached_rowset.bin" "$(printf '%s' "$TMPDIR")emp.xml"
```

## 6. Tear down

```bash
docker stop oracle-free && docker rm oracle-free
```

## Troubleshooting

- **`ORA-12541: Cannot connect. No listener…`** β€” container not up or port
not mapped. Re-check `docker ps` and the `-p 1521:1521` flag.
- **`ORA-01017: invalid credential`** β€” `ORACLE_PASSWORD` env var differs
from the demo's hardcoded `98989`. Either rerun the container with the
expected value or change the demo.
- **`ORA-00942: table or view does not exist`** β€” schema seeding step (2)
was skipped or pointed at the wrong PDB. Verify with
`SELECT table_name FROM user_tables;`.
- **IntelliJ "URL is not specified"** β€” make sure the URL type dropdown
is set to `Service name`, not `SID`. SID `FREE` exists too but the
demos use the service URL form (`/FREE`, not `:FREE`).
- **First container start takes minutes** β€” Oracle initialises the PDB on
first boot. Subsequent restarts are fast because data lives in the
container's volume.
2 changes: 1 addition & 1 deletion JavaCon/JDBC/src/main/java/MyRowSet/RowSetDemo.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ registered to the interface to receive notification when a certain event is trig

public class RowSetDemo {
public static void main(String[] args) {
String url = "jdbc:oracle:thin:@localhost:1521:orcl";
String url = "jdbc:oracle:thin:@localhost:1521/FREE";
String password = "98989";
String username = "system";

Expand Down
47 changes: 29 additions & 18 deletions JavaCon/JDBC/src/main/java/MyRowSet/Types/CachedRowSetDemo.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@

package MyRowSet.Types;

/*This import causes maven to fail hence excluding it*/

import oracle.jdbc.driver.OracleDriver;
import oracle.jdbc.rowset.OracleCachedRowSet;

import java.io.*;
import javax.sql.rowset.CachedRowSet;
import javax.sql.rowset.RowSetProvider;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.SQLException;

/**
Expand All @@ -27,54 +32,60 @@
* On the downside, connection has to be established every time to reflect any changes, performance may be slower than
* jdbcrowset but on the upside it is lightweight and we can get a better efficiency when working with large amount of
* data
*
* <p><b>Migration note (ojdbc11 23.x):</b> ojdbc11 23.x removed the {@code oracle.jdbc.rowset}
* package, so {@code OracleCachedRowSet} no longer exists. Replaced with the JDK-bundled
* {@link javax.sql.rowset.RowSetProvider#newFactory()} +
* {@link javax.sql.rowset.RowSetFactory#createCachedRowSet()}. Variable + return types now use
* the {@link CachedRowSet} interface β€” vendor-neutral and stable across driver upgrades.
*/
public class CachedRowSetDemo {
private final static String fileName = "exceptions.try_with_resources.C:\\Users\\Saurabh\\Documents\\GitHub\\JAVA\\JavaCon\\JDBC\\src\\MyRowSet\\Types\\xyz.txt";
private static final Path FILE_PATH = Paths.get(System.getProperty("java.io.tmpdir"), "cached_rowset.bin");

public static void writeCatchedRowSet() throws SQLException, ClassNotFoundException, IOException {
OracleCachedRowSet rowSet = new OracleCachedRowSet();
CachedRowSet rowSet = RowSetProvider.newFactory().createCachedRowSet();

Class.forName(OracleDriver.class.getName());
rowSet.setUrl("jdbc:oracle:thin:@localhost:1521:orcl");
rowSet.setUrl("jdbc:oracle:thin:@localhost:1521/FREE");
rowSet.setUsername("system");
rowSet.setPassword("98989");

String sql = "select * from emp";
rowSet.setCommand(sql);
rowSet.execute();

FileOutputStream fos = new FileOutputStream(fileName);
FileOutputStream fos = new FileOutputStream(FILE_PATH.toFile());
ObjectOutputStream out = new ObjectOutputStream(fos);

out.writeObject(rowSet);
out.close();
rowSet.close();
}

public static OracleCachedRowSet readOracleCatchedRowSet() throws IOException, ClassNotFoundException {
FileInputStream fin = new FileInputStream(fileName);
public static CachedRowSet readOracleCatchedRowSet() throws IOException, ClassNotFoundException {
FileInputStream fin = new FileInputStream(FILE_PATH.toFile());
ObjectInputStream in = new ObjectInputStream(fin);

OracleCachedRowSet oracleCachedRowSet = (OracleCachedRowSet) in.readObject();
CachedRowSet cachedRowSet = (CachedRowSet) in.readObject();
fin.close();
in.close();

return oracleCachedRowSet;
return cachedRowSet;

}

public static void main(String[] args) {
try {
writeCatchedRowSet();

OracleCachedRowSet oracleCachedRowSet = readOracleCatchedRowSet();
while (oracleCachedRowSet.next()) {
System.out.print("ID " + oracleCachedRowSet.getString(1));
System.out.print("\tName " + oracleCachedRowSet.getString(2));
System.out.println("\tSalary " + oracleCachedRowSet.getString(5));
CachedRowSet cachedRowSet = readOracleCatchedRowSet();
while (cachedRowSet.next()) {
System.out.print("ID " + cachedRowSet.getString(1));
System.out.print("\tName " + cachedRowSet.getString(2));
System.out.println("\tSalary " + cachedRowSet.getString(5));
}

oracleCachedRowSet.close();
cachedRowSet.close();
} catch (IOException | SQLException | ClassNotFoundException e) {
e.printStackTrace();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,21 @@

package MyRowSet.Types;

//import com.sun.rowset.FilteredRowSetImpl; - this is gone

import oracle.jdbc.rowset.OracleFilteredRowSet;

import javax.sql.RowSet;
import javax.sql.rowset.CachedRowSet;
import javax.sql.rowset.FilteredRowSet;
import javax.sql.rowset.Predicate;
import javax.sql.rowset.RowSetProvider;
import java.sql.SQLException;

/**
* Created by Saurabh on 11/29/2015. A filtered RowSet object contains only the filtered rows of the database. The
* filter criteria is set in the RowSet object and the RowSet only get the filtered data from database to the object.
* The filters can be created by implementing Predicate interface
*
* <p><b>Migration note (ojdbc11 23.x):</b> {@code OracleFilteredRowSet} was removed with the
* {@code oracle.jdbc.rowset} package. Replaced with
* {@link RowSetProvider#newFactory()}{@code .createFilteredRowSet()} β€” JDK-bundled, vendor-neutral.
*/

public class FilteredRowSetDemo implements Predicate {
Expand All @@ -30,10 +31,10 @@ public FilteredRowSetDemo(String colName) {

public static void main(String[] args) throws ClassNotFoundException, SQLException {
Class.forName("oracle.jdbc.driver.OracleDriver");
FilteredRowSet filteredRowSet = new OracleFilteredRowSet();
FilteredRowSet filteredRowSet = RowSetProvider.newFactory().createFilteredRowSet();
filteredRowSet.setUsername("system");
filteredRowSet.setPassword("98989");
filteredRowSet.setUrl("jdbc:oracle:thin:@localhost:1521:orcl");
filteredRowSet.setUrl("jdbc:oracle:thin:@localhost:1521/FREE");
filteredRowSet.setCommand("select * from emp");

//Filter
Expand Down
29 changes: 16 additions & 13 deletions JavaCon/JDBC/src/main/java/MyRowSet/Types/JdbcRowSetDemo.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,10 @@

package MyRowSet.Types;

//import com.sun.rowset.JdbcRowSetImpl;

import oracle.jdbc.rowset.OracleJDBCRowSet;

import javax.sql.RowSetEvent;
import javax.sql.RowSetListener;
import javax.sql.rowset.JdbcRowSet;
import javax.sql.rowset.RowSetProvider;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
Expand All @@ -31,6 +28,12 @@
* By using the reference implementation constructor that takes a Connection object
* By using the reference implementation default constructor
* By using an instance of RowSetFactory, which is created from the class RowSetProvider
*
* <p><b>Migration note (ojdbc11 23.x):</b> {@code OracleJDBCRowSet(Connection)} was removed
* with the {@code oracle.jdbc.rowset} package. Switched to
* {@link RowSetProvider#newFactory()}{@code .createJdbcRowSet()} β€” the rowset now opens its
* own connection from the supplied URL/credentials, so the explicit {@link Connection} +
* {@code conn.close()} are no longer needed (helper {@link #getOracleConnection()} retained).
*/

class ExampleListener implements RowSetListener {
Expand All @@ -55,16 +58,17 @@ public void cursorMoved(RowSetEvent event) {

public class JdbcRowSetDemo {
public static void main(String[] args) throws SQLException, ClassNotFoundException {
Connection conn = getOracleConnection();
// Statement st = conn.createStatement();
Class.forName("oracle.jdbc.driver.OracleDriver");

JdbcRowSet jdbcRowSet;
jdbcRowSet = new OracleJDBCRowSet(conn);
JdbcRowSet jdbcRowSet = RowSetProvider.newFactory().createJdbcRowSet();
jdbcRowSet.setUsername("system");
jdbcRowSet.setPassword("98989");
jdbcRowSet.setUrl("jdbc:oracle:thin:@localhost:1521/FREE");
/*
jdbcRowSet = new JdbcRowSetImpl();
jdbcRowSet.setUsername("system");
jdbcRowSet.setPassword("98989");
jdbcRowSet.setUrl("jdbc:oracle:thin:@localhost:1521:orcl");
jdbcRowSet.setUrl("jdbc:oracle:thin:@localhost:1521/FREE");
jdbcRowSet.setCommand("select * from bank");
jdbcRowSet.execute();
*/
Expand All @@ -89,17 +93,16 @@ public static void main(String[] args) throws SQLException, ClassNotFoundExcepti
System.out.print("name: " + jdbcRowSet.getString("emp_fname"));
System.out.println("\tSalary: " + jdbcRowSet.getInt("emp_salary"));
}
conn.close();
jdbcRowSet.close();
}

public static Connection getOracleConnection() throws ClassNotFoundException, SQLException {
String driver = "oracle.jdbc.driver.OracleDriver";
String url = "jdbc:oracle:thin:@localhost:1521:orcl";
String url = "jdbc:oracle:thin:@localhost:1521/FREE";
String password = "98989";
String username = "system";

Class.forName(driver);
Connection conn = DriverManager.getConnection(url, username, password);
return conn;
return DriverManager.getConnection(url, username, password);
}
}
Loading
Loading