2016-12-28 145 views
0

我試圖創建一個框架來使用Spring Data從MySQL讀取數據。最終目標是能夠編寫自動化測試,可以從兩個不同的MySQL數據庫中讀取數據並比較數據(例如,確保數據正確複製)。我目前在實際獲取Spring代碼時遇到了很多麻煩(我之前從未使用Spring,我嘗試過修改我在網上找到的一些各種教程代碼,但到目前爲止還沒有得到它工作。)使用Spring Boot數據讀取MySQL數據

這是我得到的。

MySQL 表:憑證 列:id(int),password_hash(字符串) 其中有4個條目。

項目佈局:

src/main 
    groovy 
    domain 
     Credentials 
    repository 
     CredentialsRepository 
    resources 
    application.properties 
src/test/groovy/ 
    CredentialsTest 

的build.gradle

buildscript { 
    repositories { 
     mavenCentral() 
    } 
    dependencies { 
     classpath("org.springframework.boot:spring-boot-gradle-plugin:1.4.3.RELEASE") 
    } 
} 

apply plugin: 'java' 
apply plugin: 'eclipse' 
apply plugin: 'idea' 
apply plugin: 'org.springframework.boot' 

jar { 
    baseName = 'gs-accessing-data-jpa' 
    version = '0.1.0' 
} 

repositories { 
    mavenCentral() 
    maven { url "https://repository.jboss.org/nexus/content/repositories/releases" } 
} 

sourceCompatibility = 1.8 
targetCompatibility = 1.8 

dependencies { 
    compile 'org.codehaus.groovy:groovy-all:2.4.7' 
    compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: '1.4.3.RELEASE' 
    compile group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: '1.4.3.RELEASE' 
    testCompile 'junit:junit:4.11' 
} 

application.properties

spring.datasource.url=jdbc:mysql://localhost:3306/my_db 
spring.datasource.username=my_user 
spring.datasource.password=my_password 
spring.datasource.driver-class-name=com.mysql.jdbc.Driver 
spring.jpa.properties.hibernate.show_sql=true 
spring.jpa.properties.hibernate.use_sql_comments=true 
spring.jpa.properties.hibernate.format_sql=true 

Credentials.groovy

package domain 

import org.springframework.data.annotation.Id 

import javax.persistence.Column 
import javax.persistence.Entity 
import javax.persistence.GeneratedValue 
import javax.persistence.GenerationType 
import javax.persistence.Table 

@Entity 
@Table(name = 'credentials') 
class Credentials { 
    @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name='id') 
    int id 

    @Column(name='password_hash') 
    String passwordHash 

    protected Credentials() {} 

    @Override 
    String toString() { 
     "Credential: [id=${id}, passwordHash=${passwordHash}]" 
    } 
} 

CredentialsRepository.groovy

package repository 

import domain.Credentials 
import org.springframework.data.repository.CrudRepository 

interface CredentialsRepository extends CrudRepository<Credentials, Integer> { 
} 

CredentialsTest.groovy

import domain.Credentials 
import repository.CredentialsRepository 
import org.junit.Test 
import org.junit.runner.RunWith 
import org.springframework.beans.factory.annotation.Autowired 
import org.springframework.boot.test.context.SpringBootTest 
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner 

import static org.junit.Assert.assertEquals 

@RunWith(SpringJUnit4ClassRunner.class) //@EnableJpaRepositories(['domain.Credentials']) 
@SpringBootTest(classes = MysqlJpaDemoApplication.class) 
class CredentialsTest { 
    @Autowired 
    CredentialsRepository credentialsRepository 

    @Test 
    void testLoadCredentials() { 
     List<Credentials> credentialsList = credentialsRepository.findAll() as ArrayList<Credentials> 
     assertEquals(20, credentialsList.size()) 
    } 
} 

運行在testLoadCredentials試驗給出了以下堆棧跟蹤:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'CredentialsTest': Unsatisfied dependency expressed through field 'credentialsRepository'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'repository.CredentialsRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} 

    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588) 
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1225) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:386) 
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:118) 
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83) 
    at org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener.prepareTestInstance(SpringBootDependencyInjectionTestExecutionListener.java:44) 
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:230) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:228) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:287) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:289) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:247) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) 
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191) 
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137) 
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) 
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51) 
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:237) 
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147) 
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'repository.CredentialsRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1474) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1102) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1064) 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585) 
    ... 33 more 

2016-12-28 14:14:32.638 INFO 39748 --- [  Thread-1] s.c.a.AnnotationConfigApplicationContext : Closing org.spring[email protected]742ff096: startup date [Wed Dec 28 14:14:32 PST 2016]; root of context hierarchy 

Process finished with exit code 255 
+0

有些事情我已經試過: *添加'@ Repository'到CredentialsRepository接口 *添加'@EnableJpaRepositories([ 'domain.Credentials'])'到CredentialsTest類 *使用'@使用主要方法的應用程序類上的SpringBootApplication' 這些都不適合我。 – drusolis

+0

這個工程:https://spring.io/guides/gs/accessing-data-jpa/。這個問題可能是由於JUnit沒有適當地連接bean。 – duffymo

+0

我之前正在使用該教程,但無法使其工作。如果我使用此代碼:我收到一個錯誤,指出符號參數無法解析。如果我刪除ARGS部分是這樣的: @Bean CommandLineRunner演示(CredentialsRepository庫){ log.info( 「!我做的東西」) 爲(證書CRED:倉庫){ log.info( cred.toString()) } } 我得到:'型的沒有合格豆 'repository.CredentialsRepository' 可供選擇:預計將有至少1 Bean上有資格作爲自動裝配candidate.' – drusolis

回答

1

貌似這是得到它的工作:

com.example/ 
    domain/ 
    Credentials 
    repository/ 
    CredentialsRepository 
    SpringConfig 

憑據。常規

@Entity 
@Table(name = 'credentials') 
class Credentials { 
    @Id @GeneratedValue(strategy = GenerationType.AUTO) 
    int id 

    @Column(name='password_hash') 
    String passwordHash 

    protected Credentials() {} 

    @Override 
    String toString() { 
     "Credential: [id=${id}, passwordHash=${passwordHash}]" 
    } 
} 

CredentialsRepository

interface CredentialsRepository extends CrudRepository<Credentials, Integer> {} 

SpringConfig.groovy

@Configuration 
@EnableAutoConfiguration 
@ComponentScan('com.example') 
class SpringConfig {} 

CredentialsTest.groovy

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(classes=SpringConfig.class) 
@SpringBootTest(classes = SpringConfig.class) 
class CredentialsTest { 

    @Autowired 
    CredentialsRepository credentialsRepository 

    @Test 
    void testLoadCredentials() { 
     List<Credentials> credentialsList = credentialsRepository.findAll() as ArrayList<Credentials> 
     assertEquals(4, credentialsList.size()) 
    } 
} 
1

看來,應用程序類MysqlJpaDemoApplication您使用配置您的測試是在默認(頂層)封裝。由於Spring在使用@ComponentScan時會執行一些檢查,因此它將阻止您的應用程序掃描整個類路徑。

你應該將MysqlJpaDemoApplication移動到一個新的包,即com.example。源文件夾應該是這樣的:

src/main 
    /groovy/com/example 
    |-- /domain 
    | |-- Credentials.groovy 
    |-- /repository 
    | |-- CredentialsRepository.groovy 
    |-- MysqlJpaDemoApplicatin.groovy