Posts Tagged ‘jdbc’

Com fer servir Java, JDBC i GNU/Linux

dissabte, abril 25th, 2009

A la facultat ens han donat instruccions per a treballar amb Java i JDBC des de Windows. Com que alguns no fem servir aquest sistema inoperatiu per motius tant tècnics com ètics, m’hi he barallat una estoneta i he trobat com fer-ho amb GNU/Linux. No és complicat :)

Entorn

Java

Primer de tot ens cal l’entorn per desenvolupar aplicacions en Java

apt-get install sun-java6-jdk

Amb això no n’hi ha prou per fer un Hello World. GNU/Linux permet tenir diverses màquines virtuals instal·lades, i per defecte en ve una de lliure (cosa que ja em sembla bé). Volem desenvolupar en un entorn tan semblat a la facultat com sigui possible, així que ens toca canviar la màquina virtual i posar la privativa:

artoo:/home/edu# update-alternatives --config java

Hi ha 3 alternatives que proveeixin «java».

Selecció     Alternativa
-----------------------------------------------
1    /usr/bin/gij-4.3
+        2    /usr/lib/jvm/java-gcj/jre/bin/java
*         3    /usr/lib/jvm/java-6-sun/jre/bin/java

Premeu retorn per a mantenir l'opció per defecte[*], o introduïu un número de selecció:

Volem la 3.

Per treballar amb JDBC i PostgreSQL ens fa falta el driver adequat. A dia d’avui n’hi ha dos de disponibles, el 3 i el 4. Jo he necessitat el 4 perquè tinc màquina virtual versió >= 1.6
edu@artoo:~/facultat/bd/java$ java -version
java version "1.6.0_12"
Java(TM) SE Runtime Environment (build 1.6.0_12-b04)
Java HotSpot(TM) Client VM (build 11.2-b01, mixed mode, sharing)
edu@artoo:~/facultat/bd/java$

Ens baixarem un fitxer .jar, que ve a ser un tar.gz. El podem posar on vulguem, perquè després li direm al sistema on és. Jo he optat per fer-me un directori de treball per fer les pràctiques en /home/edu/facultat/bd/java :
edu@artoo:~/facultat/bd/java$ ls
classp             gestioSocis.java     HelloWorldApp.java
gestioSocis.class  HelloWorldApp.class
edu@artoo:~/facultat/bd/java$ ls classp/
postgresql.jar

Ara ja tenim els ingredients, i falta connectar-los. Caldrà exportar la variable d’entorn CLASSPATH. Pels veterans de C++, això ve a ser com quan compilem amb g++

g++ -c programa.cpp -I/includesdiversos

Cal dir-li on cercar fitxers que inclourem i que no venen de sèrie. Com si fos una variable d’entorn normal, fem:

export CLASSPATH=.:classp/postgresql.jar

i així li diem que busqui classes en el directori actual i en classp/postgresql.jar. Ara, per fi, ja podem fer les primeres proves amb JDBC.

Servidor i PostgreSQL

Necessitem un servidor Apache i PostgreSQL. L’opció més fàcil és fer servir LAMPP :

Instal·leu lampp en /opt/lampp Instruccions i paquet

Instal·leu el plugin per a PosgreSQL Instruccions i paquet

Els passos indicats a la web del plugin són:

  1. “tar xfz postgresql.tar.gz -C /tmp” Canvieu el nom de fitxer pel que hagueu baixat, és clar.
  2. “cd /tmp/postgresql-addon”
  3. “./INSTALL”

Per a iniciar el servidor POSGRESQL: /opt/lampp/lampp startpostgresql

Stop: /opt/lampp/lampp stoppostgresql

combinació usuari i contrasenya per defecte: User: root Password: lampp

És recomanable iniciar primer el servidor apache: /opt/lampp/lampp start i després el posgresql: /opt/lampp/lampp startpostgresql

