SQL-J in Adaptiv Server Anywhere 8.0 Technologie Memo 19. April 2004 Dr. Arno Schmidhauser Inhalt 1 2 3 4 5 1 Importieren von Java-Klassen...................................................... Performance ............................................................................. Speicherplatz ............................................................................ SQL ......................................................................................... Java......................................................................................... 2 2 2 2 4 SQL-J in Adaptiv Server Anywhere 8.0 Importieren von Java-Klassen Im SQL-Frontend oder Sybase Central Klassen müssen mit JDK 1.3 kompiliert werden. Java Enabling in der Datenbank (Nur Java 1.3 erlaubt). alter database upgrade java on Klasse importieren mit install java [new|update] [jar jarname] from file 'classfile' Beim Ändern einer Klassendefinition werden bestehende Objekte in einer Tabelle angepasst. Neue Attribute werden neu hinzugefügt und mit einem Defaultwert belegt. Nicht mehr bestehende Attribute werden gelöscht. Eine Änderung von allfälligen Basisklassen ergibt dasselbe Verhalten: Ist die Basisklasse neu, werden die neu geerbten Attribute der bestehenden Objekte mit einem Defaultwert belegt. Existiert die Basisklasse nicht mehr, werden die Attribute aus der vormaligen Basisklasse nicht mehr ausgegeben. 2 3 4 Performance Indexierung auf dem Objekt als Ganzes erlaubt, jedoch nicht auf einzelnen Attributen des Objektes. Das heisst, die Klasse des Objektes muss das Interface Comparable implementieren. Auf Basis der Funktion compareTo() findet dann die Indexierung statt. Speicherplatz Overhead für Java-Objekte : 10-15 Byte pro Objekt (gemäss Manual) SQL Methoden die in Java void zurückliefern, werden für die Ausführung von SQL in this uminterpretiert. Folgender Update-Befehl wird damit möglich: update tabelle set obj = obj.setAttribut( neuerWert ) Bei Abfragen ist jedoch keine Modifizierung von Objekten in der Datenbank möglich. Der Befehl Technologie Memo Arno Schmidhauser 2 SQL-J in Adaptiv Server Anywhere 8.0 select obj.setAttr( wert ) from tablename führt nicht zu einer Modifikation des Objektes in der DB, sondern nur des ausgelieferten Objektes. order by obj.attribut oder order by obj.methode() ist erlaubt. wenn bei interaktivem SQL das ganze Objekt mit select obj abgefragt wird, wird anstelle von obj der Wert von obj.toString() eingesetzt. Durch die Implementierung von Comparable kann zum Beispiel nach select max(obj) from tabelle gesucht werden, wobei als Resultat direkt das gesuchte Objekt zurückgeliefert wird. cast von Objekten nach Objekten einer Unterklasse select (cast( obj as MyClass)).field from table where obj.getClass().getName() = 'MyClass' Klassenmethoden können über SQL ausgeführt werden. Sie können ohne Weiteres auch andere SQL-Felder als Parameter haben. Beispiel: select Klasse.methode( sqltabellenfeld ), sqltabellenfeld from tabelle Es können Stored Procedures in Java erstellt werden, welche ResultSets an einen JDBC-Client zurückgeben: // Der Java Code der Stored Procedure -------------------------------public static void aStoredProcedure( int id, ResultSet[] rset ) { try { System.out.println( "aStoredProcedure entered." ); Connection con; con = DriverManager.getConnection( "jdbc:default:connection" ); PreparedStatement stmt; stmt = con.prepareStatement( "SELECT fname, lname FROM customer WHERE id = ?"); stmt.setInt( 1, id ); ResultSet rs = stmt.executeQuery(); rset[0] = rs; } catch ( Exception e ) { e.printStackTrace(); } } // Die Prozedur-Deklaration in SQL ----------------------------------CREATE PROCEDURE aProc( in customerid int ) DYNAMIC RESULT SETS 1 EXTERNAL NAME 'Procedures.aStoredProcedure (I[Ljava/sql/ResultSet;)V' LANGUAGE JAVA // Der Aufruf seitens des Clients -----------------------------------Properties p = new Properties(); p.put( "USER", "dba" ); p.put( "PASSWORD", "sql" ); Technologie Memo Arno Schmidhauser 3 SQL-J in Adaptiv Server Anywhere 8.0 p.put( "SERVICENAME", "asademo" ); p.put( "IGNORE_DONE_IN_PROC", "true" ); Connection con = DriverManager.getConnection( "jdbc:sybase:Tds:localhost:2638", p );CallableStatement pstmt = con.prepareCall( "{call aProc ? }" ); pstmt.setInt( 1, 103 ); // 103 is an example ResultSet rs = pstmt.executeQuery(); while ( rs.next() ) { System.out.println( rs.getString(1) + " " + rs.getString(2) ); } Ohne das das Setzen von IGNORE_DONE_IN_PROC für die JDBC Connection funktioniert der Aufruf nicht. Analog zu CREATE PROCEDURE kann auch CREATE FUNCTION verwendet werden. 5 In einem Trigger kann eine Java-Stored Procedure aufgerufen werden. Zugriff auf die Pseudotabellen deleted und inserted scheint aber nicht möglich zu sein. Möglicherweise funktioniert für Trigger auf Zeilenebene die Übergabe von einzelnen Werten einer Zeile in Form von Parametern an die Trigger-Prozedur. Java Serverseitiges Multithreading erlaubt. Führen die serverseitigen Methoden JDBC durch, sind die Aufrufe von Methoden des JDBC-API synchronisiert. Serverseitige Threads laufen nur solange, wie der aufrufende Thread (umgebender SQL-Befehl) aktiv ist. Es ist daher nicht möglich, unabhängige (detached) Threads in die Datenbank einzupflanzen. Dynamic Class Loading von der Datenbank zur Applikation, welche Java-Objekte von der Datenbank abfragt, ist möglich (Siehe Anleitung zu jConnect, advanced features). Zu beachten ist aber, dass die Klasse zur Kompilationszeit der Applikation dann nicht zur Verfügung steht und alle Eigenschaften der über getObject() geladenen Objekte via Reflection API ermittelt werden müssen. Properties props = new Properties(); String classesUrl = "jdbc:sybase:Tds:myase:1200"; props.put("user", "grinch"); props.put("password", "meanone"); DynamicClassLoader loader = driver.getClassLoader(classesUrl, props); props.put("CLASS_LOADER", loader); props.put("user", "joeuser"); props.put("password", "joespassword"); String url = "jdbc:sybase:Tds:jdbc.sybase.com:4446"; Connection conn = DriverManager.getConnection(url, props); Statement stmnt = conn.createStatement(); ResultSet rs = stmnt.executeQuery( "select * from employee where empid = '19'"); if (rs.next() { Technologie Memo Arno Schmidhauser 4 SQL-J in Adaptiv Server Anywhere 8.0 // Even though the class is not in our class path, // we should be able to access its instance. Object obj = rs.getObject("address"); // The class has been loaded from the server, // so let's take a look. Class c = obj.getClass(); // Some Java Reflection can be done here // to access the fields of obj. } Technologie Memo Arno Schmidhauser 5