web-dev-qa-db-fra.com

configuration automatique de démarrage de printemps avec le modèle jdbc

Je suis nouveau sur Spring et sur J2EE en général. J'ai du mal à utiliser le modèle JDBC avec la configuration automatique de Spring Boot.

Ce que j'ai fait, c'est que j'ai pris l'exemple du service Web RESTful fourni ici et décidé de l'étendre pour utiliser l'accès à la base de données relationnelle du modèle JDBC. Malheureusement, un autre exemple fourni ne peut pas être utile car la seule difficulté qui consiste à fournir dataSource à partir d'un fichier de beans xml n'est pas prise en compte.

Ce que j'ai essayé de résoudre le problème:

  1. Utilisation de la classe DAO Impl comme extension de différentes implémentations de Spring.
  2. Ajout au fichier beans.
  3. Utilisation de différentes classes DataSource (par exemple DriverManagerDataSource).
  4. Essayer de câbler automatiquement un simple attribut dans une classe différente (quelque chose de moins complexe que la source de données).
  5. Au début, je viens d'écrire la classe DAO, mais je pensais qu'il était peut-être possible de câbler automatiquement la source de données uniquement si elle implémente une interface, l'a essayée, n'a pas aidé.

J'ai essayé tout ce que j'ai trouvé sur Stack ou Google. La plupart des exemples sont sérieusement obsolètes ou sans réponse ou n'ont rien à voir avec Spring Boot Autoconfiguration et cetera.

Je continue de recevoir Property 'dataSource' is required erreur, après avoir lutté si finalement réussi à lier le application-config.xml fichier avec des beans, mais ne parvient pas à câbler automatiquement la source de données pour JDBC.

Je suis désespéré de le terminer et sérieusement bloqué, à défaut d'idées, je serais formidable si quelqu'un pouvait fournir un exemple récent qui fonctionne avec les configurations automatiques de Spring Boot, les beans dans la recherche XML, la source de données auto-câblée pour JDBC.

Ou au moins quelques idées, indices, même comment les chercher, car je n'ai même plus de mots clés pour google.

Merci!

enter image description here

Classe d'application Spring.

package ws;

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;

@Configuration
@ComponentScan
@ImportResource("classpath:spring/application-config.xml")
@EnableAutoConfiguration
public class Application {

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

Classe de service Web.

package ws;

import dao.UserDAOImpl;
import model.User;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestWS {
    @RequestMapping("/greeting")
    public User greeting(@RequestParam(value="name", defaultValue="World") String name) {
    return new User("ubububu", "661331555", 0);
    }
    @RequestMapping("/create")
    public String initialize() {
        UserDAOImpl users = new UserDAOImpl();
        users.init();
        return "seems ok";
    }
}

Interface DAO

package dao;

import model.User;

public interface UserDAO {
    public void insert(User usr);
    public void init();
    public User select(int id);
}

Implémentation DAO

package dao;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.stereotype.Repository;

import model.User;
import dao.UserDAO;

@Repository
public class UserDAOImpl implements UserDAO {
    private JdbcTemplate jdbcTemplate;
    private DriverManagerDataSource dataSource;
    @Autowired
    public void setDataSource(DriverManagerDataSource dataSource) {
        this.dataSource = dataSource;
    }

    public void insert(User usr) {
        String sql = "INSERT INTO USER " +
                "(USR_ID, EMAIL, PHONE) VALUES (?, ?, ?)";

        this.jdbcTemplate = new JdbcTemplate(dataSource);
        jdbcTemplate.execute(sql);
    }

    public void init() {
        String sql = "CREATE TABLE USER (USR_ID INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,EMAIL VARCHAR(30) NOT NULL,PHONE VARCHAR(15) NOT NULL)";
        this.jdbcTemplate = new JdbcTemplate(dataSource);
        jdbcTemplate.execute(sql);
    }
}

Modèle de données

package model;

public class User {
    private String email;
    private String phone;
    private int id;
    public User(String email, String phone, int id) {
        this.email = email;
        this.phone = phone;
        this.id = id;
    }
    public int getUsrId(){
        return this.id;
    }
    public String getUsrEmail() {
        return this.email;
    }
    public String getUsrPhone() {
        return this.phone;
    }
}

Fichier de bean de configuration

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <import resource="Spring-User.xml" />-->
    <context:component-scan base-package="ws"/>
    <bean id="ds" 
         class="org.springframework.jdbc.datasource.DriverManagerDataSource">