Podeu veure una interfície web per a Posgres des del Firefox, tot anant a l’adreça: /localhost/phppgadmin

Com compilar amb Java

Farem un HelloWorld en un segon:

class HelloWorldApp {
public static void main(String[] args) {
System.out.println("Hello World!"); // Display the string.
}
}

Aquest és el codi. Cal desar-lo en HelloWorldApp.java. És important respectar el nom de fitxer, que ha de ser igual al de la classe principal.

Doncs apa:

edu@artoo:~/facultat/bd/java$ javac HelloWorldApp.java
edu@artoo:~/facultat/bd/java$ java HelloWorldApp
Hello World!
edu@artoo:~/facultat/bd/java$

Proves amb JDBC

Per l’assignatura de Bases de Dades de la FIB, quadrimestre 08-09Primavera, fem servir el següent escenari (font)

CREATE TABLE socis
(dni char(9),
nom char(30) NOT NULL,
telefon char(9),
numVISA char(12),
ciutatResidencia char(20) DEFAULT 'Barcelona',
PRIMARY KEY (dni));
 
CREATE TABLE tipus
(tipus char(15),
numMaxInscripcions integer NOT NULL,
PRIMARY KEY (tipus));
 
CREATE TABLE activitats
(tipusActivitat char(15),
dataInici integer,
descripcio char(50) UNIQUE,
dni char(9),
preu integer CHECK (preu > 10),
lloc char(20),
ciutat char(20),
PRIMARY KEY (tipusActivitat, dataInici),
FOREIGN KEY (tipusActivitat) REFERENCES tipus (tipus),
FOREIGN KEY (dni) REFERENCES socis);
 
CREATE TABLE inscripcions
(tipusActivitat char(15),
dataInici integer,
dni char(9),
formaPagament char(20),
dataPagament integer,
CHECK (dataInici < dataPagament),
PRIMARY KEY (tipusActivitat, dataInici, dni),
FOREIGN KEY (tipusActivitat, dataInici) REFERENCES activitats,
FOREIGN KEY (dni) REFERENCES socis);

Amb les dades a continuació (font):

INSERT INTO socis VALUES (10, 'Carme', 101,NULL, 'Hospitalet');
INSERT INTO socis VALUES (11, 'Nuria', 111, 111111, 'Hospitalet');
INSERT INTO socis VALUES (12, 'Josep', 121, 121121, 'Hospitalet');
INSERT INTO socis VALUES (13, 'Jordi', 131, 131131, 'Barcelona');
INSERT INTO socis VALUES (14, 'Imma', 141, 141141, 'Barcelona');
INSERT INTO socis VALUES (15, 'Roger', 151, 151151, 'Barcelona');
INSERT INTO socis VALUES (16, 'Oriol', 161, 161161, 'Barcelona');
INSERT INTO socis VALUES ('17', 'Mireia', 101,101101, 'Palleja');
INSERT INTO socis (dni, nom, telefon, numVISA) VALUES (19, 'Joan', 333, 333333);
INSERT INTO socis (dni, nom, telefon, ciutatResidencia) VALUES (20, 'Joan', 333, 'Sant Just');
 
INSERT INTO tipus VALUES ('capDAny', 200);
INSERT INTO tipus VALUES ('cine', 10);
INSERT INTO tipus VALUES ('teatre', 6);
INSERT INTO tipus VALUES ('discoteca', 30);
INSERT INTO tipus VALUES ('excursio', 30); 
INSERT INTO tipus VALUES ('sopar', 2);
INSERT INTO tipus VALUES ('opera', 6);
INSERT INTO tipus VALUES ('concert', 6);
 
