Arquivos de sites

Como persistir LocalDate e LocalDateTime do Java 8 com JPA

E ai galera beleza? faz muito tempo que eu não postava nada novo, então bora com “novidade” do java 8 + JPA 😀

O Java 8 trouxe muitas grandes funcionalidades e uma das mais importantes e uma das antecipadas foi a nova API de data e hora. Haviam muitos problemas com a antiga API e não vou entrar em detalhes do porque nós precisamos de uma nova. Tenho certeza que você teve que lutar com ela com frequencia.

Todos esses problemas se foram com Java 8 \o/. A nova API de data e hora é bem desenhada, fácil de usar e (finalmente) imutável. O único problema que permanece é, que você não pode usava com JPA.

Bem, isso não totalmente verdade. Você pode usa-la, porém o JPA irá mapeá-la para BLOB ao invés de DATE ou TIMESTAMP. Que significa que a base de dados não está ciente do objeto de data e não pode aplicar nenhuma otimização para isso. E não é desse jeito que deveríamos ou gostaríamos de fazê-lo.

Porque o JPA não suporta LocalDate e LocalDateTime?

A resposta é simples, o JPA 2.1 foi liberado antes do Java 8 e a API de data e hora simplesmente não existia naquela época. Portanto a anotação @Temporal pode apenas ser aplicada a atributos do tipo java.util.Date e java.util.Calendar.

Se você deseja armazenar um atributo LocalDate em uma coluna Date ou uma LocalDateTime em uma coluna TIMESTAMP, você mesmo precisa definir o mapeamento para java.sql.Date ou java.sql.Timestamp. Graças ao conversor de atributo, uma das diversas novas funcionalidades do JPA 2.1, isso pode ser alcançado com apenas algumas linhas de código.

Nos exemplos abaixo, eu vou mostrar pra vocês como criar um conversor de atributos para LocalDate e LocalDateTime. Se você quer aprender mais sobre conversor de atributo, dê uma olhada aqui (inglês).

O exemplo

Antes de nós criar os conversores de atributo, vamos dar uma olhada na entidade de exemplo para esse post:

@Entity
public class MyEntity {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = “id”, updatable = false, nullable = false)
private Long id;

@Column
private LocalDate date;

@Column
private LocalDateTime dateTime;

}

O conversor de atributo faz parte da especificação do JPA 2.1 e pode portanto ser usado com qualquer implementação de JPA 2.1, ex.: Hibernate ou EclipseLink. Eu usei Wildfly 8.2 com Hibernate 4.3 para os seguintes exemplos.

Convertendo LocalDate

Como você pode ver no seguinte pedaço de código, não é necessário muita coisa para criar um conversor de atributo para LocalDate.

@Converter(autoApply = true)
public class LocalDateAttributeConverter implements AttributeConverter<LocalDate, Date> {

@Override
public Date convertToDatabaseColumn(LocalDate locDate) {
return (locDate == null ? null : Date.valueOf(locDate));
}

@Override
public LocalDate convertToEntityAttribute(Date sqlDate) {
return (sqlDate == null ? null : sqlDate.toLocalDate());
}
}

Você precisa implementar a interface AttributeConverter<LocalDate, Date> e seus 2 métodos convertToDatabaseColumn e convertToEntityAttribute. Como você pode ver nos nomes dos métodos, um deles define a conversão do tipo do atributo da entidade (LocalDate) para o tipo de coluna da base de dados (Date) e o outro é a conversão inversa. A conversão em si é simples porque java.sql.Date ja nos provê o método para fazer a conversão “de” e “para” um LocalDate.

Adicionalmente o conversor de atributo precisa ser anotado com a anotação @Converter. Devido a propriedade opcional autoApply=true, o conversor será aplicado a todos os atributos do tipo LocalDate. Dê uma olhada aqui (inglês), se você quer definir o uso de cada conversor para cada atributo individualmente.

A conversão do atributo é transparente para o desenvolvedor e o atributo LocalDate pode ser usado como qualquer outro atributo da entidade. Você pode usa-lo como parâmetro de query por exemplo.

