Conectividad de Java con bases de datos -DYD'DWDEDVH&RQQHFWLYLW\ JDBC 1 JDBC • • • ¿Qué es JDBC? Cuatro tipos de drivers JDBC Uso de JDBC &RQW« 2 ¿Qué es JDBC? • JDBC es una interfaz que permite a un programa java ejecutar instrucciones SQL dentro de bases de datos relacionales. – Las bases de datos deben seguir el estandar ANSI SQL-92 3 JDBC en acción SURJUDPD -DYD GULYHU SDUD2UDFOH DB -'%& GULYHU SDUDP\VTO MGEFRGEF SXHQWH GULYHU RGEF DB DB 4 Cuatro tipos de drivers JDBC 7\SH, ³%ULGJH´ 2'%& 7\SH,, ³1DWLYH´ -'%& 2'%& 'ULYHU &/,OLE 0LGGOHZDUH 6HUYHU 7\SH,,, ³0LGGOHZDUH´ 7\SH,9 ³3XUH´ Cuatro tipos de drivers JDBC (Cont…) I. Puente JDBC-ODBC – traduce Java al API de ODBC &OLHQW 6HUYHU BD &OLHQW -DYD -'%& 2'%& ODBC 3URWRFRO ODBC 6HUYHU %' &RQWLQXHG 6 Cuatro tipos de drivers JDBC (Cont…) II. Native API - traduce Java al API de la base de datos &OLHQW 6HUYHU BD &OLHQW -DYD -'%& 1DWLYH $3, Native 3URWRFRO Native 6HUYHU %' 7 Cuatro tipos de drivers JDBC (Cont…) III. Middleware - Invoca un servidor intermedio generalmente ubicado en el mismo host de la base de datos. Utiliza un protocolo estándar independiente de la base de datos. &OLHQW 6HUYHU BD &OLHQW -DYD -'%& Standard 3URWRFRO middleware Native 6HUYHU 6HUYHU %' 8 Cuatro tipos de drivers JDBC (Cont…) IV. Net Protocol Genera el protocolo de comunicaciones de la base de datos &OLHQW 6HUYHU BD &OLHQW -DYD -'%& Native 3URWRFRO Native 6HUYHU %' 9 Drivers JDBC • Una lista de diversos drivers pueden ser encontrados (freeware, shareware, and commercial) en: http://developers.sun.com/product/jdbc/drivers 10 Algunos Drivers JDBC !"#$% &"#'(")*+,)(-./, ")*+,)(-./, $0%12 com.mysql.jdbc.Driver ".3.4.5,(6!2(78)/.39 jdbc:mysql://hostname/databaseName ")*+,)(-./,9 :).;<, oracle.jdbc.driver.OracleDriver ".3.4.5,(6!2(78)/.39 jdbc:oracle:thin@hostname:portnumber:databaseName ")*+,)(-./,9 "#= COM.ibm.db2.jdbc.net.DB2Driver ".3.4.5,(6!2(78)/.39 jdbc:db2:hostname:portnumber/databaseName ")*+,)(-./,9 >;;,55 sun.jdbc.odbc.JdbcOdbcDriver ".3.4.5,(6!2(78)/.39 jdbc:odbc:databaseName 11 Instalación del driver El driver se presenta como un archivo jar, por ejemplo para MySQL el driver se llama: mysql-connector-java-5.1.9-bin.jar El driver se instala en el directorio donde se tenga instalado el JDK, dentro de la carpeta: …/jre/lib/ext 12 Cargando el driver en Netbeans Si ya instalaron el driver en el JDK, dentro de la carpeta: …/jre/lib/ext Netbeans puede accesarlo ya que cargará todas las librerías del JDK 13 Usando el driver incluido en Netbeans Con el botón derecho en el folder “Libraries” seleccionar “Add Library” y después MySQL JDBC Driver Proyecto con la librería para MySQL incluida 14 Secuencia JDBC • Todos los programas JDBC hacen lo siguiente: – 1) Cargan el driver JDBC – 2) Especifican el nombre y ubicación de la base de datos utilizada – 3) Se conectan a la base de datos creando un objeto Connection &RQWLQXHG 15 Secuencia JDBC (Cont…) – 4) Crean un Statement object y ejecutan queries SQL – 5) Los resultados de un query se guardan en un objeto de tipo ResultSet, allí se pueden consultar – 6) Cerrar (close) los objetos ResultSet, Statement y Connection 16 Cargar el driver JDBC (Antes de JDBC 4.0) import java.sql.*; Class.forName("com.mysql.jdbc.Driver") Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver" ); El driver para ODBC viene incluido en la instalación básica de java. El driver para MySQL se puede obtener bajando el archivo mysql-connector-java-5.1.9-bin.jar de la página: www.mysql.com/products/connector/j/ e instalandolo en la carpeta jre/lib/ext de la instalación de java. 17 Conectar String url = "jdbc:odbc:Books"; String username = "anonymous"; String password = "guest"; connection = DriverManager.getConnection(url, username, password ); ODBC String url = "jdbc:mysql://localhost:3306/mysql"; Connection con = DriverManager.getConnection(url,"root", ""); MySQL Cuando se invoca el método getConnection, el DriverManager intenta localizar un driver apropiado entre los que se hayan cargado previamente y los que se puedan cargar usando el mismo classloader que la aplicación actual. 18 Algunos métodos de java.sql.Connection $?38@8 :4A,3*+8 %3.3,/,B3((;),.3,%3.3,/,B3 %3.3,/,B3((;),.3,%3.3,/,B3CD ;),.3,%3.3,/,B3CD !,E),5. FB(84A,38 @,<(3*G8 53.3,/,B3(HF, 5,)I F3*<*J.@8 G.). ,B+*.) %12(.(<.(4.5,(@,(@.385K ".3.4.5,$,3.".3. E,3$,3.".3.CD :43*,B, FB(84A,38 HF, ;8B3*,B, *B78)/.;*LB 584), <.(;8B7*EF).;*LB @,(<.(4.5,(@,(@.385K 488<,.B((*5'<85,@CD !,E),5. +,)@.@,)8 C3)F,D(5* <.(4.5,(@,(@.385 ,53I ;,)).@. +8*@(;8//*3CD M.;, G,)/.B,B3,5 38@85 <85(;./4*85 N,;N85 @,5GF,5 @,<(O<3*/8 ;8//*3P)8<<4.;QK +8*@()8<<4.;QCD ",5N.;, 38@85 <85(;./4*85 N,;N85 @,5GF?5 @,<( O<3*/8 ;8//*3P)8<<4.;QK 19 Algunos métodos de java.sql.Connection(Cont…) $?38@8 :4A,3*+8 +8*@(5,3>F38'8//*3(C488<,.B(0BD !,53.F).PHF*3. ,<(/8@8 .F38R;8//*3S(,53, /8@8 ,7,;3O. FB(;8//*3(.F38/I3*;8 @,5GF?5 @,(;.@. ;8/.B@8 %12K((T2(+.<8)(G8) @,7.F<3(@,( >F38'8//*3 ,5 8BK +8*@(;<85,CD '*,)). <.(;8B,U*LBK 20 Statement • Un objeto de tipo Statement se obtiene invocando el método ;),.3,%3.3,/,B3CD @, FB 84A,38 '8BB,;3*8B. • Permite enviar comandos SQL a la base de datos. Ejemplos: Statement myStmt = connection.createStatement(); ResultSet myResult; myResult=myStmt.executeQuery(“SELECT * FROM bikes;”); Statement myStmt = connection.createStatement(); myStmt.executeUpdate(“UPDATE Authors SET firstName=‘Joe’ WHERE firstName=‘Tem’ ”); 21 Prepared Statement Los Prepared Statements se utilizan para consultas que se ejecutan muchas veces El DBMS las compila una sola vez En lugar de datos, se utiliza el signo de interrogación ‘?’ como marcador. Los datos se agregan despues de la compilación. Los marcadores ‘?’ deben ser sustituidos por datos concretos antes de ejecutar losPrepared Statements. 22 Prepared Statement String queryStr = "SELECT * FROM Items " + "WHERE Name = ? and Cost < ?"; PreparedStatement pstmt = con.prepareStatement(queryStr); pstmt.setString(1, "shirt"); pstmt.setInt(2, 1000); ResultSet rs = pstmt.executeQuery(); 23 ResultSet • Un objeto ResultSet es similar a un arreglo de dos dimensiones. Cada llamada a next() apunta al siguiente registro en el result set. • Se debe llamar al método next() antes de poder ver el primer registro, y el método regresará el valor de false cuando ya no hay mas registros. Esta propiedad se utiliza generalmente para controlar un while loop. • El ResultSet tiene métodos de acceso en lectura getInt(), getLong(), getString() etc., para todos los tipos de datos java que equivalen a los tipos SQL, se requiere especificar el nombre ó número de órden (empezando en 1, 2, 3, etc.) de la columna que se va a leer. 24 SQL Java Type Method BIT boolean getBoolean() TINYINT byte getByte() SMALLINT short getShort() INTEGER int getInt() BIGINT long getLong() REAL float getFloat() FLOAT double getDouble() DOUBLE double getDouble() DECIMAL java.math.BigDecimal getBigDecimal() NUMERIC java.sql.Numeric getNumeric() CHAR String getString() VARCHAR String getString() LONGVARCHAR InputStream getAsciiStream() getUnicodeStream() BINARY byte[] getBytes() LONGVARBINARY InputStream getBinaryStream() DATE java.sql.Date getDate() TIME java.sql.Time getTime() TIMESTAMP java.sql.Timestamp getTimestamp() 25 ResultSetMetadata Es un objeto que puede ser utilizado para obtener información sobre los tipos de datos y propiedades de las columnas de un objeto ResultSet. ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM TABLE"); ResultSetMetaData rsmd = rs.getMetaData(); int numberOfColumns = rsmd.getColumnCount(); String name1 = rsmd.getColumnName(1); 26 Executing SQL Commands Statement MyStmt = connection.createStatement(); int x = MyStmt.executeUpdate ("INSERT INTO Sells “ + “VALUES ('Bar Of Foo', 'BudLite', 2.00)" ); REGRESA: el número de registros afectados si se hizo un INSERT, UPDATE or DELETE, regresa 0 en caso de comandos SQL que no regresan nada ResultSet rs = MyStmt.executeQuery ("SELECT * FROM Sells"); 27 Ejemplos JDBC Statement MyStmt = con.createStatement(); Strings SQL usan MyStm.executeUpdate("CREATE TABLE Sells " + "(bar VARCHAR(40), comillas simples '' beer VARCHAR(40), price REAL)" ); MyStm.executeUpdate("INSERT INTO Sells " + "VALUES ('Bar Of Foo', 'BudLite', 2.00)" ); String sqlString = "CREATE TABLE Bars " + "(name VARCHAR(40), address VARCHAR(80), license INT)" ; MyStm.executeUpdate(sqlString); Ponga especial atención al espacio en blanco que sigue después de "INSERT INTO Sells " evita que este string se pegue a "VALUES". 28 Ejemplos JDBC Statement stmt = con.createStatement(); String bar, beer ; float price ; ResultSet rs = stmt.executeQuery("SELECT * FROM Sells"); while ( rs.next() ) { bar = rs.getString("bar"); beer = rs.getString("beer"); Mueve el cursor hacia el próximo registro. El cursor está posicionado inicialmente antes del primer registro price = rs.getFloat("price"); System.out.println(bar + " sells " + beer + " for " + price + " Dollars."); } 29 Registrando la base de datos con ODBC Este dialogo es utilizado para registrar nuestra B.D. Debemos asegurarnos que User DSN esta seleccionado, y entonces hacer click sobre el boton Add. Para 64 bits: Entrar en C:\Windows\SysWOW64 Click derecho en odbcad32.exe -> Ejecutar como administrador y ya se puede agregar accdb 30 Registrando la base de datos con ODBC Ya que estamos utilizando Microsoft Access, seleccionaremos Microsoft Access Driver y daremos click en Finish. 31 Registrando la base de datos con ODBC En este dialogo capturaremos el nombre (Books) que utilizaremos para referenciarnos a la base de datos con JDBC. Después seleccionar el botón Advanced.. Para capturar los campos de nombre de usuario y password para acceder a la base de datos. 32 Registrando la base de datos con ODBC 33 Registrando la base de datos con ODBC Books Note que el diálogo del Administrador de fuente de datos ODBC, contiene ahora la fuente Books, con lo cual estamos listos para accesar a los datos a través del puente driver JDBC-ODBC. 34 Conexión con una base de datos mediante ODBC import java.sql.*; import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.*; public class TableDisplay extends JFrame { private Connection connection; private JTable table; 35 Conexión con una base de datos public TableDisplay() { // The URL specifying the Books database to which // this program connects using JDBC to connect to a // Microsoft ODBC database. String url = "jdbc:odbc:Books"; String username = "anonymous"; String password = "guest"; // Load the driver to allow connection to the database try { Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver" ); connection = DriverManager.getConnection( url, username, password ); } 36 Conexión con una base de datos catch ( ClassNotFoundException cnfex ) { System.err.println( "Failed to load JDBC/ODBC driver." ); cnfex.printStackTrace(); System.exit( 1 ); // terminate program } catch ( SQLException sqlex ) { System.err.println( "Unable to connect" ); sqlex.printStackTrace(); } getTable(); setSize( 450, 150 ); show(); } 37 Conexión con una base de datos private void getTable() { Statement statement; ResultSet resultSet; try { String query = "SELECT * FROM Authors"; statement = connection.createStatement(); resultSet = statement.executeQuery( query ); displayResultSet( resultSet ); statement.close(); } catch ( SQLException sqlex ) { sqlex.printStackTrace(); } } 38 Conexión con una base de datos private void displayResultSet( ResultSet rs ) throws SQLException { // position to first record boolean moreRecords = rs.next(); // If there are no records, display a message if ( ! moreRecords ) { JOptionPane.showMessageDialog( this, "ResultSet contained no records" ); setTitle( "No records to display" ); return; } setTitle( "Authors table from Books" ); Vector columnHeads = new Vector(); Vector rows = new Vector(); 39 Conexión con una base de datos try { // get column heads ResultSetMetaData rsmd = rs.getMetaData(); for ( int i = 1; i <= rsmd.getColumnCount(); ++i ) columnHeads.addElement( rsmd.getColumnName( i ) ); // get row data do { rows.addElement( getNextRow( rs, rsmd ) ); } while ( rs.next() ); // display table with ResultSet contents table = new JTable( rows, columnHeads ); JScrollPane scroller = new JScrollPane( table ); getContentPane().add( scroller, BorderLayout.CENTER ); validate(); } 40 Conexión con una base de datos catch ( SQLException sqlex ) { sqlex.printStackTrace(); } } 41 Conexión con una base de datos private Vector getNextRow( ResultSet rs, ResultSetMetaData rsmd ) throws SQLException { Vector currentRow = new Vector(); for ( int i = 1; i <= rsmd.getColumnCount(); ++i ) switch( rsmd.getColumnType( i ) ) { case Types.VARCHAR: currentRow.addElement( rs.getString( i ) ); break; case Types.INTEGER: currentRow.addElement(new Long( rs.getLong( i ) ) ); break; default: System.out.println( "Type was: " + rsmd.getColumnTypeName( i ) ); } return currentRow; } 42 Conexión con una base de datos public void shutDown() { try { connection.close(); } catch ( SQLException sqlex ) { System.err.println( "Unable to disconnect" ); sqlex.printStackTrace(); } } 43 Conexión con una base de datos public static void main( String args[] ) { final TableDisplay app = new TableDisplay(); app.addWindowListener( new WindowAdapter() { public void windowClosing( WindowEvent e ) { app.shutDown(); System.exit( 0 ); } } ); } } 44 Salida del programa 45 Conexión con una base de datos MySQL import java.sql.*; import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.*; public class TableDisplay extends JFrame { private Connection connection; private JTable table; 46 Conexión con una base de datos MySQL public TableDisplay() { String username = "anonymous"; String password = "guest"; // Load the driver to allow connection to the database try { Class.forName( "com.mysql.jdbc.Driver" ); connection = DriverManager.getConnection( "jdbc:mysql://localhost/Books”,”usuario”, “password”); } El resto del programa no cambia, es idéntico al de ODBC 47