INSERT INTO activitats VALUES ('cine', 124, 'One Milion Baby', 10, 17, 'Cinesa Diagonal', 'Barcelona');
INSERT INTO activitats VALUES ('cine', 224, 'Magnolias de Acero', 11, 16, 'La Farga', 'Hospitalet');
INSERT INTO activitats VALUES ('capDAny', 1224, 'Festa Roc Blanc', 12, 100, 'Plaça Major', 'Vic');
INSERT INTO activitats VALUES ('sopar', 425, 'Aniversari Josep', 12, 80, 'Can Jubany', 'Calldetenes'); 
INSERT INTO activitats VALUES ('teatre', 424, 'El Ratoli Viatger', 10, 15, 'Teatre Atlantida', 'Ripoll');
INSERT INTO activitats VALUES ('opera', 2345, 'La Flauta Magica', NULL, NULL, 'Liceu', 'Barcelona');
INSERT INTO activitats VALUES ('concert', 3234, 'La Casa de Vent i de Fusta', 10, NULL, NULL, 'Barcelona');
 
INSERT INTO inscripcions (tipusActivitat, dataInici, dni, formaPagament) VALUES ('cine', 124, 10, 'amex');
INSERT INTO inscripcions (tipusActivitat, dataInici, dni, formaPagament) VALUES ('sopar', 425, 10, 'sdfjñs');
INSERT INTO inscripcions (tipusActivitat, dataInici, dni, formaPagament) VALUES ('capDAny', 1224, 10, 'amex');
INSERT INTO inscripcions (tipusActivitat, dataInici, dni, formaPagament) VALUES ('cine', 124, 11, 'visa');
INSERT INTO inscripcions (tipusActivitat, dataInici, dni, formaPagament) VALUES ('sopar', 425, 11, 'visa');
INSERT INTO inscripcions (tipusActivitat, dataInici, dni, formaPagament) VALUES ('capDAny', 1224, 11, 'visa');
INSERT INTO inscripcions (tipusActivitat, dataInici, dni, formaPagament) VALUES ('sopar', 425, 12, 'sdfjñs');
INSERT INTO inscripcions (tipusActivitat, dataInici, dni, formaPagament) VALUES ('cine', 224, 13, 'sdfjñs');
INSERT INTO inscripcions (tipusActivitat, dataInici, dni, formaPagament) VALUES ('cine', 224, 14, 'sdfjñs');
INSERT INTO inscripcions (tipusActivitat, dataInici, dni, formaPagament) VALUES ('cine', 224, 15, 'sdfjñs');
INSERT INTO inscripcions (tipusActivitat, dataInici, dni, formaPagament) VALUES ('cine', 224, 16, 'sdfjñs');
INSERT INTO inscripcions VALUES ('teatre', 424, 10, 'VISA', 435);
INSERT INTO inscripcions VALUES ('teatre', 424, 11, 'VISA', 435);
INSERT INTO inscripcions VALUES ('teatre', 424, 12, 'VISA', 435);
INSERT INTO inscripcions VALUES ('teatre', 424, 13, 'VISA', 435);
INSERT INTO inscripcions VALUES ('teatre', 424, 14, 'VISA', 435);
INSERT INTO inscripcions VALUES ('teatre', 424, 15, 'VISA', 435);
INSERT INTO inscripcions VALUES ('teatre', 424, 16, 'VISA', 435);
INSERT INTO inscripcions (tipusActivitat, dataInici, dni) VALUES ('opera', 2345, 10);
INSERT INTO inscripcions (tipusActivitat, dataInici, dni) VALUES ('opera', 2345, 11);
INSERT INTO inscripcions (tipusActivitat, dataInici, dni) VALUES ('opera', 2345, 12);
INSERT INTO inscripcions (tipusActivitat, dataInici, dni) VALUES ('opera', 2345, 13);
INSERT INTO inscripcions (tipusActivitat, dataInici, dni) VALUES ('opera', 2345, 14);
INSERT INTO inscripcions (tipusActivitat, dataInici, dni) VALUES ('opera', 2345, 15);

La facultat ens facilita també un codi plantilla amb les línies indispensables per establir una connexió:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import java.sql.*;
import java.util.Properties;
 
