Integração do site Webix e Struts com banco de dados

É a última parte do tutorial que fala sobre o desenvolvimento de um site usando a biblioteca Webix UI e o framework Java Struts 2 . Se você ainda não leu as partes anteriores, verifique a primeira e a segunda partes no blog do Webix.

Hoje em dia ninguém está interessado em dados estáticos. É por isso que nosso site deve ser capaz de baixar uma lista de eventos e relatórios do banco de dados e salvar todas as alterações implementadas. Usaremos o banco de dados MySQL mais popular.

A estrutura do banco de dados é simples. Está representado na imagem abaixo. Usaremos duas tabelas para armazenar eventos e relatórios. Cada registro na tabela “alto-falantes” contém o event_id ao qual um determinado relatório está relacionado.

Cenário

Use as seguintes solicitações para criar o banco de dados:

CREATE TABLE IF NOT EXISTS `events` (
`id` bigint(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`description` text NOT NULL,
`date` date NOT NULL,
`location` varchar(255) NOT NULL,
`photo` varchar(255) NOT NULL,
PRIMARY KEY
(`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=7 ;

INSERT INTO
`events` (`id`, `name`, `description`, `date`, `location`, `photo`) VALUES

(1, 'Front-end #1', 'We will consider different aspects of web app development: Promises, AntiAliasing, HTML-import, using DevTools at the upcoming event in detail! We are waiting for you! ', '2014-06-06', 'Minsk,Сentralnaya str.1, Blue conference hall', 'frontend1.png'),
(2, 'Front-end #2', 'Interesting reports on Front-end development that will be presented by real gurus of JavaScript-programming!', '2014-06-20', 'Minsk,Сentralnaya str.1, Blue conference hall', 'frontend2.png'),
(3, 'Front-end #3', 'Interesting reports on Front-end development that will be presented by real gurus of JavaScript-programming!', '2014-07-04', 'Minsk,Сentralnaya str.1, Blue conference hall', 'frontend3.png'),
(4, 'Front-end #4', 'Interesting reports on Front-end development that will be presented by real gurus of JavaScript-programming!', '2014-07-18', 'Minsk,Сentralnaya str.1, Blue conference hall', 'frontend4.png'),
(5, 'Front-end #5', 'Interesting reports on Front-end development that will be presented by real gurus of JavaScript-programming!', '2014-08-01', 'Minsk,Сentralnaya str.1, Blue conference hall', 'frontend5.png'),
(6, 'Front-end #6', 'Interesting reports on Front-end development that will be presented by real gurus of JavaScript-programming!', '2014-08-15', 'Minsk,Сentralnaya str.1, Blue conference hall', 'frontend6.png'),

CREATE TABLE IF NOT EXISTS
`speakers` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`author` varchar(255) NOT NULL,
`topic` varchar(255) NOT NULL,
`photo` varchar(255) NOT NULL,
`event_id` bigint(20) NOT NULL,
`description` text NOT NULL,
PRIMARY KEY
(`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=7 ;

INSERT INTO
`speakers` (`id`, `author`, `topic`, `photo`, `event_id`, `description`) VALUES
(1, 'Iron Man' , 'JavaScript Promises - There and Back Again', 'ironman.jpg', 1, 'One of the new features that browser developers are preparing for us together with the developers who write specifications of JavaScript Promises is that this template of writing asynchronous code popular with lots of users gets native support. What’s the point of Promises and how to deal with them?'),

(2, ‘Hulk’, ‘Evitando reprocessamento desnecessário’, ‘halk.jpg’, 2, ‘Renderizar elementos para um site ou aplicativo pode levar muito tempo e pode ter um impacto negativo no desempenho. Vamos considerar o razões para renderizar novamente em um navegador e aprender como evitar chamadas desnecessárias. ‘),
(3,’ Homem-Aranha ‘,’ Usando seu terminal a partir do DevTools ‘,’ spiderman.jpg ‘, 1,’ O Terminal DevTools é um nova extensão do Chrome que fornece a funcionalidade de linha de comando diretamente no seu navegador. ‘),
(4,’ Thor ‘,’ Animações de alto desempenho ‘,’ thor.jpg ‘, 2,’ Mergulhe fundo em obter animações mais rápidas em seus projetos. Vamos descobrir por que os navegadores modernos podem facilmente animar as seguintes propriedades: posição, escala, rotação, opacidade. ‘),
(5, ‘Batman’, ‘Anti-aliasing. Basics’, ‘batman.jpg’, 1, ‘Uma introdução ao anti-aliasing, explicando como formas vetoriais e texto são renderizados suavemente.’),
(6, ‘Capitão América’, ‘HTML -Importar ‘,’ captainamerica.jpg ‘, 1,’ A importação de HTML é uma forma de incluir alguns documentos HTML em outros. Você também não está limitado à marcação. Você também pode incluir CSS, JavaScript ou qualquer outro arquivo .html pode conter. ‘);

O Hibernate é freqüentemente usado para trabalhar com banco de dados em Java. O Hibernate é uma biblioteca de mapeamento objeto-relacional para a linguagem Java. Para simplificar, trabalhamos com registros de banco de dados como com objetos, enquanto o Hibernate é responsável por solicitações, salvamento e carregamento.

Para começar a usar o Hibernate, você precisa adicionar dependências hibernate-core e mysql-driver mysql-connector-java no arquivo pom.xml :

<dependencies>

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.5.Final</version>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependencies>

Depois disso, você precisa executar o “Projeto Maven- Update” para fazer o Maven baixar as novas bibliotecas.

Vamos criar um arquivo de configuração src / main / resources / hibernate.cfg.xml :

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">


<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/myapp</property>
<property name="hibernate.connection.useUnicode">true</property>
<property name="hibernate.connection.characterEncoding">UTF-8</property>
<property name="hibernate.connection.charSet">UTF-8</property>
<property name="connection.username">root</property>
<property name="connection.password"></property>
<property name="connection.pool_size">1</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="current_session_context_class">thread</property>
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">validate</property>

<mapping class="com.myapp.model.Event" />
<mapping class="com.myapp.model.Speaker" />
</session-factory>
</hibernate-configuration>

Configuramos a conexão com o banco de dados neste arquivo:

  • connection.url – a string de conexão ao banco de dados no formato jdbc: driver: // host: porta / dbname.
  • connection.username – nome de usuário do banco de dados
  • connection.password – senha do usuário do banco de dados

Também especificamos as classes que serão vinculadas ao banco de dados no arquivo src / main / resources / hibernate.cfg.xml . No nosso caso, essas classes são Evento e Palestrante. Isso significa que um objeto da classe Event corresponderá a um registro na tabela “events” do banco de dados. A mesma lógica se aplica à classe Palestrante.

A classe Event já existe, mas precisa ser editada. Você deve adicionar anotações para especificar a qual tabela de banco de dados a classe será associada e como as propriedades da classe se relacionam com as colunas da tabela:

 package com.myapp.model;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

import org.apache.struts2.json.annotations.JSON;

@Entity
@Table(name="events")
public class Event {

private Long id;
private String name;
private String description;
private Date date;
private String location;
private String photo;

public Event() {

}

public Event(Long id, String name, String description, Date date, String location, String photo) {
this.id = id;
this.name = name;
this.description = description;
this.date = date;
this.location = location;
this.photo = photo;
}

@Id
@GeneratedValue
@Column(name="id")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}

@Column(name="name")
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@Column(name="description", columnDefinition="TEXT")
public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}

@Column(name="date")
@JSON(format = "yyyy-MM-dd")
public Date getDate() {
return date;
}

public void setDate(Date date) {
this.date = date;
}

@Column(name="location")
public String getLocation() {
return location;
}

public void setLocation(String location) {
this.location = location;
}

@Column(name="photo")
public String getPhoto() {
return photo;
}

public void setPhoto(String photo) {
this.photo = photo;
}

}

A anotação @Table (name = ”events”) antes da declaração da classe especifica a tabela que será usada enquanto a anotação @Column (name = ”location”) antes da propriedade “location” especifica qual campo do banco de dados corresponde a esta propriedade.

Vamos criar a classe Palestrante por analogia:

 package com.myapp.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="speakers")
