Dev (Back & Front)ARTIGO

Usando Quartz com Hibernate

Olá, pessoal! No artigo de hoje eu vou apresentar a API Quartz. O objetivo é mostrar como o Quartz é simples de usar. E para contextualizar, decidi que criaremos um job que terá como trabalho popular um banco a cada X time. Nesse caso, vamos usar o Hibernate para fazer o job. O Quartz nada mais é que um scheduler de jobs, que podem ser executados em determinados momentos. No decorrer do artigo veremos como ele funciona na prática.

Para usar o Quartz, basta fazer o download do jars(quartz-all.x.jar) e adicionar ao projeto. Adicione as libs do Hibernate e banco de dados (aqui usaremos o MySQL) ao projeto também.

Desenvolvimento

Para usar o Quartz, vamos criar um package br.com.camilolopes.scheduler. Nele teremos uma classe responsável por executar os jobs programados. No package br.com.camilolopes.job é onde está a classe que tem um trabalho a ser feito, que no nosso caso é persistir no banco de dados.Já o package br.com.camilolopes.dao tem as configurações para o Hibernate que não está atrelado ao quartz.

Primeiro passo

Vamos começar com a classe SchedulerJobs no package br.com.camilolopes.scheduler, onde vamos definir os jobs a serem executados e o time para eles. Como esta classe será a principal, ela terá o método main.

Trigger trigger = TriggerUtils.makeSecondlyTrigger(30);
trigger.setName("jobdb");
/*dou informacoes qual classe ele deve chamar
ou seja, o trabalho a ser feito
*/
JobDetail jobDetail = new JobDetail("save db", PersistDB.class);
try{
Scheduler scheduler = new StdSchedulerFactory().getScheduler();
//info o job a ser feito e de em qto em qto tempo passando o trigger
scheduler.scheduleJob(jobDetail, trigger);
//peco para iniciar
scheduler.start();
}catch (SchedulerException e) {
e.printStackTrace();
}

  • Trigger – esta classe é responsável por configurar o tempo em que cada job será executado – nesse caso configuramos para a cada trinta segundos. Veja que usamos a classe TriggerUtils, que já possui alguns metodos implementados. Em seguida, damos um nome para esse trigger.
  • JobDetail – é aqui que temos o job a ser executado – nesse caso mandamos executar o job que está na classe PersistDB.class. Veja que lhe damos um nome.
  • Scheduler – aqui é onde temos uma instância de um scheduler que será responsavel por executar o job, e como criamos uma instância de uma factory, precisamos apenas informar o job e o tempo no qual ele deverá ser executado – nesse caso, é a variavel de JobDetail e o time que definimos em Trigger. Para iniciar o job, chamamos o metodo start().

 Na classe a serguir, teremos que criar um usuário e chamar o método save(), responsável por fazer o trabalho de persistência no banco de dados.

public class PersistDB implements Job{

@Override
public void execute(JobExecutionContext arg0) throws JobExecutionException {
UsuarioQuartzDao usuariodao = new UsuarioQuartzDao();
Usuario usuario = new Usuario();
usuario.setEmail("camilo@");
usuario.setNome("lopesff");
usuario.setSenha("123");
usuario.setTipo("admin");
usuariodao.save(usuario);
System.out.println(new Date());
}
}

A classe que possui o job a ser feito precisa implementar a interface Job e colocar o trabalho dentro do metodo execute().

 Classe DAO:

public class UsuarioQuartzDao extends DAO {

public void save(Usuario us){
begin();
getSession().save(us);
try{
commit();
}catch (Exception e) {
e.printStackTrace();
}
}
}

Na classe acima é onde ocorre a persistência com o banco usando o Hibernate. Quero lembrá-los de pedir para o Hibernate criar a table e a cada vez que o job rodar, ele não vai criar uma nova table e sim adicionar os dados. Para isso, seu arquibo hibernate.cfg.xml deve ter um update no hb2mddl.auto.

<property name="hibernate.hbm2ddl.auto">update</property>

O code completo:


<property name="hibernate.connection.driver_class">org.gjt.mm.mysql.Driver</property>
<property name="hibernate.connection.password">blog</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost/blogleitores</property>
<property name="hibernate.connection.username">camilolopes</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<mapping class="br.com.camilolopes.bean.Usuario"/>

Resultado

Ao executar o code, temos os resultado conforme a seguir:

Observe que o Job é executado dentro do tempo e o trabalho de persistir de fato acontece. Um fato que identifiquei é que, se o job demorar mais que o tempo configurado, o próximo job tem que aguardar o outro finalizar para iniciar o trabalho dele. Outro detalhe: se configurarmos o método shutdown (true), após o termino de todos os jobs, o scheduler é “desligado” e os trabalhos não são mais reiniciados. No nosso exemplo, ele roda de maneira infinita.

Fico por aqui e espero que tenham gostado do artigo. Tenho usado o Quartz em algumas soluções e de fato é uma API excelente. Além de uma boa documentação, o fórum é bem ativo para tirar duvidas.

é Bacharel em Sistemas de Informação e Especialista em Gestão e Estratégia de Negócios. Trabalha com TI desde 2003 e possui as certificações SCJP 5 e SCM. Trabalhou na IBM Brasil como Analista Programador Java, passou pelo laboratório da Enterprise Computing Lab (ECL) HP como Software Engineer, Ci&amp;T como Engenheiro de Software em projeto JEE. Tem experiência internacional em Índia, Dubai e Londres. Atualmente é cofundador da ITSLabs (www.itslabs.com.br), uma start-up focada na criação de produtos web e mobile para start-ups. Também é autor dos livros "Guia do Exame SCJP", "Guia Prático JEE com Frameworks" e "TDD na prática".

Ver perfil