vājās tipizācijas izmantošana objektu transformēšanai · web vieworacle...
TRANSCRIPT
Objektu transformēšanas nepieciešamība
Datu bāzes sistēma
Datu bāze
Datu bāzes
vadības sistēma
SQL objekts
Lietojums
JDBC interfeiss
Java objekts
2
SQL objekta transformēšana programmas Java objektā
1. Vāji tipizētās Java klases (pēc noklusējuma) (weakly typed default Java class) Struct (Java) vai STRUCT (Oracle) izmantošana objekta transformēšanai. Šis variants ir efektīvāks un vienkāršāks.
2. Stipri tipizētas pašveidotās Java klases (strongly typed custom Java classe) izveidošana Oracle SQL objektam.
JDBC
Literatūra
1. R. M. Menon. Expert Oracle JDBC Programming. Apress, 2005, 744. Lpp.
2.Kuassi Mensah. Oracle Database programming using Java and Web Services. Elsevier Digital Press publications, 2006.
Programmas Java objekts
SQL objekts
Javas objekts SQL objektsSQLData interfeiss
Objektu attēlojumu (transformāciju) bibliotēka
JDBC
Struct (Java)STRUCT (Oracle)
3
Vājās tipizācijas izmantošana objektu transformēšanai
Klases java.sql.Struct izmantošana SQL un Java objekta savstarpējai transformēšanai
Struktūra:java.sql.Struct
Datu bāzes sistēma
ResultSet rs= stmt.executeQuery( "select Value(a) from TAB_1");java.sql.Struct jdbcStr = (java.sql.Struct)rs.getObject(1);
Struktūras java.sql.Struct metodes:1) getAttributes(map)2) get Attributes3) getSQLTypeName
Izveidošana
4
JDBC interfeiss java.sql.Struct un datu tipu transformācija
JDBC interfeiss java.sql.Struct objekts attēlo dažāda tipa datu bāzes objektus vispārējā veidā kā atribūtu kolekciju. Objekta atribūti tiek glabāti objekta masīvā kā Java objekti. Atribūta tips pēc noklusējuma tiek definēts šādi:
1) CHAR, VARCHAR, LONG oracle.sql.CHAR java.lang.String, java.sql.Date, java.sql.Time, java.sql.Timestamp, java.lang.Byte, java.lang.Short, java.lang.Integer, java.lang.Long, java.lang.Float, java.lang.Double, java.math.BigDecimal, byte, short,int,long, float, double
2) DATE oracle.sql.DATE, java.sql.Date, java.sql.Time, java.sql.Timestamp, java.lang.String
3) NUMBER oracle.sql.NUMBER, java.lang.Byte, java.lang.Short, java.lang.Integer, java.lang.Long, java.lang.Float, java.lang.Double, java.math.BigDecimal, byte, short,int,long, float,double
4) OPAQUE oracle.sql.OPAQUE 5) RAW, LONG RAW oracle.sql.RAW, byte[] 6) ROWID oracle.sql.CHAR, oracle.sql.ROWID,
java.lang.String 7) BFILE oracle.sql.BFILE8) BLOB oracle.sql.BLOB, java.sql.Blob9) CLOB oracle.sql.CLOB, java.sql.Clob
5
JDBC interfeiss java.sql.Struct un tā standarta metodes
1. getAttributes(map). This method retrieves the values of the attributes, using entries in the specified type map to determine the Java classes to use in materializing any attribute that is a structured object type. The Java types for other attribute values would be the same as for a getObject call on data of the underlying SQL type.Ja izmanto savu SQL objekta attēlojumu:public Object[] getAttributes(Map map) throws SQLException;
2. getAttributes. This method is the same as the preceding getAttributes(map) method, except it uses the default type map for the connection.Ja izmanto SQL objekta attēlojumu pēc noklusējuma:public Object[] getAttributes() throws SQLException;
3. getSQLTypeName. This method returns a Java String that represents the fully qualified name of the Oracle object type that this Struct represents.You can use standard JDBC functionality, such as getObject, to retrieve an Oracle object from the database as an instance of java.sql.Struct. Because getObject returns a java.lang.Object, you must cast the output of the method to Struct. Tiek iegūts Java String objekts ar SQL objekta tipa nosaukumu (schema.sql_type_name):public String getSQLTypeName() throws SQLException;
6
Klases oracle.sql.STRUCT izmantošana datu bāzes un Java objektu savstarpējai transformēšanai
java.lang.Object oracle.sql.Datum oracle.sql.DatumWithConnection oracle.sql.STRUCT
Atšķirībā no java.sql.Struct interfeisa, ko var izmantot tikai lai veiktu vaicājumus datu bāzei, oracle.sql.STRUCT klasi var izmantot arī, lai ievietotu un atjauninātu datus.
Tiek iegūti atribūti (atribūtu objektu masīvā) kā oracle.sql.* objekti:public oracle.sql.Datum[] getOracleAttributes() throws SQLException;
Tiek iegūts oracle.sql.StructDescriptor objekts SQL objekta tipam:public oracle.sql.StructDescriptor getDescriptor() throws SQLException;
oracle.sql.Datum[] attrs = oracleSTRUCT.getOracleAttributes();
oracle.sql.Datum[] attrs = ((oracle.sql.STRUCT)jdbcStruct).getOracleAttributes();
Object[] attrs = jdbcStruct.getAttributes();
Struktūra:oracle.sql.STRUCT Datu bāzes
sistēma
Struktūrasoracle.sql.STRUCT
metodes:1) getOracleAttributes2) getDescriptor3) getJavaSQLConnection4) toJdbc5) toJdbc(map)
Izveidošana
7
You can select data from the database into STRUCT objects and create STRUCT objects for inserting data into the database. STRUCT objects completely preserve data, because they maintain the data in SQL format. Using STRUCT objects is more efficient and more precise in situations where you do not need the information in an application specific form.If you want to take advantage of the extended functionality offered by Oracle-defined methods, then use an oracle.sql.STRUCT instance.The oracle.sql.STRUCT class implements the java.sql.Struct interface and provides extended functionality beyond the JDBC 2.0 standard.The STRUCT class includes the following methods in addition to standard Struct functionality:
1) getOracleAttributes. Retrieves the values of the values array as oracle.sql.* objects
2) getDescriptor. Returns the StructDescriptor object for the SQL type that corresponds to this STRUCT object.
3) getJavaSQLConnection. Returns the current connection instance.4) toJdbc. Consults the default type map of the connection to determine what
class to map to and, then, uses toClass.5) toJdbc(map). Consults the specified type map to determine what class to map
to, and then uses toClassIf you want to retrieve Oracle object attributes from a STRUCT or Struct instance as oracle.sql types, then use the getOracleAttributes method of the oracle.sql.STRUCT class, as follows:
oracle.sql.Datum[] attrs = oracleSTRUCT.getOracleAttributes();or:oracle.sql.Datum[] attrs = ((oracle.sql.STRUCT)jdbcStruct).getOracleAttributes();
If you want to retrieve Oracle object attributes as standard Java types from a STRUCT or Struct instance, use the standard getAttributes method:
Object[] attrs = jdbcStruct.getAttributes();
Note: Oracle JDBC drivers cache array and structure descriptors. This provides enormous performance benefits. However, it means that if you change the underlying type definition of a structure type in the database, the cached descriptor for that structure type will become stale and your application will receive a SQLException exception.
8
Oracle klase oracle.sql.STRUCT
java.lang.Object oracle.sql.Datum oracle.sql.DatumWithConnection oracle.sql.STRUCT
Atšķirībā no java.sql.Struct interfeisa, ko var izmantot tikai lai veiktu vaicājumus datu bāzei, oracle.sql.STRUCT klasi var izmantot arī, lai ievietotu un atjauninātu datus.
Tiek iegūti atribūti (atribūtu objektu masīvā) kā oracle.sql.* objekti:public oracle.sql.Datum[] getOracleAttributes() throws SQLException;
Tiek iegūts oracle.sql.StructDescriptor objekts SQL objekta tipam:public oracle.sql.StructDescriptor getDescriptor() throws SQLException;
9
The order of these attribute objects in the Object array is the same order in which they were specified at the time of the creation of the object type that they represent. For example, a Struct Java object that corresponds to the database person object type containing the attributes name and date_of_birth, in that order would be stored in an internal array of Object elements (i.e., an Object[] object) containing two elements:1) the first attribute would be a String object (since the database type varchar2 maps to a String object in Java, by default) that contains the value in the name attribute of the person object.2) the second attribute would be a java.sql.Timestamp object (since the database type date, by default, maps to a java.sql.Timestamp object in Java) that contains the value in the date_of_birth attribute of the person object.
Note that you may need to cast each of these attributes manually into an object of the appropriate data type in Java. For example, while manipulating the second element of the Object[] structure in the previous example (corresponding to the date_of_birth attribute), you may need to cast the second array element to the interface java.sql.Timestamp type in order to access any methods specific to the interface java.sql.Timestamp. Weakly typed Struct objects are useful in the following scenarios:1) if your program needs to work with an arbitrary object type in a generic fashion without really needing to materialize it as a custom class object. This may be true, for example, if you are building a utility that needs to deal with an object of an arbitrary object type in a generic fashion as a collection of attributes.2) if your end user application doesn’t need to do a lot of manipulation of objects in memory. If you need to do a lot of manipulation in memory, then it is much more intuitive to use strongly typed objects, where a custom class that has appropriate getter and setter methods for the object attributes represents the database object type.
Oracle implements the Struct interface as an object of type oracle.sql.STRUCT class which, in a typical fashion, implements the standard methods in the Struct interface and also adds Oracle extension methods1.
public interface Struct is the standard mapping in the Java programming language for an SQL structured type. A Struct object contains a value for each attribute of the SQL structured type that it represents. By default, an instance of Struct is valid as long as the application has a reference to it. All methods on the Struct interface must be fully implemented if the JDBC driver supports the data type.
String getSQLTypeName(); retrieves the SQL type name of the SQL structured type that this Struct object represents.
Object[] getAttributes(); produces the ordered values of the attributes of the SQL structured type that this Struct object represents. As individual attributes are processed, this method uses the type map associated with the connection for customizations of the type mappings. If there is no entry in the connection's type map that matches the structured type that an attribute represents, the driver uses the standard mapping. Conceptually, this method calls the method getObject on each attribute of the structured type and returns a Java array containing the result.
Object[] getAttributes(Map<String, Class<?>> map); produces the ordered values of the attributes of the SQL structured type that this Struct object represents. As individual attrbutes are proccessed, this method uses the given type map for customizations of the type mappings. If there is no entry in the given type map that matches the structured type that an attribute represents, the driver uses the standard mapping. This method never uses the type map associated with the connection. Conceptually, this method calls the method getObject on each attribute of the structured type and returns a Java array containing the result.
1 http://docs.oracle.com/cd/B28359_01/java.111/b31224/oraoot.htm
10
Oracle SQL objekta izgūšana izmantojot klasi STRUCT un interfeisu Struct2
create or replace type ADRESE_T as object(NUMURS number,IELA varchar2(20),PILSETA varchar(20));
create table DARBINIEKI (D_NUM number,D_UZV varchar2(30),D_ADRESE ADRESE_T);
insert into DARBINIEKI values (1, 'Koks', ADRESE_T(21, 'Avotu', 'Rīga'));insert into DARBINIEKI values (2, 'Celms', ADRESE_T(21, 'Avotu', 'Rīga'));insert into DARBINIEKI values (3, 'Sakne', ADRESE_T(5, 'Ozolu', 'Talsi'));
2 Database JDBC developer's guide. 13. Working with Oracle de.1 3.types. http://docs.oracle.com/cd/B28359_01/java.111/b31224/oraoot.htm
11
create or replace JAVA source named "Objekts" asimport java.sql.*; //JDBCimport java.io.*; // Ievade, izvadeimport oracle.jdbc.*; // Oracle JDBC (aizmaiņa)public class Objekts{ public static void main(String args[]) throws SQLException {try {// Savienojuma objekta izveidošana (pēc noklusējuma) Connection sav = DriverManager.getConnection("jdbc:default:connection:");//Komandas objekta izveidošana Statement kom = sav.createStatement();// Rezultātu objekta izveidošana, izpildāmās SELECT komandas // ievade un tās izpilde. ResultSet atbilde = kom.executeQuery( "select D_NUM, D_UZV, D_ADRESE from DARBINIEKI where D_NUM = 1"); atbilde.next(); //Pirmās rezultātu rindas iegūšana no atbildes masīva// Pirmo divu kolonu vērtību ieguve no rezultātu objekta. int num = atbilde.getInt(1); String uzv = atbilde.getString(2); System.out.println("Darbinieka numurs = " + num + " Uzvārds = " + uzv); kom.close(); } catch (SQLException e) {System.err.println(e.getMessage());} } }
create or replace procedure OBJEKTA_IZVADE as language JAVA name 'Objekts.main(java.lang.String[])';
beginOBJEKTA_IZVADE;end;
12
create or replace JAVA source named "Objekts" asimport java.sql.*; //JDBCimport java.io.*; // Ievade, izvadeimport oracle.jdbc.*; //Oracle JDBC (aizmaiņa)public class Objekts{ public static void ObjIzvade() throws SQLException {try {// Savienojuma objekta izveidošana (pēc noklusējuma) Connection sav = DriverManager.getConnection("jdbc:default:connection:");//Komandas objekta izveidošana Statement kom = sav.createStatement();// Rezultātu objekta izveidošana, izpildāmās SELECT komandas // ievade un tās izpilde. ResultSet atbilde = kom.executeQuery( "select D_NUM, D_UZV, D_ADRESE from DARBINIEKI" + " where D_NUM = 1"); atbilde.next(); //Pirmās rezultātu rindas iegūšana no atbildes masīva// Pirmo divu kolonu vērtību ieguve no rezultātu objekta. int num = atbilde.getInt(1); String uzv = atbilde.getString(2);System.out.println("Darbinieka numurs = " + num + " Uzvārds = " + uzv); kom.close(); } catch (SQLException e) {System.err.println(e.getMessage());} } }
create or replace procedure OBJEKTA_IZVADE as language JAVA name 'Objekts.ObjIzvade()';
beginOBJEKTA_IZVADE;end;
13
Pilnā transformācijas programma
create or replace JAVA source named "Objekts" asimport java.sql.*; //JDBCimport java.io.*; // Ievade, izvadeimport oracle.jdbc.*; //Oracle JDBC (aizmaiņa)import oracle.sql.STRUCT; import java.math.BigDecimal;public class Objekts{ public static void ObjIzvade() throws SQLException {try {// Savienojuma objekta izveidošana (pēc noklusējuma) Connection sav = DriverManager.getConnection("jdbc:default:connection:");//Komandas objekta izveidošana Statement kom = sav.createStatement();// Rezultātu objekta izveidošana, izpildāmās SELECT komandas // ievade un tās izpilde. ResultSet atbilde = kom.executeQuery( "select D_NUM, D_UZV, D_ADRESE from DARBINIEKI" + " where D_NUM = 1"); atbilde.next(); //Pirmās rezultātu rindas iegūšana no atbildes masīva// Pirmo divu kolonu vērtību ieguve no rezultātu objekta. int num = atbilde.getInt(1); String uzv = atbilde.getString(2);System.out.println("Darbinieka numurs = " + num + " Uzvārds = " + uzv); oracle.sql.STRUCT jdbcStruct = (oracle.sql.STRUCT) atbilde.getObject(3);Object[] d_adreseAttr = jdbcStruct.getAttributes();// Tiek izgūti atribūti pārveidoti vēlamajos Java tipos. int iel_num = ((BigDecimal) d_adreseAttr[0]).intValue(); // int iel_num = d_adreseAttr(0).getInt; nestrādā String iela = (String) d_adreseAttr[1]; String pilseta = (String) d_adreseAttr[2]; System.out.println("Ielas numurs: " + iel_num + " Iela: " + iela + " Pilsēta: " + pilseta); kom.close(); } catch (SQLException e) {System.err.println(e.getMessage());} } }
14
create or replace procedure OBJEKTA_IZVADE as language JAVA name 'Objekts.ObjIzvade()';
beginOBJEKTA_IZVADE;end;
15
Komandu apskats
// Trešajā kolonā glabājas objekts. Tas tiek izgūts kā struktūra.// 1. Oracle objekta izgūšanas variants (oracle.sql.STRUCT izmantošana).// No struktūras STRUCT objekta atribūti (lauki) tiek izgūti Object tipa// masīvā. Notiek Oracle SQL datu tipu transformācija Java datu tipos// varchar2, char String, number BigDecimal, date Dateoracle.sql.STRUCT oracleSTRUCT = (oracle.sql.STRUCT) atbilde.getObject(2);
// 2. Oracle objekta izgūšanas variants (oracle.sql.STRUCT izmantošana).oracle.sql.STRUCT oracleSTRUCT = ((OracleResultSet)atbilde).getStruct(2);
// 3. Oracle objekta izgūšanas variants (java.sql.Struct izmantošana).java.sql.Struct jdbcStruct = (java.sql.Struct) atbilde.getObject(2);
16
// 1. Oracle objekta atribūtu izgūšana kā oracle.sql tipus.
oracle.sql.Datum[] d_adreseAttr = oracleSTRUCT.getOracleAttributes();
// 2. Oracle objekta atribūtu izgūšana kā oracle.sql tipus.
oracle.sql.Datum[] d_adreseAttr = ((oracle.sql.STRUCT) jdbcStruct).getOracleAttributes();
// 3. Oracle objekta atribūtu izgūšana kā standarta Java tipus no STRUCT vai Struct instancēm.
Object[] d_adreseAttr = jdbcStruct.getAttributes();
// Tiek izgūti atribūti pārveidoti vēlamajos Java tipos. int iel_num = ((BigDecimal) d_adreseAttr[0]).intValue(); String iela = (String) d_adreseAttr[1]; String pilseta = (String) d_adreseAttr[2];
17
// Alternatīvs variants metodes getAttributes() izmantošanai ir // getOracleAttributes() metodes lietošana. Šajā gadījumā atribūtu tipi // atbilst Oracle JDBC datu tipiem (number, char). Turpinājumā šie // tipi tiek transformēti Java tipos. Šis ir racionālāks variants.
// Object d_adreseAttr[] = d_adreseStruct.getOracleAttributes();// int iel_num = ((NUMBER) elementAttr[0]).intValue();// String iela = ((CHAR) elementAttr[1]).toString();// String pilseta = ((CHAR) elementAttr[2]).toString();