8. Programación para bases de datos

8.1 Conceptos Generales

Todo DBMS que se digne tener calidad debe proveer una manera de comunicarse con él.

8.1.1 Introducción

Por qué hacer programas que interactúen con nuestras bases de datos ???

Customizar la entrada de datos

  • Interfaces X, Tcl/Tk, Web
  • Formatos Fechas, Precisión

Customizar la salida de datos

  • Encabezados
  • Formatos Fechas, Precisión
  • Eliminar Duplicidad, NULL

Trabajar alrededor de las limitantes inherentes de SQL

  • No todo es posible en SQL
  • Estructuras de Datos sofisticadas

Integración en alguna aplicación

  • Investigación: Graficación, Inteligencia Artificial, etc.
  • Industria: Directorios, Bibliotecas, etc etc etc

 

8.1.2 API's (Application Programming Interface)


Surgen para facilitar el desarrollo de aplicaciones

C
Por lo general y debido a la trascendencia de este lenguaje todos los DBMS proveen un API en este lenguaje
C++
Basados en el paradigma orientado a objetos y siguiendo el lenguaje de Stroustrup
DBI (Database Interface)
API basado en el lenguaje de scripting Perl y usando un DBD (Database Driver)
PHP (Hypertext Preprocessor)
Embedded scripts en paginas web
Java (JDBC Driver)
Ventaja de multiplataformidad para los programas clientes
 

Qué API debo utilizar ??

Aspectos a considerar:

  • Ambiente de ejecución:
    contexto

  • Performance:
    eficiencia y desempeño; compilados vs interpretados.

  • Facilidad de Desarrollo:
    tiempo de entrega, modularidad, mantenimiento.

  • Portabilidad:
    plataforma, dbms


 

8.1.3 Interactuando con el DBMS

Actividades a realizar
 

Crear Conexión

            Abrir Conexión
            (Openconnection)

                    Iniciar Transacción
                    (Begin Transaction)

                       Queries...
                        (Insert, Select, Update, Delete...)

                        -Error
                             (Abort Transaction)

                       Procesar resultados
                        (Print,   a= ,   b= )

                  Asegurar Transacción
                    (End Transaction)

        Cerrar Conexión
        (Closeconnection)


Error Handling

Es muy importante manejar los errores:

1) Mantener informado al usuario
2) Poder recuperarse de ellos

 

Causas de errores

1) Errores de sintáxis en expresiones de queries
2) Problemas de privilegios en determinadas tablas o bases de datos
3) Caídas del DBMS: luz, espacio en disco, NFS.

8.1.4 Terminología

Conexión: Línea de comunicación entre nuestro programa y el dbms 
Result Set:

Resultados de un querie (select)a la base de datos, se compone de renglones (rows).

 

valor valor valor
valor valor valor
valor valor valor
valor valor valor

Nota:

Queries que no involucren resultsets devuelven un número entero asociado a las tuplas afectadas

Row:

Un renglón (tupla) obtenidas de un query y que a su vez contiene las distintas columnas (valores atributos) de dicha operación.

valor valor valor

 

Result Set MetaData:

Metadatos de un result set (nombres de atributos, tipos de datos)

Atrib1, Tipo Atrib2, Tipo Atrib3, Tipo

 

Transacción:

Unidad de programa que accede y posiblemente actualiza varios elementos de información

 

 

 


8.2 Java Database Connectivity (JDBC)

8.2.1 Arquitectura

8.2.2 Versiones

  • JDBC 1: soporte para SQL 2.
  • JDBC 2: soporte para SQL 2, adición de blobs y clobs
  • JDBC 3: soporte para SQL 3

8.2.3 Tipos de Drivers:

Tipo

Características

Puro Java

1

Basados en Tecnología Bridge
JDBC-ODBC Bridge

No

2

Native Client API (C o C++)

No

3

JDBC-Net (Middleware)

Yes

4

Native Protocol

Yes

 Vendedores:

           - Actualmente la mayoría de los DBMS proveen sus drivers
           - El más popular entre los vendedores comerciales era WebLogic
 

Información necesaria para inicializar un Driver


MySQL

server

scanner.udlap.mx

port

9096

driver

org.gjt.mm.mysql.Driver,com.mysql.jdbc.Driver

url 

jdbc:mysql

database

prueba

username

carlos

password

lolo

  Informix

server

ict3.udlap.mx

port

1526

driver

