1 JDBC JDBC Qu es JDBC? Cuatro tipos de drivers JDBC Uso de JDBC 2 Uso de JDBC &RQW Qu es JDBC? JDBC es una interfaz que permite a un programa java ejecutar instrucciones SQL dentro de bases de datos relacionales. 3 Las bases de datos deben seguir el estandar ANSI SQL-92 JDBC en accin programa Java JDBC driver para Oracle DB 4 JDBC driver para mysql jdbc-odbc puente driver odbc DB DB Cuatro tipos de drivers JDBC JDBC Type I 'Bridge Type II ODBC ODBC Driver CLI (.lib) JDBC 'Native Type III 'Middleware Type IV 'Pure CLI (.lib) Middleware Server Cuatro tipos de drivers JDBC (Cont) I. Puente JDBC-ODBC traduce Java al API de ODBC &OLHQW 6HUYHU 6 &RQWLQXHG &OLHQW 6HUYHU BD Client Java JDBC ODBC ODBC Server BD ODBC Protocol Cuatro tipos de drivers JDBC (Cont) II. Native API - traduce Java al API de la base de datos &OLHQW 6HUYHU 7 &OLHQW 6HUYHU BD Client Java JDBC Native API Native Server BD Native Protocol 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 estndar independiente de la base de datos. 8 &OLHQW 6HUYHU BD Client Java JDBC Native Server BD Standard Protocol middleware Server Cuatro tipos de drivers JDBC (Cont) IV. Net Protocol Genera el protocolo de comunicaciones de la base de datos &OLHQW 6HUYHU 9 &OLHQW 6HUYHU Native Server BD Native Protocol BD Client Java JDBC Drivers JDBC Una lista de diversos drivers pueden ser encontrados (freeware, shareware, and commercial) en: 10 http://developers.sun.com/product/jdbc/drivers Algunos Drivers JDBC RDBMS JDBC Driver Name MySQL Driver Name com.mysql.jdbc.Driver Database URL format: jdbc:mysql://hostname/databaseName Oracle Driver Name: oracle.jdbc.driver.OracleDriver Database URL format: 11 jdbc:oracle:thin@hostname:portnumber:databaseName DB2 Driver Name: COM.ibm.db2.jdbc.net.DB2Driver Database URL format: jdbc:db2:hostname:portnumber/databaseName Access Driver Name: sun.jdbc.odbc.JdbcOdbcDriver Database URL format: jdbc:odbc:databaseName Instalacin 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 12 El driver se instala en el directorio donde se tenga instalado el JDK, dentro de la carpeta: /jre/lib/ext Cargando el driver en Netbeans Si ya instalaron el driver en el JDK, dentro de la carpeta: /jre/lib/ext 13 /jre/lib/ext Netbeans puede accesarlo ya que cargar todas las libreras del JDK Usando el driver incluido en Netbeans 14 Proyecto con la librera para MySQL incluida Con el botn derecho en el folder Libraries seleccionar Add Library y despus MySQL JDBC Driver Secuencia JDBC Todos los programas JDBC hacen lo siguiente: 1) Cargan el driver JDBC 2) Especifican el nombre y ubicacin de la base de datos utilizada 15 datos utilizada 3) Se conectan a la base de datos creando un objeto Connection &RQWLQXHG 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 Secuencia JDBC (Cont) 16 objeto de tipo ResultSet, all se pueden consultar 6) Cerrar (close) los objetos ResultSet, Statement y Connection Cargar el driver JDBC (Antes de JDBC 4.0) Class.forName("com.mysql.jdbc.Driver") Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver" ); import java.sql.*; 17 El driver para ODBC viene incluido en la instalacin bsica de java. El driver para MySQL se puede obtener bajando el archivo mysql-connector-java-5.1.9-bin.jar de la pgina: www.mysql.com/products/connector/j/ e instalandolo en la carpeta jre/lib/ext de la instalacin de java. Conectar String url = "jdbc:odbc:Books"; String username = "anonymous"; String password = "guest"; connection = DriverManager.getConnection(url, username, password ); String url = "jdbc:mysql://localhost:3306/mysql"; Connection con = DriverManager.getConnection(url,"root", ""); ODBC MySQL 18 Cuando se invoca el mtodo 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 aplicacin actual. Connection con = DriverManager.getConnection(url,"root", ""); MySQL Algunos mtodos de java.sql.Connection Mtodo Mtodo Mtodo Mtodo Objetivo Objetivo Objetivo Objetivo Statement Statement Statement Statement createStatement createStatement createStatement createStatement() () () () Regresa un objeto del tipo statement que ser utilizado para enviar SQL a la base de datos. DatabaseMetaData getMetaData() Obtiene un objeto que contiene informacin sobre la configuracin de la base de datos. boolean isClosed() Regresa verdadero (true) si la base de datos est cerrada 19 cerrada void commit() Hace permanentes todos los cambios hechos despues del ltimo commit/rollback. void rollback() Deshace todos los cambios hechos despus del ltimo commit/rollback. Algunos mtodos de java.sql.Connection(Cont) Mtodo Mtodo Mtodo Mtodo Objetivo Objetivo Objetivo Objetivo void setAutoCommit (boolean yn) Restaura/quita el modo auto-commit, este modo efecta un commit automtico despus de cada comando SQL. EL valor por default de AutoCommit es on. 20 void close() Cierra la conexin. Statement Un objeto de tipo Statement se obtiene invocando el mtodo createStatement() de un objeto Connection. Permite enviar comandos SQL a la base de datos. Ejemplos: Statement myStmt = connection.createStatement(); ResultSet myResult; 21 myResult=myStmt.executeQuery(SELECT * FROM bikes;); Statement myStmt = connection.createStatement(); myStmt.executeUpdate(UPDATE Authors SET firstName=Joe WHERE firstName=Tem ); Prepared Statement Los Prepared Statements se utilizan para consultas que se ejecutan muchas veces El DBMS las compila una sola vez 22 En lugar de datos, se utiliza el signo de interrogacin ? como marcador. Los datos se agregan despues de la compilacin. Los marcadores ? deben ser sustituidos por datos concretos antes de ejecutar losPrepared Statements. Prepared Statement String queryStr = "SELECT * FROM Items " + "WHERE Name = ? and Cost < ?"; 23 PreparedStatement pstmt = con.prepareStatement(queryStr); pstmt.setString(1, "shirt"); pstmt.setInt(2, 1000); ResultSet rs = pstmt.executeQuery(); 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 mtodo next() antes de poder ver el primer registro, y el mtodo regresar el valor de false cuando ya no hay mas registros. Esta propiedad se utiliza generalmente para controlar un while loop. 24 propiedad se utiliza generalmente para controlar un while loop. El ResultSet tiene mtodos 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 nmero de rden (empezando en 1, 2, 3, etc.) de la columna que se va a leer. 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() 25 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() ResultSetMetadata ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM TABLE"); Es un objeto que puede ser utilizado para obtener informacin sobre los tipos de datos y propiedades de las columnas de un objeto ResultSet. 26 ResultSetMetaData rsmd = rs.getMetaData(); int numberOfColumns = rsmd.getColumnCount(); String name1 = rsmd.getColumnName(1); Executing SQL Commands int x = MyStmt.executeUpdate ("INSERT INTO Sells + VALUES ('Bar Of Foo', 'BudLite', 2.00)" ); REGRESA: el nmero de registros afectados si se hizo un INSERT, Statement MyStmt = connection.createStatement(); 27 REGRESA: el nmero 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"); Ejemplos JDBC Statement MyStmt = con.createStatement(); MyStm.executeUpdate("CREATE TABLE Sells " + "(bar VARCHAR(40), beer VARCHAR(40), price REAL)" ); MyStm.executeUpdate("INSERT INTO Sells " + "VALUES ('Bar Of Foo', 'BudLite', 2.00)" ); Strings SQL usan comillas simples '' 28 String sqlString = "CREATE TABLE Bars " + "(name VARCHAR(40), address VARCHAR(80), license INT)" ; MyStm.executeUpdate(sqlString); Ponga especial atencin al espacio en blanco que sigue despus de "INSERT INTO Sells " evita que este string se pegue a "VALUES". Ejemplos JDBC Statement stmt = con.createStatement(); String bar, beer ; float price ; ResultSet rs = stmt.executeQuery("SELECT * FROM Sells"); 29 ResultSet rs = stmt.executeQuery("SELECT * FROM Sells"); while ( rs.next() ) { bar = rs.getString("bar"); beer = rs.getString("beer"); price = rs.getFloat("price"); System.out.println(bar + " sells " + beer + " for " + price + " Dollars."); } Mueve el cursor hacia el prximo registro. El cursor est posicionado inicialmente antes del primer registro Registrando la base de datos con ODBC Este dialogo es utilizado para registrar nuestra B.D. Debemos asegurarnos que User DSN esta 30 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 Registrando la base de datos con ODBC Ya que estamos utilizando Microsoft Access, seleccionaremos 31 seleccionaremos Microsoft Access Driver y daremos click en Finish. Registrando la base de datos con ODBC En este dialogo capturaremos el nombre (Books) que utilizaremos para referenciarnos a la base de 32 para referenciarnos a la base de datos con JDBC. Despus seleccionar el botn Advanced.. Para capturar los campos de nombre de usuario y password para acceder a la base de datos. Registrando la base de datos con ODBC 33 Registrando la base de datos con ODBC Note que el dilogo del Administrador de fuente de datos ODBC, contiene 34 de fuente de datos ODBC, contiene ahora la fuente Books, con lo cual estamos listos para accesar a los datos a travs del puente driver JDBC-ODBC. Books Conexin con una base de datos mediante ODBC import java.sql.*; import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.*; 35 public class TableDisplay extends JFrame { private Connection connection; private JTable table; Conexin 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"; 36 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 ); } Conexin con una base de datos catch ( ClassNotFoundException cnfex ) { System.err.println( "Failed to load JDBC/ODBC driver." ); cnfex.printStackTrace(); System.exit( 1 ); // terminate program } 37 catch ( SQLException sqlex ) { System.err.println( "Unable to connect" ); sqlex.printStackTrace(); } getTable(); setSize( 450, 150 ); show(); } Conexin con una base de datos private void getTable() { Statement statement; ResultSet resultSet; try { 38 try { String query = "SELECT * FROM Authors"; statement = connection.createStatement(); resultSet = statement.executeQuery( query ); displayResultSet( resultSet ); statement.close(); } catch ( SQLException sqlex ) { sqlex.printStackTrace(); } } Conexin 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 ) { 39 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(); Conexin 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 { 40 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(); } Conexin con una base de datos catch ( SQLException sqlex ) { sqlex.printStackTrace(); } } 41 Conexin 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 ) ); 42 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; } Conexin con una base de datos public void shutDown() { try { connection.close(); } catch ( SQLException sqlex ) { 43 catch ( SQLException sqlex ) { System.err.println( "Unable to disconnect" ); sqlex.printStackTrace(); } } Conexin con una base de datos public static void main( String args[] ) { final TableDisplay app = new TableDisplay(); app.addWindowListener( 44 app.addWindowListener( new WindowAdapter() { public void windowClosing( WindowEvent e ) { app.shutDown(); System.exit( 0 ); } } ); } } Salida del programa 45 Conexin con una base de datos MySQL import java.sql.*; import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.*; 46 public class TableDisplay extends JFrame { private Connection connection; private JTable table; Conexin con una base de datos MySQL public TableDisplay() { String username = "anonymous"; String password = "guest"; // Load the driver to allow connection to the database try { 47 try { Class.forName( "com.mysql.jdbc.Driver" ); connection = DriverManager.getConnection( "jdbc:mysql://localhost/Books,usuario, password); } El resto del programa no cambia, es idntico al de ODBC