public class gestioSocis
   {
   public static void main (String args[])
     {
	try
	   {
	   // carregar el driver al controlador
	   Class.forName ("org.postgresql.Driver");
	   System.out.println ("Driver de PostgreSQL carregat correctament.");
 
 
	   // connectar a la base de dades
	   // cal modificar el username, password i el nom de la base de dades
	   // en el servidor postgresfib, SEMPRE el SSL ha de ser true
	   Properties props = new Properties();
	   props.setProperty("user","elMeuNomUsuari");
	   props.setProperty("password","elMeuPassword");
	   props.setProperty("ssl","true");
	   props.setProperty("sslfactory", "org.postgresql.ssl.NonValidatingFactory"); 
	   Connection c = DriverManager.getConnection("jdbc:postgresql://postgresfib.fib.upc.es:5432/laMevaBaseDeDades", props);
	   c.setAutoCommit(false);
	   System.out.println ("Connexio realitzada correctament.");
 
 
	   // canvi de l'esquema per defecte a un altre esquema
		 Statement s = c.createStatement();
		 s.executeUpdate("set search_path to elMeuEsquema;");
		 s.close();					
	   System.out.println ("Canvi d'esquema realitzat correctament.");
 
 
	   // consultar tots les socis que viuen a Hospitalet
	   // Dir quantes inscripcions té cada un 
	   String cR = "Hospitalet";
	   String consSocis="select dni,nom from socis "+
                         "where ciutatResidencia = '"+cR+"';";
	   System.out.println (consSocis);
	   s = c.createStatement();
	   ResultSet r = s.executeQuery (consSocis);
 
           String consInscr="select count(*) as numInscr "+
                      "from inscripcions i where i.dni = ? ;";
	   System.out.println (consInscr);
 	   PreparedStatement ps = c.prepareStatement(consInscr); 
 	   ResultSet rs = null;
	   int quantsSocis = 0;
	   String dni=" ";
	   String nom=" ";
	   while (r.next())
	   	   {
	   	   quantsSocis = quantsSocis + 1;
	   	   dni = r.getString("dni");
	   	   nom = r.getString("nom");
	   	   System.out.print ("El soci amb dni "+dni+" i nom ");
	   	   if (nom==null) { System.out.print ("null"); }
                     else { System.out.print (nom); }
		     ps.setString(1,dni);
		     rs = ps.executeQuery();
		     rs.next();
		     System.out.print("te ");
		     System.out.print (rs.getInt("numInscr"));
		     System.out.println(" inscripcions");
		     rs.close();
	   	   }
           r.close();
           System.out.println ("Nombre de socis consultats "+quantsSocis);
	   s.close();
 
	   // Inserir una activitat 
 
	   s = c.createStatement();
	   String inserirAct="insert into activitats "+
                      "values ('concert', 3250, 'El fantasma del museu', 10, 120, 'Romea', 'Barcelona')";
	   s.executeUpdate(inserirAct);
	   System.out.println ("Una activitat inserida");
           s.close();
 
	   // Rollback i desconnexió de la base de dades
	   c.rollback();
	   c.close();
	   System.out.println ("Rollback i desconnexio realitzats correctament.");
	   }
 
	catch (ClassNotFoundException ce)
	   {
	   System.out.println ("Error al carregar el driver");
	   }	
	catch (SQLException se)
	   {
	   System.out.println (se.getSQLState());
	   System.out.println (se.getMessage());	   
	   }
  }
}

El que passa és que està preparat per connectar-se des dels laboratoris de la uni, i a casa vull treballar en local. M’ho modifico:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import java.sql.*;
import java.util.Properties;
 