com.informix.jdbc.IfxDriver

url 

jdbc:informix-sqli

database

uva:INFORMIXSERVER=ict3

username

carlos

password

xlolo

URL=  url  ://  server : port / database


   Access

server

null

port

null (librerias como JUDBC utilizan 0 para este tipo de puerto)

driver

SUN sun.jdbc.odbc.JdbcOdbcDriver
Microsoft com.ms.jdbc.odbc.JdbcOdbcDriver

url 

jdbc:odbc

database

uva

username

null

password

null

URL = url : database


8.2.4 Clases principales para conexiones con la base de datos
 

Driver Manager: Busca el JDBC driver correspondiente
Connection: Clase de mas alto nivel , la cual interactúa con el DBMS
DatabaseMetaData: Información acerca de los metadatos relacionados
con una conexión
PreparedStatement: Se utiliza para queries "preparados" . principalmente aquellos que
ocurren repetidamente, o aquellos que no se pueden representar directamente en una línea
de SQL,
            String sql= "insert into table imagenes values (?,?,?,?);"
 
Statement : ejecuta queries a través de la conexión
ResultSet:  resultados de un query.
ResultSetMetaData: información acerca de los resultados de un query, pero no de los resultados en si.
 

8.2.5 Ejemplos

Ejemplo de una aplicacion en JDBC

//Inserción de una tupla

// Teniendo la tabla users(id int, name char(255))

   1:import java.sql.*;
   2:
   3:class Insert{
   4:        public static void main (String argv[ ]) {
   5:                Connection con=null;
   6:                try {
   7:
   8:                        // Busca el driver para el tipo de DBMS en cuestion
   9:                        Class.forName("com.mysql.jdbc.Driver");
  10:
  11:                        //definiendo url de conexion con la base de datos
  12:                        String url="jdbc:mysql://localhost:9096/prueba";
  13:
  14:                        //Abriendo conexion
  15:                        con= DriverManager.getConnection(url, "carlos","lolo");
  16:
  17:
  18:                        con.setAutoCommit(false);
  19:
  20:                        // crear enunciado
  21:                        Statement stmt = con.createStatement();
  22:
  23:
  24:
  25:                        //ejecutar query
  26:                        int inserted = stmt.executeUpdate("insert into users values (56,'juan perez');");
  27:
  28:                        con.commit();
  29:
  30:                        // Ciclo para recorrer los resultados
  31:                        System.out.println("Inserted:"+inserted);
  32:                        //cerrando el statement
  33:                        stmt.close( );
  34:
  35:                        //cerrando conexion
  36:                        con.close( );
  37:                }
  38:                catch( Exception e) {
  39:                        e.printStackTrace( );
  40:
  41:                        try
  42:
  43:                        {
  44:
  45:                                con.rollback();
  46:
  47:                                con.close();
  48:
  49:                        }catch(Exception e2){}
  50:
  51:                }
  52:        }
  53:}

 

 

//Selección de tuplas

// Teniendo la tabla users(id int, name char(255))

 

   1:import java.sql.*;
   2:
   3:class Select {
   4:        public static void main (String argv[ ]) {
   5:
   6:                Connection con=null;
   7:                try {
   8:
   9:                        // Busca el driver para el tipo de DBMS en cuestion
  10:                        Class.forName("com.mysql.jdbc.Driver");
  11:
  12:                        //definiendo url de conexion con la base de datos
  13:                        String url="jdbc:mysql://localhost:9096/prueba";
  14:
  15:                        //Abriendo conexion
  16:                        con = DriverManager.getConnection(url, "carlos","lolo");
  17:
  18:
  19:                        // crear enunciado
  20:
  21:
  22:                        Statement stmt = con.createStatement();
  23:
  24:                        // Teniendo la tabla users(id int, name char(255))
  25:
  26:                        //ejecutar query
  27:                        ResultSet rs = stmt.executeQuery ("select  *  from users;");
  28:
  29:                        // Ciclo para recorrer los resultados
  30:                        System.out.println("Got results:");
  31:                        while (rs.next( ))  {
  32:
  33:                                int ID= rs.getInt(1);
  34:                                String Name= rs.getString(2);
  35:                                System.out.print(ID +" "+ Name );
  36:                                System.out.print("\n");
  37:
  38:                        }
  39:                        //cerrando el statement
  40:                        stmt.close( );
  41:
  42:                        //cerrando conexion
  43:                        con.close( );
  44:                }
  45:                catch( Exception e) {
  46:                        e.printStackTrace( );
  47:
  48:                }
  49:        }
  50:}

 

 

 

 

