SQL-J in Adaptiv Server Anywhere 8.0

Werbung
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
Herunterladen