package ar.com.javacuriosities.jdbc; import static ar.com.javacuriosities.jdbc.util.Constants.PASSWORD; import static ar.com.javacuriosities.jdbc.util.Constants.URL; import static ar.com.javacuriosities.jdbc.util.Constants.USER; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; /* * El API de JDBC (Java Database Connectivity), nos permite interactuar con bases de datos * relacionales. * * El API consta de 4 componentes claves: * - JDBC Drivers: Son el conjunto de clases que nos permite establecer una conexión con la DB, son las implementaciones de las interfaces JDBC * - Connections: Es la forma en que vamos a establecer una conexión con la DB, y la comunicación sucede a través de esta conexión * - Statements: Es la sentencia que enviaremos al motor para ejecutar nuestras consultas y actualizaciones * - ResultSets: Es la estructura que manejaremos para obtener los datos de la DB * * Driver Types: * Hay cuatro tipo de Drivers, en general ya casi todas las DB tienen implementaciones del driver tipo 4. * * - Type 1: Tiene una parte en Java que se conecta con un ODBC Bridge que se conecta al ODBC Driver y ahí a la DB * - Type 2: Tiene una parte en Java que se conecta con un driver nativo y ahí a la DB * - Type 3: Tiene una parte en Java que se conecta a un Middleware que hace la traducción y ahí a la DB * - Type 4: Todo el driver esta implementado en Java * * Register JDBC Driver: * A la hora de usar un driver JDBC, debemos registrarlo esto se puede hacer de dos formas * * - Reflection: Podemos usar "Class.forName("com.mysql.jdbc.Driver");", esto debería funcionar siempre que el Driver sea standard, si no lo es podemos probar con "Class.forName("com.mysql.jdbc.Driver").newInstance();" * - Manualmente: Podemos registrar el driver de forma manual * Driver driver = new com.mysql.jdbc.Driver(); * DriverManager.registerDriver(driver); * * JDBC URL: * La URL para la conexion varia segun el motor de base de datos, algunos ejemplos son * * - MySQL: jdbc:mysql://hostname/ databaseName * - Oracle: jdbc:oracle:thin:@hostname:port Number:databaseName * - DB2: jdbc:db2:hostname:port Number/databaseName * - Sybase: jdbc:sybase:Tds:hostname: port Number/databaseName * * SQLException: * Se utiliza para notificar detalles sobre los errores de la base de datos resultantes. * Esta clase es iterable para que podamos ver toda la cadena de errores, y tiene tres métodos para obtener * Información de la exception (getSQLState, getErrorCode, getMessage) * * JDBC Closing resources: * A la hora de trabajar con los recursos de la base de datos podemos tomar dos approach distintos, o cerrar la conexión al final luego de haberla usado * lo cual genera se cierren todos los objetos (Statement, ResultSet) pero esto no es óptimo porque los recursos no se liberan conviene cerrar cada uno de ellos * * Nota: * Para los ejemplos se va a usar MySQL, asi que el motor debe estar instalado y corriendo, por defecto se usara user="root" password="root" en caso de ser * distinta hay que cambiarlo, si el motor fuera otro habría que cambiar el connector y la URL para la conexión * */ public class Lesson01Introduction { public static void main(String[] args) { try { // Usamos Reflection para cargar la clase del Driver la cual tiene un bloque estático que registra el Driver Class.forName("com.mysql.jdbc.Driver"); // Nos conectamos con la base de datos try (Connection connection = DriverManager.getConnection(URL, USER, PASSWORD)) { System.out.println("Connection open"); // Por medio de la conexión podemos obtener metadata de la base y ejecutar algunas consultas DatabaseMetaData databaseMetaData = connection.getMetaData(); int majorVersion = databaseMetaData.getDatabaseMajorVersion(); int minorVersion = databaseMetaData.getDatabaseMinorVersion(); String productName = databaseMetaData.getDatabaseProductName(); String productVersion = databaseMetaData.getDatabaseProductVersion(); System.out.println("Major Version: " + majorVersion); System.out.println("Minor Version: " + minorVersion); System.out.println("Product Name: " + productName); System.out.println("Product Version: " + productVersion); listingTables(databaseMetaData); listingColumnFromTable(databaseMetaData); primaryKeyFortable(databaseMetaData); checkSupportedFeatures(databaseMetaData); checkSQLANSI92(databaseMetaData); } } catch (Exception e) { // Log and Handle exception e.printStackTrace(); } } private static void listingTables(DatabaseMetaData databaseMetaData) throws SQLException { // Podemos pasarle algunos parámetros para filtrar esta consulta ResultSet result = databaseMetaData.getTables(null, null, null, null); while (result.next()) { String tableName = result.getString(3); System.out.println(tableName); } } private static void listingColumnFromTable(DatabaseMetaData databaseMetaData) throws SQLException { String catalog = null; String schemaPattern = null; String tableNamePattern = "alumnos"; String columnNamePattern = null; ResultSet result = databaseMetaData.getColumns(catalog, schemaPattern, tableNamePattern, columnNamePattern); while (result.next()) { String columnName = result.getString(4); int columnType = result.getInt(5); System.out.println("Column Name: " + columnName + " Column Type: " + columnType); } } private static void primaryKeyFortable(DatabaseMetaData databaseMetaData) throws SQLException { String catalog = null; String schema = null; String tableName = "alumnos"; ResultSet result = databaseMetaData.getPrimaryKeys(catalog, schema, tableName); while (result.next()) { String columnName = result.getString(4); System.out.println("Primary Key: " + columnName); } } private static void checkSupportedFeatures(DatabaseMetaData databaseMetaData) throws SQLException { System.out.println("Supports Get Generated Keys: " + databaseMetaData.supportsGetGeneratedKeys()); System.out.println("Supports Group By: " + databaseMetaData.supportsGroupBy()); System.out.println("Supports Outer Joins: " + databaseMetaData.supportsOuterJoins()); } /* * La mayoría de las bases de datos soportan un juego estándar de semántica y * sintaxis SQL descrita por la especificación de nivel de entrada SQL-92 de ANSI * (American National Standards Institute). */ private static void checkSQLANSI92(DatabaseMetaData databaseMetaData) throws SQLException { System.out.println("Supports ANSI 92 Entry Level SQL: " + databaseMetaData.supportsANSI92EntryLevelSQL()); System.out.println("Supports ANSI 92 Intermediate SQL: " + databaseMetaData.supportsANSI92IntermediateSQL()); System.out.println("Supports ANSI 92 Full SQL: " + databaseMetaData.supportsANSI92FullSQL()); } }