setenv CLASSPATH ${CLASSPATH}:$HOME/mysql-connector-java-3.0.9-stable-bin.jar

%>  javac Select.java
%> java Select
Got results:
1 carlos
2 alfredo
%>
 


 

Ejemplo de una aplicacion en JDBC usando PreparedStatements

//Inserción y Selección de una tupla

// Teniendo la tabla datafiles(id int, description varchar(255), category int, files blob)
// blob ~ byte

   1:import java.sql.*;
   2:import java.io.*;
   3:
   4:class BlobSample{
   5:        public static void main (String argv[ ]) {
   6:
   7:                Connection con=null;
   8:                try {
   9:
  10:                        // Busca el driver para el tipo de DBMS en cuestion
  11:                        Class.forName("com.mysql.jdbc.Driver");
  12:
  13:                        //definiendo url de conexion con la base de datos
  14:                        String url="jdbc:mysql://localhost:9096/prueba";
  15:
  16:                        //Abriendo conexion
  17:                        con = DriverManager.getConnection(url, "carlos","lolo");
  18:
  19:
  20:
  21:
  22:                        //ejecutar query
  23:                        // Teniendo la tabla datafiles(id int, description varchar(255), category int, files blob)
  24:                        // blob ~ byte
  25:                        String sql = "insert into datafiles values(?,?,?,?);";
  26:
  27:
  28:                        // crear enunciado
  29:                        PreparedStatement ps = con.prepareStatement(sql);
  30:
  31:                        ps.setInt(1, 34);
  32:                        ps.setString(2,"rock");
  33:                        ps.setString(3,"music");
  34:                        FileInputStream fis = null;
  35:                        int fileLength = Integer.MIN_VALUE;
  36:
  37:                        try
  38:                        {
  39:                                File file=new File("/home/digital/biblio_news.txt");
  40:                                fis = new FileInputStream(file);
  41:                                fileLength= (int)  file.length();
  42:                                ps.setBinaryStream(4, fis, fileLength);
  43:                        }
  44:                        catch(FileNotFoundException fnfe)
  45:                        { fnfe.printStackTrace();}
  46:
  47:
  48:
  49:                        ps.executeUpdate();
  50:                        //--------------------------------------
  51:                        //recuperamos esa informacion
  52:
  53:                        // crear enunciado
  54:                        Statement stmt = con.createStatement();
  55:
  56:                        //ejecutar query
  57:                        ResultSet rs = stmt.executeQuery ("select  *  from datafiles;");
  58:                        // Ciclo para recorrer los resultados
  59:                        System.out.println("Got results:");
  60:                        while (rs.next( ))  {
  61:
  62:                                InputStream  is= rs.getBinaryStream("files");
  63:                                ByteArrayOutputStream baos=new ByteArrayOutputStream();
  64:                                int abyte;
  65:                                while(true)
  66:                                {
  67:                                        try
  68:                                        {
  69:                                                abyte=is.read();
  70:                                                if (abyte== -1)
  71:                                                        break;
  72:
  73:                                                baos.write(abyte);
  74:                                        }
  75:                                        catch(Exception e1)
  76:                                        {  break;     }
  77:                                }//while
  78:
  79:                                System.out.println(new String(baos.toByteArray()));
  80:
  81:                        }
  82:                        //cerrando el statement
  83:                        stmt.close( );
  84:
  85:                        //cerrando conexion
  86:                        con.close( );
  87:                }
  88:                catch( Exception e) {
  89:                        e.printStackTrace( );
  90:
  91:                }
  92:        }
  93:}

 

 

 

8.3 Patterns

Usualmente la programación para bases de datos consiste de varios objetos que son parte de patrones (patterns) bien conocidos, tomando en cuenta las 3 capas de toda aplicación (presentation, business e integration), como son los DTO's (Data Transfer Objects) y los DAO's (Data Access Objects), de manera que el DTO se ubica en la capa de negocio y contiene toda la informacion de los objetos a salvarse en la base datos y el DAO asociado se encuentra en la capa de integración y realiza todas las operaciones de persistencia de dicho objeto.

Más información de estos patrones se puede encontrar en:

http://www.corej2eepatterns.com/Patterns2ndEd/index.htm