public class gestioSocis
   {
   public static void main (String args[])
     {
	try
	   {
	   // carregar el driver al controlador
	   Class.forName ("org.postgresql.Driver");
	   System.out.println ("Driver de PostgreSQL carregat correctament.");
 
 
	   // connectar a la base de dades
	   // cal modificar el username, password i el nom de la base de dades
	   // en el servidor postgresfib, SEMPRE el SSL ha de ser true
	   Properties props = new Properties();
	   props.setProperty("user","root");
	   props.setProperty("password","lampp");
	   //props.setProperty("ssl","true");
	   //props.setProperty("sslfactory", "org.postgresql.ssl.NonValidatingFactory"); 
	   Connection c = DriverManager.getConnection("jdbc:postgresql://localhost/javafib", props);
	   c.setAutoCommit(false);
	   System.out.println ("Connexio realitzada correctament.");
 
 
	   // canvi de l'esquema per defecte a un altre esquema
		 Statement s = c.createStatement();
		 s.executeUpdate("set search_path to public;");
		 s.close();					
	   System.out.println ("Canvi d'esquema realitzat correctament.");
 
 
	   // consultar tots les socis que viuen a Hospitalet
	   // Dir quantes inscripcions té cada un 
	   String cR = "Hospitalet";
	   String consSocis="select dni,nom from socis "+
                         "where ciutatResidencia = '"+cR+"';";
	   System.out.println (consSocis);
	   s = c.createStatement();
	   ResultSet r = s.executeQuery (consSocis);
 
           String consInscr="select count(*) as numInscr "+
                      "from inscripcions i where i.dni = ? ;";
	   System.out.println (consInscr);
 	   PreparedStatement ps = c.prepareStatement(consInscr); 
 	   ResultSet rs = null;
	   int quantsSocis = 0;
	   String dni=" ";
	   String nom=" ";
	   while (r.next())
	   	   {
	   	   quantsSocis = quantsSocis + 1;
	   	   dni = r.getString("dni");
	   	   nom = r.getString("nom");
	   	   System.out.print ("El soci amb dni "+dni+" i nom ");
	   	   if (nom==null) { System.out.print ("null"); }
                     else { System.out.print (nom); }
		     ps.setString(1,dni);
		     rs = ps.executeQuery();
		     rs.next();
		     System.out.print("te ");
		     System.out.print (rs.getInt("numInscr"));
		     System.out.println(" inscripcions");
		     rs.close();
	   	   }
           r.close();
           System.out.println ("Nombre de socis consultats "+quantsSocis);
	   s.close();
 
	   // Inserir una activitat 
 
	   s = c.createStatement();
	   String inserirAct="insert into activitats "+
                      "values ('concert', 3250, 'El fantasma del museu', 10, 120, 'Romea', 'Barcelona')";
	   s.executeUpdate(inserirAct);
	   System.out.println ("Una activitat inserida");
           s.close();
 
	   // Rollback i desconnexió de la base de dades
	   c.rollback();
	   c.close();
	   System.out.println ("Rollback i desconnexio realitzats correctament.");
	   }
 
	catch (ClassNotFoundException ce)
	   {
	   System.out.println ("Error al carregar el driver");
	   }	
	catch (SQLException se)
	   {
	   System.out.println (se.getSQLState());
	   System.out.println (se.getMessage());	   
	   }
  }
}

i es fa la màgia

edu@artoo:~/facultat/bd/java$ java gestioSocis
Driver de PostgreSQL carregat correctament.
Connexio realitzada correctament.
Canvi d'esquema realitzat correctament.
select dni,nom from socis where ciutatResidencia = 'Hospitalet';
select count(*) as numInscr from inscripcions i where i.dni = ? ;
El soci amb dni 10 i nom Carme te 5 inscripcions
El soci amb dni 11 i nom Nuria te 5 inscripcions
El soci amb dni 12 i nom Josep te 3 inscripcions
Nombre de socis consultats 3
Una activitat inserida
Rollback i desconnexio realitzats correctament.
edu@artoo:~/facultat/bd/java$


Entra