如何在 SpringBoot 中使用复合主键从 MySql 中检索数据

How to retrive data from MySql in SpringBoot using composite primary keys

我正在开发一个简单的 spring 引导项目,以从 MySQL table 检索数据,其中 table 将具有复合主键。这是我的 MySQL 数据 table

id     date              temp

0  2018-12-01 10:20:12    35

1  2018-12-02 10:40:12    38

1  2018-12-01 10:20:12    40

在界面中,我创建了一个自己的方法来检索特定 ID 的数据集。但这显示如下错误:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'demoRepo': FactoryBean threw exception on object creation; nested exception is java.lang.IllegalStateException: Using named parameters for method public abstract java.util.List com.example.demo.DemoRepo.findAllByMyIdId(int) but parameter 'Optional[:id]' not found in annotated query 'from Sensor where myId.id=:id'!
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:176) ~[spring-beans-5.3.1.jar:5.3.1]
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:101) ~[spring-beans-5.3.1.jar:5.3.1]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1879) ~[spring-beans-5.3.1.jar:5.3.1]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getObjectForBeanInstance(AbstractAutowireCapableBeanFactory.java:1268) ~[spring-beans-5.3.1.jar:5.3.1]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:345) ~[spring-beans-5.3.1.jar:5.3.1]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.1.jar:5.3.1]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:671) ~[spring-beans-5.3.1.jar:5.3.1]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:659) ~[spring-beans-5.3.1.jar:5.3.1]
    at org.springframework.data.repository.config.DeferredRepositoryInitializationListener.onApplicationEvent(DeferredRepositoryInitializationListener.java:53) ~[spring-data-commons-2.4.1.jar:2.4.1]
    at org.springframework.data.repository.config.DeferredRepositoryInitializationListener.onApplicationEvent(DeferredRepositoryInitializationListener.java:35) ~[spring-data-commons-2.4.1.jar:2.4.1]
    at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:203) ~[spring-context-5.3.1.jar:5.3.1]
    at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:196) ~[spring-context-5.3.1.jar:5.3.1]
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:161) ~[spring-context-5.3.1.jar:5.3.1]
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:426) ~[spring-context-5.3.1.jar:5.3.1]
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:383) ~[spring-context-5.3.1.jar:5.3.1]
    at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:945) ~[spring-context-5.3.1.jar:5.3.1]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:591) ~[spring-context-5.3.1.jar:5.3.1]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:144) ~[spring-boot-2.4.0.jar:2.4.0]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:767) ~[spring-boot-2.4.0.jar:2.4.0]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759) ~[spring-boot-2.4.0.jar:2.4.0]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:426) ~[spring-boot-2.4.0.jar:2.4.0]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:326) ~[spring-boot-2.4.0.jar:2.4.0]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1309) ~[spring-boot-2.4.0.jar:2.4.0]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1298) ~[spring-boot-2.4.0.jar:2.4.0]
    at com.example.demo.DemoApplication.main(DemoApplication.java:10) ~[classes/:na]
Caused by: java.lang.IllegalStateException: Using named parameters for method public abstract java.util.List com.example.demo.DemoRepo.findAllByMyIdId(int) but parameter 'Optional[:id]' not found in annotated query 'from Sensor where myId.id=:id'!
    at org.springframework.data.jpa.repository.query.JpaQueryMethod.assertParameterNamesInAnnotatedQuery(JpaQueryMethod.java:157) ~[spring-data-jpa-2.4.1.jar:2.4.1]
    at org.springframework.data.jpa.repository.query.JpaQueryMethod.<init>(JpaQueryMethod.java:136) ~[spring-data-jpa-2.4.1.jar:2.4.1]
    at org.springframework.data.jpa.repository.query.DefaultJpaQueryMethodFactory.build(DefaultJpaQueryMethodFactory.java:44) ~[spring-data-jpa-2.4.1.jar:2.4.1]
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:81) ~[spring-data-jpa-2.4.1.jar:2.4.1]
    at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.lookupQuery(QueryExecutorMethodInterceptor.java:100) ~[spring-data-commons-2.4.1.jar:2.4.1]
    at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.lambda$mapMethodsToQuery(QueryExecutorMethodInterceptor.java:93) ~[spring-data-commons-2.4.1.jar:2.4.1]
    at java.base/java.util.stream.ReferencePipeline.accept(ReferencePipeline.java:195) ~[na:na]
    at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133) ~[na:na]
    at java.base/java.util.Collections$UnmodifiableCollection.forEachRemaining(Collections.java:1054) ~[na:na]
    at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801) ~[na:na]
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484) ~[na:na]
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474) ~[na:na]
    at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913) ~[na:na]
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:na]
    at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578) ~[na:na]
    at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.mapMethodsToQuery(QueryExecutorMethodInterceptor.java:95) ~[spring-data-commons-2.4.1.jar:2.4.1]
    at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.lambda$new[=12=](QueryExecutorMethodInterceptor.java:85) ~[spring-data-commons-2.4.1.jar:2.4.1]
    at java.base/java.util.Optional.map(Optional.java:258) ~[na:na]
    at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.<init>(QueryExecutorMethodInterceptor.java:85) ~[spring-data-commons-2.4.1.jar:2.4.1]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:303) ~[spring-data-commons-2.4.1.jar:2.4.1]
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet(RepositoryFactoryBeanSupport.java:326) ~[spring-data-commons-2.4.1.jar:2.4.1]
    at org.springframework.data.util.Lazy.getNullable(Lazy.java:230) ~[spring-data-commons-2.4.1.jar:2.4.1]
    at org.springframework.data.util.Lazy.get(Lazy.java:114) ~[spring-data-commons-2.4.1.jar:2.4.1]
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:271) ~[spring-data-commons-2.4.1.jar:2.4.1]
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:58) ~[spring-data-commons-2.4.1.jar:2.4.1]
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:169) ~[spring-beans-5.3.1.jar:5.3.1]
    ... 24 common frames omitted

对应的demoRepo接口class:

public interface DemoRepo extends JpaRepository<Sensor, MyId> {

    @Query("from Sensor where myId.id=:id")
    List<Sensor> findAllByMyIdId(@Param(":id") int id);
}

对应的型号class如下:

@Entity
@Table(name = "sensors")
public class Sensor {

    @EmbeddedId
    private MyId myId;
    private int temp;

    public Sensor() {
    }

    public Sensor(MyId myId, int temp) {
        this.myId = myId;
        this.temp = temp;
    }
     /*Getters and setters*/

@Embeddable
public class MyId implements Serializable {

    public int id;
    private String date;

    public MyId() {
    }

    public MyId(int id) {
        this.id = id;
    }

    public MyId(int id, String date) {
        this.id = id;
        this.date = date;
    }
/*Getters and Setters*/

在控制器class和服务class中获取特定id数据的相关方法如下:

@GetMapping("/sensors/{id}")
    public List<Sensor> getSensorData(@PathVariable int id){
        return demoService.getOneSensor(id);
    }

 public List<Sensor> getOneSensor(int id){
        List<Sensor> sensors = demoRepo.findAllByMyIdId(id);
        return sensors;
    }

我认为你的查询是错误的

而不是

              @Query("from Sensor where myId.id=:id")

应该是这样的

              @Query("Select * from Sensor where myId.id=id")

从此注释中删除冒号:@Param(":id")

冒号仅用于标记查询中的变量,它们不是参数名称的一部分。