LocalDate date = LocalDate.of(2015, 8, 11);
TypedQuery<MyEntity> query = this.em.createQuery(“SELECT e FROM MyEntity e WHERE date BETWEEN :start AND :end”, MyEntity.class);
query.setParameter(“start”, date.minusDays(2));
query.setParameter(“end”, date.plusDays(7));
MyEntity e = query.getSingleResult();

Convertendo LocalDateTime

O conversor de atributo para LocalDateTime é basicamente o mesmo. Você precisa implementar a interface attributeConverter<LocalDateTime, Timestamp> e o conversor precisa ser anotado com a anotação @Converter. Assim como o LocalDateConverter, a conversão entre LocalDateTime e um java.sql.Timestamp é feita através dos métodos de conversão do Timestamp.

@Converter(autoApply = true)
public class LocalDateTimeAttributeConverter implements AttributeConverter<LocalDateTime, Timestamp> {

@Override
public Timestamp convertToDatabaseColumn(LocalDateTime locDateTime) {
return (locDateTime == null ? null : Timestamp.valueOf(locDateTime));
}

@Override
public LocalDateTime convertToEntityAttribute(Timestamp sqlTimestamp) {
return (sqlTimestamp == null ? null : sqlTimestamp.toLocalDate());
}
}

Conclusão

O JPA 2.1 foi liberado antes do Java 8 e portanto não suporta a nova API de data e hora. Se você quer usar as novas classes (do jeito certo), você mesmo precisa definir a conversão para java,sql.Date e java.sql.Timestamp. Isso pode ser feito facilmente implementando a interface AttributeConverter<EntityType, DatabaseType> e anotando a classe com a anotação @Converter(autoApply=true). Setando autoApply=true, a conversão será aplicada a todos os atributos do EntityType e nenhuma alteração na entidade é necessária.

Até onde eu sei, a próxima versão do JPA suportará a nova API de data e hora e as diferentes implementações provavelmente irão suporta-la ainda mais cedo. O Hibernate 5 por exemplo irá suporta-la como uma funcionalidade proprietária.

É isso ai galera, espero tê-los ajudado 😀

Fonte: thoughts-on-java.org – Thorben Janssen

jQuery – Pegando e atribuindo atributos [attr()]

No capítulo anterior, nós vimos como foi fácil pegar e atribuir conteúdo texto e HTML de/para um elemento. Felizmente, modificar um ou mais atributos de um elemento é igualmente fácil. Nós usamos o método attr() para isso, que na forma mais simples recebe um parâmetro: O nome do atributo que nós desejamos pegar:

<a href="http://www.google.com" id="aGoogle1">Google Link</a>
<script type="text/javascript">
$(function()
{
        alert($("#aGoogle1").attr("href"));
});
</script>

Neste exemplo, nós pegamos o valor do atributo “href” do nosso link e então mostramos ele ao usuário. Para mudar um atributo, nós simplesmente especificamos um parâmetro extra:

<a href="http://www.google.com" id="aGoogle2">Google Link</a>
<script type="text/javascript">
$(function()
{
        $("#aGoogle2").attr("href", "http://www.google.co.uk");
});
</script>

Isso irá mudar o link para apontar para versão britânica do Google. O método att() pode também receber um mapa de pares nome/valor, para atribuir múltiplos atributos ao mesmo tempo. Aqui nós atribuímos ambos atributos href e title simultâneamente:

<a href="http://www.google.com" id="aGoogle3">Google Link</a>
<script type="text/javascript">
$(function()
{
        $("#aGoogle3").attr(
        { 
                "href" : "http://www.google.co.uk", 
                "title" : "Google.co.uk"
        });
});
</script>

O método attr() também suporta a sobrecarga especial onde o parâmetro  de valor é em vez disso uma função de callback, permitindo você acessar o índice do element selecionado assim como o valor do atributo existente. Aqui está um exemplo disso:

