Connessione a MySQL in Vaadin con Java, Spring Boot e Flow

Mattepuffo's logo
Connessione a MySQL in Vaadin con Java, Spring Boot e Flow

Connessione a MySQL in Vaadin con Java, Spring Boot e Flow

Vaadin è un fullstack framework per Java e Kotlin che ci mette a disposizione alcune opzioni sia per il back end che per il front end.

In questo articolo vediamo come connetterci ad un db MySQL usando questa configuazione:

  • Java
  • Spring Boot per il back end
  • Flow per il front end --> Flow ci permette di costruire la parte di front end direttamente in Java (non entro nel merito se sia buono o no)

Per interagire con il db ho usato JPA, ma non è obbligatorio.

Ho usanto anche Lombock, non è obbligatorio in generale, ma ve lo consiglio.

Quindi queste le dipendenze da aggiungere a Maven:

<dependency>
  <groupId>com.mysql</groupId>
  <artifactId>mysql-connector-j</artifactId>
  <scope>runtime</scope>
</dependency>

<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <version>1.18.36</version>
  <scope>provided</scope>
</dependency>

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

Questa la configurazione per il db da mettere nell'application.properties:

spring.datasource.url=jdbc:mysql://HOST:3306/DB_NOME
spring.datasource.username=USER
spring.datasource.password=PWD
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
spring.jpa.hibernate.ddl-auto=update
spring.jpa.defer-datasource-initialization=true
spring.sql.init.mode=always

Se avete già usato Spring Boot sapete di che parlo.

Questa l'entity che rappresenta la tabella:

package com.test.data;

import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@Entity
@Table(name = "persone")
public class Persona {

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private int id;

  private String nome;

  private String email;
}

Questo il repository:

package com.test.data;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

public interface PersonaRepository
    extends
    JpaRepository<Persona, Long>,
    JpaSpecificationExecutor<Persona> {
}

Il service:

package com.test.services;

import com.test.data.Persona;
import com.test.data.PersonaRepository;

import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

@Service
public class PersonaService {

  @Autowired
  PersonaRepository repository;

  public Page<Persona> list(Pageable pageable) {
    return repository.findAll(pageable);
  }

}

Adesso la "novità" rispetto ad altri articoli che abbiamo visto, la parte grafica.

Come dicevo ho usato Flow in questo caso, quindi la view sarà scritta in Java:

package com.test.views.myview;

import com.test.data.Persona;
import com.test.services.PersonaService;
import com.vaadin.flow.component.Composite;
import com.vaadin.flow.component.dependency.Uses;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.grid.GridVariant;
import com.vaadin.flow.component.icon.Icon;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.spring.data.VaadinSpringDataHelpers;
import org.springframework.beans.factory.annotation.Autowired;

@PageTitle("My View")
@Route("")
@Uses(Icon.class)
public class MyViewView extends Composite<VerticalLayout> {

  @Autowired
  private PersonaService personaService;

  public MyViewView() {
    Grid<Persona> stripedGrid = new Grid<>(Persona.class);
    getContent().setWidth("100%");
    getContent().getStyle().set("flex-grow", "1");
    stripedGrid.addThemeVariants(GridVariant.LUMO_ROW_STRIPES);
    stripedGrid.setWidth("100%");
    stripedGrid.getStyle().set("flex-grow", "0");
    setGridSampleData(stripedGrid);
    getContent().add(stripedGrid);
  }

  private void setGridSampleData(Grid<Persona> grid) {
    grid.setItems(query -> personaService.list(VaadinSpringDataHelpers.toSpringPageRequest(query)).stream());
  }

}

Infine l'entry point:

package com.test;

import com.test.data.PersonaRepository;
import com.vaadin.flow.component.page.AppShellConfigurator;
import com.vaadin.flow.theme.Theme;

import javax.sql.DataSource;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.sql.init.SqlDataSourceScriptDatabaseInitializer;
import org.springframework.boot.autoconfigure.sql.init.SqlInitializationProperties;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
@Theme(value = "test-vaadin-flow")
public class Application implements AppShellConfigurator {

  public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
  }

  @Bean
  SqlDataSourceScriptDatabaseInitializer dataSourceScriptDatabaseInitializer(
      DataSource dataSource,
      SqlInitializationProperties properties,
      PersonaRepository repository
  ) {
    return new SqlDataSourceScriptDatabaseInitializer(dataSource, properties) {
      @Override
      public boolean initializeDatabase() {
        if (repository.count() == 0L) {
          return super.initializeDatabase();
        }
        return false;
      }
    };
  }
}

Enjoy!


Condividi

Commentami!