        <property name="driverClassName" value="org.springframework.jdbc.core.JdbcTemplate" />
        <property name="url" value="jdbc:mysql://localhost/:3306/databasename" />
        <property name="username" value="root" />
        <property name="password" value="password" />
    </bean>
    <bean id="UserDAOprovider" class="dao.UserDAOImpl">
        <property name="dataSource" ref="ds" />
    </bean> 

</beans>

Message d'erreur:

ERROR [dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is Java.lang.IllegalArgumentException: Property 'dataSource' is required] with root cause
Java.lang.IllegalArgumentException: Property 'dataSource' is required
    at org.springframework.jdbc.support.JdbcAccessor.afterPropertiesSet(JdbcAccessor.Java:135) ~[spring-jdbc-4.0.8.RELEASE.jar!/:4.0.8.RELEASE]
    at org.springframework.jdbc.core.JdbcTemplate.<init>(JdbcTemplate.Java:169) ~[spring-jdbc-4.0.8.RELEASE.jar!/:4.0.8.RELEASE]
    at dao.UserDAOImpl.init(UserDAOImpl.Java:66) ~[demo3-0.0.1-SNAPSHOT.jar!/:na]
    at ws.TestWS.initialize(TestWS.Java:30) ~[demo3-0.0.1-SNAPSHOT.jar!/:na]
    at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.6.0_33]
    at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:57) ~[na:1.6.0_33]
    at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:43) ~[na:1.6.0_33]
    at Java.lang.reflect.Method.invoke(Method.Java:622) ~[na:1.6.0_33]
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.Java:215) ~[spring-web-4.0.8.RELEASE.jar!/:4.0.8.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.Java:132) ~[spring-web-4.0.8.RELEASE.jar!/:4.0.8.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.Java:104) ~[spring-webmvc-4.0.8.RELEASE.jar!/:4.0.8.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.Java:749) ~[spring-webmvc-4.0.8.RELEASE.jar!/:4.0.8.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.Java:689) ~[spring-webmvc-4.0.8.RELEASE.jar!/:4.0.8.RELEASE]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.Java:83) ~[spring-webmvc-4.0.8.RELEASE.jar!/:4.0.8.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.Java:938) ~[spring-webmvc-4.0.8.RELEASE.jar!/:4.0.8.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.Java:870) ~[spring-webmvc-4.0.8.RELEASE.jar!/:4.0.8.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.Java:961) ~[spring-webmvc-4.0.8.RELEASE.jar!/:4.0.8.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.Java:852) ~[spring-webmvc-4.0.8.RELEASE.jar!/:4.0.8.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.Java:620) ~[Tomcat-embed-core-7.0.57.jar!/:7.0.57]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.Java:837) ~[spring-webmvc-4.0.8.RELEASE.jar!/:4.0.8.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.Java:727) ~[Tomcat-embed-core-7.0.57.jar!/:7.0.57]
    at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:303) ~[Tomcat-embed-core-7.0.57.jar!/:7.0.57]
    at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:208) ~[Tomcat-embed-core-7.0.57.jar!/:7.0.57]
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.Java:77) ~[spring-web-4.0.8.RELEASE.jar!/:4.0.8.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107) ~[spring-web-4.0.8.RELEASE.jar!/:4.0.8.RELEASE]
    at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:241) ~[Tomcat-embed-core-7.0.57.jar!/:7.0.57]
    at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:208) ~[Tomcat-embed-core-7.0.57.jar!/:7.0.57]
    at org.Apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.Java:220) ~[Tomcat-embed-core-7.0.57.jar!/:7.0.57]
    at org.Apache.catalina.core.StandardContextValve.invoke(StandardContextValve.Java:122) ~[Tomcat-embed-core-7.0.57.jar!/:7.0.57]
    at org.Apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.Java:503) ~[Tomcat-embed-core-7.0.57.jar!/:7.0.57]
    at org.Apache.catalina.core.StandardHostValve.invoke(StandardHostValve.Java:170) ~[Tomcat-embed-core-7.0.57.jar!/:7.0.57]
    at org.Apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.Java:103) ~[Tomcat-embed-core-7.0.57.jar!/:7.0.57]
    at org.Apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.Java:116) ~[Tomcat-embed-core-7.0.57.jar!/:7.0.57]
    at org.Apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.Java:421) ~[Tomcat-embed-core-7.0.57.jar!/:7.0.57]
    at org.Apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.Java:1070) ~[Tomcat-embed-core-7.0.57.jar!/:7.0.57]
    at org.Apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.Java:611) ~[Tomcat-embed-core-7.0.57.jar!/:7.0.57]
    at org.Apache.Tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.Java:1736) ~[Tomcat-embed-core-7.0.57.jar!/:7.0.57]
    at org.Apache.Tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.Java:1695) ~[Tomcat-embed-core-7.0.57.jar!/:7.0.57]
    at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java:1146) ~[na:1.6.0_33]
    at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:615) ~[na:1.6.0_33]
    at org.Apache.Tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.Java:61) ~[Tomcat-embed-core-7.0.57.jar!/:7.0.57]
    at Java.lang.Thread.run(Thread.Java:701) ~[na:1.6.0_33]
15
Marek

La façon la plus simple de configurer une source de données dans Spring Boot est de créer un fichier application.properties sous src/main/resources avec le contenu suivant (il peut être nécessaire de le mettre à jour avec une URL, un nom d'utilisateur et un mot de passe corrects):

spring.datasource.url=jdbc:mysql://localhost/:3306/databasename
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

Spring Boot créera automatiquement la classe DataSource pour vous et l'injectera à d'autres beans. Par conséquent, vous n'aurez plus besoin du fichier de configuration xml et vous pourrez vous débarrasser de cette ligne dans la classe Application:

@ImportResource("classpath:spring/application-config.xml")

De plus, dans UserDAOImpl Spring peut câbler automatiquement l'objet JdbcTemplate à l'aide du bean DataSource ( http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-sql.html# boot-features-using-jdbc-template ) vous n'avez donc pas besoin d'en créer un à chaque appel de la méthode insert ().

Quant à la méthode init () dans UserDAOImpl, vous pouvez créer un fichier schema.sql sous src/main/resources et y déplacer l'instruction CREATE TABLE (pour plus de détails, voir http://docs.spring.io/ spring-boot/docs/1.2.0.RELEASE/reference/htmlsingle/# howto-intialize-a-database-using-spring-jdbc )

Voir cet exemple pour plus d'informations: http://xantorohara.blogspot.ca/2013/11/spring-boot-jdbc-sample.html

31
kaviddiss