<a href="http://www.google.com/">Google.com</a><br />
<a href="http://www.google.co.uk/">Google UK</a><br />
<a href="http://www.google.de/">Google DE</a><br />
<script type="text/javascript">
$(function()
{
        $("a.google").attr("href", function(index, oldValue)
        {
                return oldValue + "imghp?tab=wi";
        });
});
</script>

Nós simplesmente mudamos todos os links do Google para apontar para a busca de imagem ao invés da página padrão, adicionando um parâmetro extra ao atributo href. Nesse exemplo nós não usamos realmente o parâmetro índice, mas nós poderíamos se nós precisássemos, para nos dizer qual índice na lista de elementos selecionados nós estamos atualmente lidando.

Fonte: jquery-tutorial.net

jQuery – Introdução a manipulação do DOM – Pegando e atribuindo conteúdo [text(), html() and val()]

Introdução a manipulação do DOM

Um dos mais importantes aspectos do JavaScript e desse modo jQuery, é a manipulação do DOM. O DOM significa Document Object Model (Modelo de Objeto de Documento) e é um mecanismo para representação e interação com nossos documentos HTML, XHTML ou XML. Ele lhe permite navegar e manipular seus documentos através de uma linguagem de programação, que no navegador será quase sempre JavaScript. A navegação e manipulação do DOM usando o JavaScript padrão pode muito complicado, mas felizmente para nós, o jQuery vem com um monte de métodos relacionado ao DOM, fazendo isso tudo muito mais fácil.

No primeiro exemplo “Hello, world!” desse tutorial, nós comparamos o trabalho de encontrar um elemento e atribuir um texto a ele usando primeiro jQuery e então JavaScript. Esta é apenas a ponta do iceberg, porém, e nos capítulos seguintes você verá como é fácil manipular o conteúdo dos seus documentos com jQuery.

Pegando e atribuindo conteúdo [text(), html() and val()]

O aspecto mais simples da manipulação do DOM é recuperar e atribuir text (texto), valores (valores) e HTML. Essas três coisas podem parecer a mesma coisa, mas elas não são. Text é uma representação literal (sem HTML) do conteúdo interno para todos os elementos normais, values são para elementos de formulário e HTML é o mesmo que text, mas incluindo qualquer marcação (markup).

Felizmente para nós, o jQuery vem com um método para cara um dos três, nos permitindo recuperar e atribuir essas propriedades: Os métodos text(), html() e val(). Aqui está um pequeno exemplo que mostrará a você a diferença entre eles e como eles são simples de usar:

<div id="divTest">
        <b>Test</b>
        <input type="text" id="txtTest" name="txtTest" value="Input field" />
</div>
<script type="text/javascript">
$(function()
{
        alert("Text: " + $("#divTest").text());
        alert("HTML: " + $("#divTest").html());
        alert("Value: " + $("#divTest").val());
        
        alert("Text: " + $("#txtTest").text());
        alert("HTML: " + $("#txtTest").html());
        alert("Value: " + $("#txtTest").val());
});
</script>

Então uma chamada  para um desses métodos sem parâmetros irá simplesmente retornar a propriedade desejada, Se nós queremos atribuir a propriedade em vez disso, nós simplesmente especificamos um parâmetro extra. Aqui está um exemplo completo:

<div id="divText"></div>
<div id="divHtml"></div>
<input type="text" id="txtTest" name="txtTest" value="Input field" />

<script type="text/javascript">
$(function()
{
        $("#divText").text("A dynamically set text");
        $("#divHtml").html("<b><i>A dynamically set HTML string</i></b>");
        $("#txtTest").val("A dynamically set value");
});
</script>

E isso é o quão fácil é para atribuir texto, HTML e valores.

Essas três funções vêm com uma sobrecarga a mais, onde você especifica uma função de callback como primeiro e único parâmetro. Essa função de callback será chamada com dois parâmetros pela jQuery, o índice do elemento corrente na lista de elementos selecionados, assim como o valor existente, antes dele ser substituído com um novo valor. Você então retorna a string que você deseja usar como o novo valor para função. Essa sobrecarga funciona para ambos html(), text() e val(), mas por motivo de simplicidade, nós apenas usamos a versão do text() neste exemplo:

<p>Paragraph 1</p>
<p>Paragraph 2</p>
<p>Paragraph 3</p>
<script type="text/javascript">
$(function()
{
        $("p").text(function(index, oldText) {
                return "Existing text: " + oldText + ". New text: A dynamically set text (#" + index + ")";
        });
});
</script>

Nós começamos com três elementos de parágrafos semelhantes, que o texto é a única diferença deles. No código jQuery, nós selecionamos todos eles e então usamos a versão especial do método text() para substituir o texto atual com um novo texto construído, baseado nos dois parâmetros que jQuery fornece a nós: O índice do elemento atual e também o seu texto atual. Esse novo texto é então retornado ao jQuery, que irá substituir texto atual pelo novo.

Fonte: jquery-tutorial.net / jquery-tutorial.net

jQuery – Animações customizadas com o método animate()

Nos capítulos anteriores, nós vimos dentro dos métodos de efeitos embutidos fading e sliding do jQuery. Porém, você pode muito mais que isso. Com o método animated(), você pode criar animações customizada onde você manipula quase qualquer propriedade CSS numérica de um elemento. Isso permite você por exemplo mover uma caixa devagar através uma tela ou subir ou descer. Vamos tentar alguma coisa muito simples:

<div style="height: 60px;">
        <div id="divTestBox1" style="height: 50px; width: 50px; background-color: #89BC38; position: absolute;"></div>
</div>
<script type="text/javascript">
$(function()
{
        $("#divTestBox1").animate(
                {
                        "left" : "200px"
                }
        );
});
</script>

O primeiro, e único necessário, parâmetro da função animated é o mapa das propriedades do CSS que você deseja que seja alterado. Nesse caso, nós temos um elemento div absolutamente posicionado, que nós dissemos ao jQuery para mover até ele alcançar 200 pixels na propriedade left.
O segundo parâmetro permite você especificar a duração da animação em milissegundos ou como “slow” ou “fast” que é o mesmo de 600 ou 200ms. Com isso, nós podemos diminuir o exemplo acima mais do que nós queremos:

<div style="height: 60px;">
        <div id="divTestBox2" style="height: 50px; width: 50px; background-color: #89BC38; position: absolute;"></div>
</div>
<script type="text/javascript">
$(function()
{
        $("#divTestBox2").animate(
                {
                        "left" : "200px"
                }, 
                5000
        );
});
</script>

Com o terceiro parâmetro, nós podemos especificar uma função de callback para ser chamada uma vez que a  animação terminar. Isso pode ser bastante útil para executar um número diferente de animações em uma fila. Por exemplo, veja esse exemplo:

<div style="height: 40px;">
        <div id="divTestBox3" style="height: 20px; width: 20px; background-color: #89BC38; position: absolute;"></div>
</div>
<script type="text/javascript">
$(function()
{
        $("#divTestBox3").animate(
                { "left" : "100px" }, 
                1000,
                function()
                {
                        $(this).animate(
                                { "left" : "20px" },
                                500,
                                function()
                                {
                                        $(this).animate({ "left" : "50px" }, 500);
                                }
                        )
                }
        );
});
</script>

Isso pode parecer um pouco repetitivo, mas o que nós fazemos é que nós chamamos o método animado e perguntamos pela propriedade left da nossa “div” de teste para ser animada até ela alcançar 100 pixels no left. Nós queremos que isso leve 1 segundo (1000 milissegundos) e uma vez que isso se complete, nós desejamos que uma nova animação comece, que mova isso de volta para 20 pixels dentro de meio segundo, e assim que ESSA animação finalize, nós movemos ela um pouco para direito de novo, então agora ela tem uma propriedade left de 50 pixels.