public class Speaker {

private Long id;
private String author;
private String topic;
private String description;
private String photo;
private Long event_id;

public Speaker() {

}

public Speaker(Long id, String author, String topic, String description, String photo, Long event_id) {
this.id = id;
this.author = author;
this.topic = topic;
this.description = description;
this.photo = photo;
this.event_id = event_id;
}

@Id
@GeneratedValue
@Column(name="id")
public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

@Column(name="author")
public String getAuthor() {
return author;
}

public void setAuthor(String author) {
this.author = author;
}

@Column(name="topic")
public String getTopic() {
return topic;
}

public void setTopic(String topic) {
this.topic = topic;
}

@Column(name="description", columnDefinition="TEXT")
public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}

@Column(name="photo")
public String getPhoto() {
return photo;
}

public void setPhoto(String photo) {
this.photo = photo;
}

@Column(name="event_id")
public Long getEvent_id() {
return event_id;
}

public void setEvent_id(Long event_id) {
this.event_id = event_id;
}
}

Para trabalhar com o Hibernate você precisa de uma classe que criará uma fábrica de sessão ou retornará uma sessão existente. Crie esta classe no pacote com.myapp.util e nomeie-a HibernateUtil :

package com.myapp.util;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {

private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
return new Configuration()
.configure() // configures settings from hibernate.cfg.xml
.buildSessionFactory();
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}

Para manipular objetos de banco de dados devemos criar as classes EventsManager e SpeakersManager. Colocaremos essas classes no pacote com.myapp.controller. Essas classes são responsáveis ​​por: selecionar uma lista de eventos / relatórios (o método de lista ), selecionar os três últimos registros (o método lastList ), selecionar os registros por um identificador ( getById ), adicionar um novo registro (o método de inserção ), editar registros existentes (o método de atualização ), excluindo um registro (o método de exclusão ).

EventsManager.java:

package com.myapp.controller;

import java.util.List;
import org.hibernate.HibernateException;
import