Spring MVC Acceso a datos

Anteriormente creamos una serie de tutoriales dedicados al acceso a datos con Spring Framework, ahora veremos como podemos integrar las tecnologías de datos en una aplicación Spring Web MVC, nos centraremos en la tecnología Spring Data JPA utilizando el ORM Hibernate y el motor de datos integrado HSQLDB, aunque lo aprendido se puede aplicar fácilmente a otros tecnologías.

Todos los conceptos aplicados en este tutorial ya los hemos visto en tutoriales anteriores por lo que la explicación será breve, si deseas información mas detallada puedes dirigirte a los correspondientes tutoriales, en el siguiente enlace encontrarás una lista de todos ellos: Tutoriales Spring Framework.

La configuración del Servlet la haremos programáticamente, sin XML, tratamos este tema en el tutorial Configurar Spring MVC con Java, la clase correspondiente es la siguiente:

public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{RootAppConfig.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{WebAppConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}

La clase WebAppConfig contiene la configuración web y la clase RootAppConfig la configuración de acceso a datos, veamos primero la configuración del WebApplicationContext.

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"carmelo.spring.controller"})
public class WebAppConfig {

    @Bean
    public ViewResolver getInternalResourceViewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        return resolver;
    }
}

Esta configuración también al hemos visto en tutoriales anteriores, lo siguiente que veremos será la configuración de acceso a datos, para ello tenemos la siguiente clase:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories("carmelo.spring.repository")
@ComponentScan("carmelo.spring.service")
public class RootAppConfig {

    @Bean
    public DataSource dataSource() {
        return new EmbeddedDatabaseBuilder()
                .setType(EmbeddedDatabaseType.HSQL)
                .addDefaultScripts()
                .generateUniqueName(true)
                .build();
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean factoryBean
                = new LocalContainerEntityManagerFactoryBean();
        factoryBean.setDataSource(dataSource());
        factoryBean.setJpaVendorAdapter(jpaVendorAdapter());
        factoryBean.setPackagesToScan("carmelo.spring.model");
        factoryBean.setPersistenceUnitName("spring-data-pun");
        return factoryBean;
    }

    @Bean
    public JpaVendorAdapter jpaVendorAdapter() {
        HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
        jpaVendorAdapter.setGenerateDdl(false);
        jpaVendorAdapter.setDatabase(Database.HSQL);
        return jpaVendorAdapter;
    }

    @Bean
    public PlatformTransactionManager transactionManager() {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
        return transactionManager;
    }
}

La explicación de esta clase la tenemos disponible en la seria de tutoriales Spring IoC Acceso a Datos, de manera breve configuramos una base de datos HSQLDB como fuente de datos, para las operaciones de acceso a datos usamos el ORM Hibernate JPA.

Para crear las tablas de nuestra base de datos tenemos el siguiente script:

CREATE TABLE Customer(
    ID INTEGER PRIMARY KEY, 
    FirstName VARCHAR(20),
    LastName VARCHAR(30), 
    Street VARCHAR(50), 
    City VARCHAR(25));

CREATE TABLE Product(
    ID INTEGER PRIMARY KEY, 
    Name VARCHAR(30), 
    Price DOUBLE);

Agregamos datos a estas tablas con este otro script:

INSERT INTO Customer VALUES(0,'Laura','Steel','429 Seventh Av.','Dallas');
INSERT INTO Product  VALUES(0,'Iron Iron',54);
INSERT INTO Customer VALUES(1,'Susanne','King','366 - 20th Ave.','Olten');
INSERT INTO Product  VALUES(1,'Chair Shoe',248);
INSERT INTO Customer VALUES(2,'Anne','Miller','20 Upland Pl.','Lyon');
INSERT INTO Product  VALUES(2,'Telephone Clock',248);
INSERT INTO Customer VALUES(3,'Michael','Clancy','542 Upland Pl.','San Francisco');
INSERT INTO Product  VALUES(3,'Chair Chair',254);
INSERT INTO Customer VALUES(4,'Sylvia','Ringer','365 College Av.','Dallas');
INSERT INTO Product  VALUES(4,'Ice Tea Shoe',128);
INSERT INTO Customer VALUES(5,'Laura','Miller','294 Seventh Av.','Paris');
INSERT INTO Product  VALUES(5,'Clock Clock',236);
INSERT INTO Customer VALUES(6,'Laura','White','506 Upland Pl.','Palo Alto');
INSERT INTO Product  VALUES(6,'Ice Tea Chair',98);
INSERT INTO Customer VALUES(7,'James','Peterson','231 Upland Pl.','San Francisco');
INSERT INTO Product  VALUES(7,'Telephone Shoe',84);
INSERT INTO Customer VALUES(8,'Andrew','Miller','288 - 20th Ave.','Seattle');
INSERT INTO Product  VALUES(8,'Ice Tea Clock',226);
INSERT INTO Customer VALUES(9,'James','Schneider','277 Seventh Av.','Berne');
INSERT INTO Product  VALUES(9,'Clock Telephone',172);
INSERT INTO Customer VALUES(10,'Anne','Fuller','135 Upland Pl.','Dallas');
INSERT INTO Product  VALUES(10,'Telephone Ice Tea',204);

Con todo esto tenemos la siguiente estructura de proyecto:

spring mvc con acceso a datos

En el paquete carmelo.spring.model almacenaremos las entidades JPA para las tablas Product y Customer, las clases tendrán el mismo nombre, primero la clase Product:

@Data
@Entity
public class Product {

    @Id private Long id;
    private String name;
    private Double price;
}

Usamos la anotación @Data de Lombok para simplificar la creación de nuestras clases, la siguiente entidad es la clase Customer.

@Data
@Entity
public class Customer {

    @Id private Long id;
    
    private String firstName;
    private String lastName;
    private String street;
    private String city;
}

En el paquete carmelo.spring.repository encontraremos los repositorios JPA, estos son los encargados de las operaciones de acceso a datos, por ejemplo, para la clase Product tenemos:

public interface ProductRepository extends CrudRepository<Product, Long> {
    List<Product> findByPriceGreaterThan(Double price);
}

En el paquete carmelo.spring.service tenemos la capa de servicios.

@Service
public class ProductServiceImpl implements ProductService {

    @Autowired
    private ProductRepository product;

    @Override
    public Iterable<Product> productList() {
        return product.findAll();
    }

    @Override
    public void productDelete(Long id) {
        this.product.delete(id);
    }

    @Override
    public void productAdd(Product product) {
        this.product.save(product);
    }

    @Override
    public Long productCount() {
        return this.product.count();
    }
}

Tenemos lo siguiente:spring mvc con spring data jpa

Como vemos en este tutorial aplicamos todo lo aprendido previamente, este proyecto se usará como base para próximos tutoriales Spring MVC, inmediatamente puede ir al tutorial Spring MVC con Vistas JSP y JSTL donde veremos como crear una vista que nos permitirá interactuar con la tabla Product.

Comentarios

Entradas populares de este blog

Conectar SQL Server con Java

Detección de rostros

Instalar OpenCV para Python en Windows