Buscar
Social
Ofertas laborales ES

Foro sobre Java SE > Detectar cuando se hace un cambio en una tabla mysql

Hola, tengo un programa tipo agenda en el que necesito actualizar los datos en pantalla cada vez que algún usuario haga algún cambio en una tabla mysql, ahora lo estoy haciendo comprobando las fechas entre dos ficheros de texto (wficherocambioslocal es un fichero de texto que tengo en el disco local y wficherocambios está en un una unidad de red compartida)


initComponents();

javax.swing.Timer t = new javax.swing.Timer(1000, new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
buscaCambios();
}
});
t.start();

private void buscaCambios() {
if (wficheroCambios.lastModified() == wficheroCambiosLocal.lastModified()) {
return;
}
wficheroCambiosLocal.setLastModified(wficheroCambios.lastModified());
cargarCitas();
}


Cada vez que se modifica la tabla de citas actualizo el ficheroCambios.

¿Creéis que es una forma correcta de hacerlo?

octubre 5, 2012 | Registered Commenterfermin

La base de datos está en local o en remoto.
Que volumen de datos tienes que recuperar?

octubre 5, 2012 | Unregistered Commenterfileal_v

A ver si ésto te puede ayudar:

http://code.rocksol.it/call-java-from-mysql-trigger

octubre 5, 2012 | Registered Commenterchoces

Perdón, el volumen de datos es pequeño y la base de datos está en remoto.
¿Con los triggers puedo llamar a una función ubicada dentro de mi proyecto java?
El proyecto es un calendario de citas médicas, y la vista debe actualizase cada vez que un usuario añada o modifique una cita.

octubre 12, 2012 | Registered Commenterfermin

He revisado el enlace de choces y parece que con esa librería se puede ejecutar código java, pero no me aclaro como hacerlo.

octubre 12, 2012 | Registered Commenterfermin

Debes definir un trigger en MySQL con este nombre: onEventLogAfterInsert
Ese trigger debe dispararse cuando se actualiza la tabla, o tablas, en las que estás interesado.
Creo que el código Java que se usa para "capturar" el trigger es bastante sencillo:

1.- Activas el trigger:

DatabaseTrigger dbTrigger = new DatabaseTrigger(conn, "EventLog", DatabaseTrigger.Time.AFTER, DatabaseTrigger.Event.INSERT, this);

2.- Declaras un interface:

public interface DatabaseTriggerMonitor
{
public void onTrigger(DatabaseTrigger trigger);
}

Ese interface lo implementas en las clases donde estás interesado en recibir el trigger. Al hacerlo, cada una de esas clases tendrá que implementar el código para el método declarado en ese interface:

public void onTrigger(DatabaseTrigger trigger){
// aquí incluyes el código que actualiza el UI
}

Un detalle importante es que ese método no se ejecutará en el EDT de Swing. Asi que las llamadas a métodos de Swing deberás encapsularlas en:

EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
// código que usa métodos del UI de Swing
}
});

octubre 12, 2012 | Registered Commenterchoces

Lo siento pero no lo pillo, ¿como creo en el triger?, ¿no debería decirle ya en el triger lo que debe hacer? he probado a crearlo así:

CREATE TRIGGER onEventLogAfterInsert AFTER INSERT ON citas;

...pero me da error...

octubre 15, 2012 | Registered Commenterfermin

¿Quién te lanza ese error?. Y ya de paso, ¿Qué error es ese?.

octubre 16, 2012 | Registered Commenterchoces

Hola, perdón por ser tan escueto.
Intento crear el triger desde phpmyadmin (no sé si debe ser así) y el error que me da es:

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1

octubre 18, 2012 | Registered Commenterfermin

Comprueba la sintaxis de create trigger para tu versión concreta de MySQL, porque esas ' ' me dan "mala espina".

octubre 18, 2012 | Registered Commenterchoces

Vale, ya he conseguido crear el trigger, ahora a por lo siguiente...
Por si le sirve a alguien explico como he creado el trigger:
Tenía que cambiar el delimitador ';' por '//' y luego crear el trigger de la siguiente forma:

CREATE TRIGGER onEventLogAfterInsert BEFORE UPDATE ON citas
FOR EACH ROW BEGIN END;//

Supongo que para este caso no necesito poner nada entre el begin y el end.

octubre 18, 2012 | Registered Commenterfermin

Hola, ya se que soy un pesao, pero sigo teniendo dudas sobre este tema y agradecería vuestra ayuda.
-¿Al activar el trigger a qué hace referencia el último parámetro (this)?
-¿Como declaro la interface, dentro del formulario o como una clase externa?

Gracias de antemano.

octubre 24, 2012 | Registered Commenterfermin

this es la clase donde se ejecuta ese código, que debe implementar ese interface.

octubre 24, 2012 | Registered Commenterchoces

Claro! me faltaba ponerle a la clase "implements DatabaseTriggerMonitor"
Gracias y un saludo.

octubre 24, 2012 | Registered Commenterfermin

Hola ya lo he probado y funciona, pero para el caso creo no me sirve, ya que lo que hace es crear un fichero en la maquina del usuario, por lo que si hay otra máquina ejecutando el programa parece ser que no se entera de que han habido cambios.


BEGIN DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END;
BEGIN SELECT 1 INTO OUTFILE '\\FERMIN\pipe\onusuariosAfterUpdate';
END; END

(No hay que crear el trigger, se crea automáticamente al ejecutar el programa)

octubre 24, 2012 | Registered Commenterfermin