Porém, desde que o jQuery vem com funcionalidade de fila para animações, você pode normalmente realizar o exemplo acima de um modo muito mais simples. Isso entretanto, apenas se aplica quando você quer um conjunto de animações executadas após cada uma – se você quer fazer outra coisa quando uma animação estiver completa, o exemplo acima será ainda o caminho a ser seguido. Aqui está uma versão de fila:

<div style="height: 40px;">
        <div id="divTestBox4" style="height: 20px; width: 20px; background-color: #89BC38; position: absolute;"></div>
</div>
<script type="text/javascript">
$(function()
{
        $("#divTestBox4").animate({ "left" : "100px" }, 1000);
        $("#divTestBox4").animate({ "left" : "20px" }, 500);
        $("#divTestBox4").animate({ "left" : "50px" }, 500);
});
</script>

Fonte: jquery-tutorial.net

jQuery – Fading de elementos (Exibir/Esconder)

Fazer simples animação é muito fácil com jQuery. Um desses efeitos é o fading em um elemento, para exibí-lo ou escondê-lo. Aqui está um simples exemplo, onde nós exibimos uma caixa escondida, usando o método fadeIn():

<div id="divTestArea1" style="padding: 50px; background-color: #89BC38; text-align: center; display: none;">
        <b>Hello, world!</b>
</div>
<a href="javascript:void(0);" onclick="ShowBox();">Show box</a>
<script type="text/javascript">
function ShowBox()
{
        $("#divTestArea1").fadeIn();
}
</script>

Você pode dar um fade em um monte de elementos diferentes, como divs, spans ou links. O método fadeIn() pode receber três parâmetros. O primeiro permite você especificar a duração do efeito em milissegundos, ou “fast” (rápido) ou “slow” (devagar), que é o mesmo que especificar 200 ou 600 milissegundos. Aqui está um exemplo disso em uso:

<div id="divTestArea21" style="width: 50px; height: 50px; display: none; background-color: #89BC38;"></div>
<div id="divTestArea22" style="width: 50px; height: 50px; display: none; background-color: #C3D1DF;"></div>
<div id="divTestArea23" style="width: 50px; height: 50px; display: none; background-color: #9966FF;"></div>
<a href="javascript:void(0);" onclick="ShowBoxes();">Show boxes</a>
<script type="text/javascript">
function ShowBoxes()
{
        $("#divTestArea21").fadeIn("fast");
        $("#divTestArea22").fadeIn("slow");
        $("#divTestArea23").fadeIn(2000);
}
</script>

Não se importe com todo o HTML, está lá apenas para que você possa ver a diferença entre as durações do fading. Agora, o segundo parâmetro pode ser o nome de uma função de atenuação (que nós não vamos usar nesse tutorial) ou uma função de callback que você pode fornecer, para ser chamada uma vez que o efeito terminar. Aqui está um exemplo disso, combinado com o uso do método fadeOut(), que obviamente tem o efeito reverso do fadeIn():

<div id="divTestArea3" style="width: 50px; height: 50px; display: none; background-color: #89BC38;"></div>
<script type="text/javascript">
$(function()
{
        $("#divTestArea3").fadeIn(2000, function()
        {
                $("#divTestArea3").fadeOut(3000);
        });
});
</script>

Pode ter situações onde você quer esconder ou exibir um element dependendo do estado corrente do mesmo. Você poderia com certeza checar se ele está visível ou não, e então chamar ou fadeIn() ou fadeOut(), mas os desenvolvedores legais do jQuery tem nos fornecido um método específico para alternar (toggling) um elemento, chamado fadeToggle().  Ele leva os mesmo parâmetros como fadeIn() e fadeOut(), então ele é muito fácil de usar. Aqui está um pequeno exemplo:

<div id="divTestArea4" style="width: 50px; height: 50px; display: none; background-color: #89BC38;"></div><br />
<a href="javascript:void(0);" onclick="ToggleBox();">Toggle box</a>
<script type="text/javascript">
function ToggleBox()
{
        $("#divTestArea4").fadeToggle("slow");  
}
</script>

E isso é quão fácil é usar os efeitos de fading do jQuery.

Fonte: jquery-tutorial.net