JDBC: Conexiones con bases de datos desde Java Luis Fernando Llana Díaz Departamento de Sistemas Informáticos y Computación Universidad Complutense de Madrid 0 de mayo de 007
JDBC Conexión con una fuentes de datos. Realizar peticiones y actualizaciones. Manejar los resultados de las consultas Aplicacion Java JDBC DBMS MySQL DBMS Oracle DBMS PostgresSQL
Drivers JDBC Es necesario un driver dependiente del proveedor de la Base de datos. MySQL MySQL java connector
Creando la base de datos Fichero crea.sql create database valores ; use valores ; create table valores ( id int unsigned auto_increment primary key, nombre varchar (), ibex_id varchar (00), url varchar (), tipo enum (" acciones "," fondos ") ); create table datos ( id int unsigned auto_increment primary key, empresa int unsigned, fecha date, valor double ); grant all on valores.* to luis identified by ' patata '; 7 8 9 0 7 8 9 ~/ sql$ mysql -u root < crea.sql
Interfaz java.sql.connection Establece conexión con la base de datos. No tiene constructor. Es un interfaz (está implementado en el driver). Constuye instrucciones SQL precompiladas (método preparestatement).
Realizando conexión con la base de datos package valores ; import java.sql. Connection ; import java.sql. DriverManager ; import java.sql. SQLException ; public class Conexion { protected static Connection getmysqlconnection ( String url, String db, String user, String passwd ) throws ClassNotFoundException, InstantiationException, SQLException, IllegalAccessException { Class. forname ("com. mysql.jdbc. Driver " ). newinstance (); return DriverManager. getconnection ("jdbc : mysql :// "+url+"/"+db+ "?user ="+ user +"& password ="+ passwd ); protected static Connection getmysqlconnection () throws ClassNotFoundException, InstantiationException, SQLException, IllegalAccessException { return getmysqlconnection (" localhost ", " valores ", "luis ", " patata " ); protected static String getfich ( String fich ) { java.net.url url = ClassLoader. getsystemresource (fich ); return url. getpath (); 7 8 9 0 7 8 9 0 7 8
Ficheros de datos Fichero de valores: valores.csv BSCH BSCH acciones http :// www. bolsamadrid.es /esp / mercados / acciones / accind_.htm Endesa ENDESA acciones http :// www. bolsamadrid.es /esp / mercados / acciones / accind_.htm Repsol - YPF REPSOL YPF acciones http :// www. bolsamadrid.es /esp / mercados / acciones / accind_ Acciona ACCIONA acciones http :// www. bolsamadrid.es /esp / mercados / acciones / accind_.htm Inditex INDITEX acciones http :// www. bolsamadrid.es /esp / mercados / acciones / accind_.htm Teléfonica TELEFONICA acciones http :// www. bolsamadrid.es /esp / mercados / acciones / accind_ Banco Popular BA. POPULAR acciones http :// www. bolsamadrid.es /esp / mercados / acciones / accind 7 Ebro - Puleva EBRO PULEVA acciones http :// www. bolsamadrid.es /esp / mercados / acciones / igbm 8 Mittal - Steel ARCELOR MIT. acciones http :// www. bolsamadrid.es /esp / mercados / acciones / 9igbm_ Indra INDRA A acciones http :// www. bolsamadrid.es /esp / mercados / acciones / igbm.htm0 EADS EADS acciones http :// www. bolsamadrid.es /esp / mercados / acciones / igbm.htm Unipapel UNIPAPEL acciones http :// www. bolsamadrid.es /esp / mercados / acciones / igbm.htm Madrid Bolsa MADRID BOLSA fondos http :// www. bolsamadrid.es /esp / mercados / fondos / htmfondos Plus Madrid PLUSMADRID fondos http :// www. bolsamadrid.es /esp / mercados / fondos / htmfondos /00 FonCaixa FONCAIXA BOLSA INDICE ESPA &#; A fondos http :// www. bolsamadrid.es /esp / me
Cargar datos package valores ; import java.io. BufferedReader ; import java.io. FileReader ; import java.io. IOException ; import java.sql. Connection ; import java.sql. PreparedStatement ; import java.sql. SQLException ; 7 import java.util. Scanner ; 8 public class LeeValores { 9 private static void insertadatos ( Connection con, BufferedReader in ) 0 throws IOException, SQLException {... public static void main ( String [] args ) throws Exception { Connection con = null ; BufferedReader in = null ; try { 7 con = Conexion. getmysqlconnection (); 8 in = new BufferedReader (new FileReader ( Conexion. getfich ("sql / valores.csv 9" ))) insertadatos (con, in ); 0 finally { if (con!= null ) con. close (); if (in!= null ) in. close ();
¾Dónde está el chero sql/valores.csv?. -- -- sql -- borra. sql -- crea. sql -- datos. csv -- usuarios. csv `-- valores. csv -- src -- valores -- CVS -- Entries -- Repository `-- Root -- Conexion. java -- ConsigueDatos. java -- ConsigueDatos. java.~..~ -- LeeDatos. java `-- LeeValores. java -- classes `-- valores -- Conexion. class -- ConsigueDatos. class -- LeeDatos. class `-- LeeEmpresas. class 7 8 9 0 7 8 9 0
Accediendo sql/valores.csv Los objetos de clase ClassLoader permitend acceder a los recursos Java. java.net.url url = ClassLoader. getsystemresource (fich ); fich debe estar dentro del CLASSPATH en la ejecución. ~/ Java$ export CLASSPATH =.:./ classes ~/ Java$ $JAVA_HOME /bin /java valores. LeeValores
Cargar datos private static final String sqlins = " insert into valores (nombre,ibex_id,url,tipo ) "+ " values (?,?,?,?) "; private final static int NOMBRE =; private final static int IBEX_ID =; private final static int URL_BOLSA =; private final static int TIPO =; private static void insertadatos ( Connection con, BufferedReader in ) throws IOException, SQLException { String linea = in. readline (); PreparedStatement pstmt = con. preparestatement ( sqlins ); while ( linea!= null ) { Scanner scan = new Scanner ( linea ); scan. usedelimiter (" " ); String nombre = scan. next (); String ibex_id = scan. next (); String tipo = scan. next (); String url = scan. next (); System.out. println ( nombre +":"+ ibex_id +":"+ tipo +":"+ url ); pstmt. setstring (NOMBRE, nombre ); pstmt. setstring (IBEX_ID, ibex_id ); pstmt. setstring (TIPO,tipo ); pstmt. setstring (URL_BOLSA,url ); int n = pstmt. executeupdate (); linea = in. readline (); 7 8 9 0 7 8 9 0 7 8
Ficheros de datos Fichero de valores: valores.csv Fecha BSCH ENDESA REPSOL - YPF ACCIONA INDITEX Telefónica Banco Popular Ebro - Puleva Mittal 8/0/0 9. 7.0.. 7..9 0/0/0 9. 7.0.. 7..9 7/08/0 8..98 0. 9.8.8 7.0. 0/08/0 7.99.9 7.0 0.0 9.08.78.89 7.. //0.0.7 7.7 7.9 9.9.0.7 8.. 8..08. 87. 8 9//0.98..9 8. 0.78..7 9.7. 8..0. 9.7 8 0//0.08..9 9.9 0.9.8.8 9.8.8 8... 0.7 8 //0.0.. 0.9 0... 9..8 8..79..9 8. 7//0..7. 0.0..9 9.9.9 9.0.07... 8//0....0 0.89..8 9.. 8.7.00.0.0 9//0..8.. 0.8..7 9. 8..00.0.. 8 0/0/07..8.. 0.8..7 9. 8..00.0.8. 0/0/07.9.7..0 0.79.9.97 9..87 8.88.9.8 7.8
Cargar datos private static void insertadatos ( Connection con, BufferedReader in ) throws IOException, SQLException, ParseException { int [] id_valores = valores ( con ); String linea = in. readline (); linea = in. readline (); String sql = " insert into datos (fecha,valor, precio ) values (?,?,? )"; PreparedStatement pstmt = con. preparestatement (sql ); 7 while ( linea!= null ) { 8 Scanner scan = new Scanner ( linea ); 9 scan. usedelimiter (" " ); 0 String strfecha = scan. next (); if (! strfecha. equals ("" )) { DateFormat df = new SimpleDateFormat (" dd / MM / yy " ); Date fecha = df. parse ( strfecha ); System.out. println (df. format ( fecha )); for (int i = 0; i < id_valores. length ; i ++) { String strvalor = scan. next (); 7 if (! strvalor. equals ("" )) { 8 double precio = Double. parsedouble ( strvalor ); 9 pstmt. setdate (, new java.sql.date ( fecha. gettime ())); 0 pstmt. setint (, id_valores [i ]); pstmt. setdouble (, precio ); int n = pstmt. executeupdate (); 7 linea = in. readline (); 8 9 0
Cargar datos private static String [] valores = { " BSCH "," ENDESA "," REPSOL YPF ", " ACCIONA "," INDITEX "," TELEFONICA ", "BA. POPULAR ","EBRO PULEVA "," ARCELOR MIT.", " INDRA A"," EADS "," UNIPAPEL "," MADRID BOLSA ", " PLUSMADRID "," FONCAIXA BOLSA INDICE ESPA &#; A" ; private static int [] valores ( Connection con ) throws SQLException { int [] ids = new int [valores. length ]; String sql = " select id from valores where ibex_id like?"; PreparedStatement pstmt = con. preparestatement (sql ); for (int i = 0; i < ids. length ; i ++) { pstmt. setstring (, valores [i ]); ResultSet rs = pstmt. executequery (); rs. next (); ids [i ]=rs. getint (); return ids ; 7 8 9 0 7 8 9
Realizar actualizaciones Instrucciones: INSERT, UPDATE, DELETE public static void pr ( Connection con ) throws SQLException { String sql = " update datos set precio = precio + "; PreparedStatement pstmt = con. preparestatement (sql ); int n = pstmt. executeupdate (); System.out. println (n+" filas actualizadas " ); SQLWarning warning = pstmt. getwarnings (); if ( warning!= null ) { System. out. println (" AVISOS... " ); while ( warning!= null ) { System.out. println (" Message : " + warning. getmessage ()); warning = warning. getnextwarning (); else { System.out. println ("No hay avisos " ); 7 8 9 0
Realizar Consultas Instrucciones Select select id, nombre, tipo from valores ResultSet rs = pstmt.executequery(); rs id nombre tipo
Realizar Consultas Instrucciones Select select id, nombre, tipo from valores rs.next(); id nombre tipo rs BSCH acciones
Realizar Consultas Instrucciones Select select id, nombre, tipo from valores rs.next(); id nombre tipo BSCH acciones rs Endesa acciones
Realizar Consultas Instrucciones Select select id, nombre, tipo from valores rs.next(); id nombre tipo BSCH acciones Endesa acciones rs Repsol-YPF acciones
Realizar Consultas Instrucciones Select select id, nombre, tipo from valores rs.next(); id nombre tipo BSCH acciones Endesa acciones Repsol-YPF acciones rs Acciona acciones
Realizar Consultas Instrucciones Select select id, nombre, tipo from valores rs.next(); id nombre tipo BSCH acciones Endesa acciones Repsol-YPF acciones Acciona acciones rs Inditex acciones
Realizar Consultas Instrucciones Select select id, nombre, tipo from valores rs.next(); id nombre tipo BSCH acciones Endesa acciones Repsol-YPF acciones Acciona acciones Inditex acciones rs Telefónica acciones
Realizar Consultas Instrucciones Select select id, nombre, tipo from valores id nombre tipo BSCH acciones Endesa acciones Repsol-YPF acciones Acciona acciones Inditex acciones Telefónica acciones
Ejemplos de consultas I public static void pr ( Connection con ) throws SQLException { String sql = " select * from valores "; PreparedStatement pstmt = con. preparestatement (sql ); ResultSet rs = pstmt. executequery (); while ( rs. next ()) { int id = rs. getint ("id " ); String nombre = rs. getstring (" nombre " ); System.out. println (id +":"+ nombre ); 7 8 9 0
Ejemplos de consultas II public static void pr ( Connection con ) throws SQLException { String sql = " select valores.nombre, datos.fecha, datos. precio "+ " from datos left join valores on valores.id = datos. valor "+ " where datos. fecha >= '007-0 -0 ' "+ " order by valores.tipo, valores.nombre, datos. fecha "; PreparedStatement pstmt = con. preparestatement (sql ); ResultSet rs = pstmt. executequery (); 7 while ( rs. next ()) { 8 String nombre = rs. getstring (" valores. nombre " ); 9 Date fecha = rs. getdate (" datos. fecha " ); 0 double precio = rs. getdouble (" datos. precio " ); DateFormat df = new SimpleDateFormat (" dd 'de ' MMMM 'de ' yyy " ); NumberFormat nf = new DecimalFormat (" #,000.00 'e'" ); System.out. println (df. format ( fecha )+ "\t"+ nombre +"\t"+ nf. format ( precio ));
Ejemplos de consultas III public static int getid ( String ibex_id, Connection con ) throws SQLException { String sql = " select id from valores where ibex_id like '"+ibex_id +" '"; PreparedStatement pstmt = con. preparestatement (sql ); ResultSet rs = pstmt. executequery (); if ( rs. next ()) { return rs. getint (); else { return -; 7 8 9 0
Consiguiendo datos desde www.bolsamadrid.es Conseguir el chero HTML. Analizar el chero. Añadir datos en la base de datos.
Conseguir el chero HTML Fichero de valores: valores.csv BSCH BSCH acciones http :// www. bolsamadrid.es /esp / mercados / acciones / accind_.htm Endesa ENDESA acciones http :// www. bolsamadrid.es /esp / mercados / acciones / accind_.htm private static String cargapagina ( java. net. URL url ) throws IOException { InputStream in = url. openstream (); StringBuffer sb = new StringBuffer (); int c = in. read (); while (c!= -) { sb. append (( char )c ); c = in. read (); String res = sb. tostring (); return res ; 7 8 9 0
Analizar el chero HTML Fichero de valores: http://www.bolsamadrid.es/esp/mercados/acciones/accind_.ht...... <IMG SRC="/ images /arr -up9.gif " BORDER=0> BSCH</A></TD><TD>,0</TD>......... <IMG SRC="/ images /arr -dw9.gif " BORDER=0> ENDESA</A></TD><TD>0,9</TD>... private static double getvalor ( String ibex_id, String datos, String tipo ) throws ParseException { String regexp = null ; if (tipo. equals (" acciones " )) { regexp=ibex_id+" *</A></TD><TD >([0-9,]+) </TD>"; else if (tipo. equals (" fondos " )) { regexp=ibex_id+" *</a></td >.*? <TD *[^>]* >([0-9,]+) </TD>"; 7 else { 8 throw new RuntimeException (" Tipo \'"+ tipo +"\' desconocido " ); 9 0 Pattern p = Pattern. compile ( regexp ); Matcher m = p. matcher ( datos ); if (m. find ()) { // Double. parsedouble no vale, no analiza,0 NumberFormat nf = NumberFormat. getinstance (); return nf. parse (m. group ()). doublevalue (); else { 7 throw new RuntimeException (" Acciones \'"+ ibex_id +"\' no encontrada " ); 8 9 0
Insertar los datos en la Base de datos private static final String sqlins = " insert into datos ( fecha, valor, precio ) values (?,?,?) "; private static final int FECHA =; private static final int VALOR =; private static final int PRECIO =; private static void insertadatos (java.sql.date fecha, Connection con ) throws SQLException, IOException, ParseException { HashMap <String, String > paginas = new HashMap <String, String >(); String sql = " select * from valores "; PreparedStatement pstmtvalores = con. preparestatement (sql ); ResultSet rs = pstmtvalores. executequery (); PreparedStatement pstmtins = con. preparestatement ( sqlins ); while ( rs. next ()) { insertadatos ( pstmtins, fecha, rs, paginas ); 7 8 9 0 7 8 9
Insertar los datos en la Base de datos private static void insertadatos ( PreparedStatement pstmtins, java. sql. Date fecha, ResultSet rs, HashMap <String, String > paginas ) throws SQLException, IOException, ParseException { String url = rs. getstring ("url " ); String datos = paginas. get ( url ); if ( datos == null ) { datos = cargapagina ( paginas, url )); paginas.put (url, datos ); String tipo = rs. getstring ("tipo " ); String ibex_id = rs. getstring (" ibex_id " ); double valor = getvalor ( ibex_id, datos, tipo ); int id = rs. getint ("id " ); String nombre = rs. getstring (" nombre " ); pstmtins. setdate (FECHA, fecha ); pstmtins. setint (VALOR,id ); pstmtins. setdouble (PRECIO, valor ); int n = pstmtins. executeupdate (); 7 8 9 0 7 8 9 0
Consiguiendo datos automáticamente #!/ bin / sh # $Id : transparencias. tex,v.8 007-0 -0 :7: luis Exp $ JAVA_HOME =/ opt /java /jdk. CLASSPATH =/ home /casa / ahorros / classes $JAVA_HOME /bin /java -cp $CLASSPATH valores. ConsigueDatos $* $ crontab -l SHELL =/ bin /bash MAILTO = luis # Directorios donde buscar programas PATH =/ bin :/ usr /bin :/ usr / XR /bin :/ usr / local /bin :/ home /luis /bin * *,,,, /home /casa / ahorros / scripts / consiguedatos.sh > /dev /null 7 >& 8