Query database every X seconds

3

What I need to do is the following, I do not know why but if you update a data in database does not paint it at once in my view, I must run my project to see the update of the data. I would like to do a method that every 5 seconds consult the database and update me the data I want.

I have been told that I can do it with f: ajax but I do not know how to use it, if you could give me an example to guide me I would really appreciate it.

The database is MySQL, I use JavaServerFaces and the connection is made through JPA.

    
asked by Lina Cortés 06.06.2016 в 19:10
source

3 answers

2

The strategy explained in the response of @ PabloPéres-Aradros is a solution known as polling. This, the client consults the server from time to time. You must use setInterval for a method to run in a time interval . It happens that JSF, by default, places certain parameters on the client to ensure the status of the view and thus avoid the CSRF attacks a>, so that using the method explained by Pablo is not "so simple" when using JSF when doing everything manually. In any case, JSF does support poll.

If you use pure JSF, it would be best to delegate the action to a component with <f:ajax> :

<h:form id="idForm">
    <!-- ... contenido ... -->
    <!-- Nota: el componente DEBE ser visible, sino no se ejecutará. -->
    <h:commandButton id="idBoton" action="#{bean.metodoParaRefrescar}">
        <f:ajax render="idComponenteARefrescar" />
    </h:commandButton>
    <!-- ... contenido ... -->
</h:form>

And create a JavaScript function:

setInterval(function() {
        document.getElementById("idForm:idBoton").click()
    }, 3000); //cada 3 segundos, adáptalo a tus necesidades

If you use a library as PrimeFaces, consider that it already provides its own component to make poll (code adapted from the PrimeFaces examples page .

<h:form id="idForm">
    <h:outputText id="txtContador" value="#{bean.numero}" />
    <!--
        Cada 3 segundos ejecutar una petición y ejecutar
        de lado del servidor el método declarado en listener
    -->
    <p:poll interval="3" listener="#{bean.incrementar}"
        update="txtContador" />
</h:form>

Consider this as a simple example. Your server-side method can execute the necessary database calls. Also, you should measure the response time of the server and update the page to set the value of your interval.

There is another strategy called push, which consists of the server executing the operations in time intervals and notifying the client that it must be updated. BalusC (guru in Java and JSF) explains how to use push in JSF in this answer , partially translated:

  

Up to the new JSF 2.3 <f:websocket> ( issue 1396 ), the standard JSF library does not offer facilities for this. Needed to go to third-party libraries for now:

     

The new JSF component 2.3 <f:websocket> is widely based in <o:socket> .

For the description of your problem, in my opinion, I would use polling. In any case, it is up to you to evaluate the alternatives and choose the most convenient one to use.

    
answered by 06.06.2016 / 21:32
source
2

I give you an example of what the ajax code would look like:

function ajax() {          

        var oReq = new XMLHttpRequest();
        oReq.open("POST", "tufuncionphp.php", true);

        oReq.onload = function (oEvent) {
            if (oReq.status == 200) {
                document.getElementById("divobjetivo").innerHTML = oReq.responseText;
            }
        };
        oReq.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        oReq.send(datos);
}

I'll explain, for ajax to work, you always have to create an XMLHttpRequest type object.

The essential thing is that in the object.open, enter if it is POST or GET type and the URL of your PHP.

The object.onload function is executed when the PHP code has been executed. The method .responseText, collects the response text of PHP, and then you insert it where you want, in my example I leave it ready for you to put it in a field specified by an id. In the document.getElementById ("divobjective"), change the divobjective by the id of your item where you want to reload the information.

Finally, it is in object.send (), the fields you want to send are passed to simulate the sending of a form to PHP, in the format "data1 = data & data2 = data2".

If you want this to run every 5 seconds, you enter the code in a setInterval, just like that.

function ajax() {          
setInterval(function(){
        var oReq = new XMLHttpRequest();
        oReq.open("POST", "tufuncionphp.php", true);

        oReq.onload = function (oEvent) {
            if (oReq.status == 200) {
                document.getElementById("divobjetivo").innerHTML = oReq.responseText;
            }
        };
        oReq.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        oReq.send(datos);

},5000);
}

I hope to have explained myself well. Greetings.

    
answered by 06.06.2016 в 19:23
0

For that you have two options one is that just a moment before your query returns the result of the command to execute a select command where everything that has that table is called again. The other is the same form but using what with timers so that from time to time the sentence will be executed again.

    
answered by 13.06.2016 в 11:37