【问题标题】:How to use MySql Database queries in Spring Boot?如何在 Spring Boot 中使用 MySql 数据库查询?
【发布时间】:2018-10-10 07:18:45
【问题描述】:

我正在使用 Spring Boot 创建 API。在这个项目中,我使用了spring web、JPA、jstl和MySql作为API的依赖。在这个项目中,我创建了一个控制器、模型和存储库。基本上,这个 API 执行 CRUD 操作。当我使用 GET 请求时,我只想获取 3 列。但是,情况是我在此使用了 JPA,但我不知道如何使用自定义查询,例如

"SELECT devname,hrs,ot FROM imaginaryTable"

我该怎么做??

我的控制器类。

@RestController
@RequestMapping("/api")
public class ImController {

    @Autowired
    private ImRepository TaskRepository;

    @GetMapping("/projects")
    public List<ImModel> findAll() {
        return (List<ImModel>) TaskRepository.findAll();
    }

    @GetMapping("/developers/{id}")
    public ImModel findByName(@PathVariable final int id){
        return TaskRepository.findById(id);
    }

}

我的存储库界面。

package com.kisalka.pacrestapi.repository;

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

import com.kisalka.pacrestapi.model.ImModel;

public interface ImRepository extends JpaRepository<ImModel, Integer> {

    ImModel findById(int id);

}

【问题讨论】:

    标签: java mysql spring spring-boot spring-data-jpa


    【解决方案1】:

    您可以使用列作为构造函数的参数来创建对象。

    我会给你一个我自己的例子和我制作的自定义 DTO:

    @Query("SELECT new org.twinnation.site.dto.TitleAndDescriptionAndId(a.title, a.description, a.id) "
          + "FROM Article a")
    List<TitleAndDescriptionAndId> getAllArticlesWithoutContent();
    

    其中 DTO TitleAndDescriptionAndId 如下:

    public class TitleAndDescriptionAndId {
    
        private String title;
        private String description;
        private Long id;
    
    
        public TitleAndDescriptionAndId(String title, String description, Long id) {
            this.title = title;
            this.description = description;
            this.id = id;
        }
    
        // ...
    
    }
    

    【讨论】:

    • 在这里我有几个问题。 1.) 你从这封信 a 中是什么意思? 2.) 我应该在控制器中做什么??
    • FROM Article a。对象/表的名称是Article,我只是给它起了别名a。在你的情况下,你会写FROM ImModel im 并使用im 而不是a。从控制器中,您只需调用您在 ImRepository 中使用 DTO 创建的方法。
    • 它给了我这个错误 - 原因:org.hibernate.hql.internal.ast.QuerySyntaxException: ImModel 未映射 [SELECT new Manage(im.pname, im.devname, im.id) FROM ImModel im].. 我该如何解决这个问题??
    • 您需要包含完整路径。例如com.the.full.package.location.Manage(im.pname, im.devname, im.id)
    • 仍然,给我这个错误 - 原因:org.hibernate.hql.internal.ast.QuerySyntaxException: ImModel 未映射 [SELECT new com.kisalka.pacrestapi.model.Manage(im.pname , im.devname, im.id) FROM ImModel im]
    【解决方案2】:

    您可以在存储库中使用@Query("Your query") 注释来查询数据库。 例如

    @Query(value="SELECT devname,hrs,ot FROM imaginaryTable",nativeQuery=true)
    private List<Object> getValues();
    

    希望它能解决你的问题。

    【讨论】:

    • 如果您的返回类型是 'List',您可以获得这些值。我基于此编辑了我的答案。现在您可以获取 3 列值。
    【解决方案3】:

    您可以使用 Spring 对 Jackson 的 JSONView 的支持来自定义控制器中实体的 JSON 表示。

    https://spring.io/blog/2014/12/02/latest-jackson-integration-improvements-in-spring#json-views

        @JsonView(View.Summary.class)
        @GetMapping("/developers/{id}")
        public ImModel findByName(@PathVariable final int id){
            return TaskRepository.findById(id);
        }
    

    或者,您可以使用 Spring Data 的投影功能在存储库级别进行处理:

    https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections

        @GetMapping("/developers/{id}")
        public ImModelSummaryProjection findByName(@PathVariable final int id){
            return TaskRepository.someMethodReturningSummaryProjection(id);
        }
    

    【讨论】:

    • 我不明白这一点。如何使用“SELECT devname,hrs,ot FROM imaginaryTable”查询??
    • 您是否阅读过链接?对于选项 1,只需按您的操作方式加载实体(即无需编写查询)并在控制器、实体字段上添加必要的 JsonView 注释。
    • 我尝试在模型类中使用@JsonView(View.Summary.class),它给了我这个错误 - View.Summary 无法解析为一个类型。我现在能做什么??
    【解决方案4】:

    如 Spring Docs 中所述: Interface-based projections 将查询结果限制为仅公开名称属性的最简单方法是声明一个接口,该接口将为要读取的属性公开访问器方法。

    您可以创建interface 来限制结果

    interface LimitImaginaryTable {
      String getDevname();
      String getHrs();
      String getOt();
    }
    

    然后在您的repository 中,您可以使用该界面获得有限的结果

    public interface ImRepository extends JpaRepository<ImModel, Integer> {
    
        ImModel findById(int id);
        LimitImaginaryTable findById(int id);
        List<LimitImaginaryTable> findByDevname(String name);
    
    }
    

    现在您可以在Controller 中简单地获得所需的结果集

    List<LimitImaginaryTable> myList = taskRepository.findByDevname("JavaDev");
    

    【讨论】:

    • 好的,这很完美。但是,我只想获得所有开发人员的 3 列。在这种情况下,我不想在控制器中提供名称。我该怎么做??
    • 然后您可以简单地在您的存储库中创建更多方法List&lt;LimitImaginaryTable&gt; findAll() ;并在控制器中调用它List&lt;LimitImaginaryTable&gt; myList = taskRepository.findAll();
    • 现在我再次从 Db 获取所有数据。我该如何解决这个问题??
    • @Amithash 确保您在列表中使用LimitImaginaryTable List&lt;LimitImaginaryTable&gt; myList = taskRepository.findAll();
    • 是的,我使用了 List myList = taskRepository.findAll();在我的控制器中。但是,它给了我所有的数据。我不能修复这个吗??
    猜你喜欢
    • 1970-01-01
    • 2023-01-03
    • 2017-08-13
    • 2018-05-05
    • 1970-01-01
    • 2017-10-24
    • 1970-01-01
    • 2017-05-28
    • 2020-02-08
    相关资源
    最近更新 更多