首页 > 解决方案 > 如何在春季使用 JPA 存储库从服务器检索 blob

问题描述

我已经为 CRUD 创建了 spring 应用程序。我可以轻松地写入服务器数据,如字符串、长、blob,但是当我尝试从服务器检索它时。我遇到了服务器的哪个字节数组在服务器的 BigInteger 中给出的困难。我如何才能在字节数组中而不是 BigInteger 中获取数据?当我在插入字节数组中写入此数据时,哪一列是 BLOB。这是我的代码

存储库

public interface ArriveRepository extends JpaRepository<ArriveEntity,Long>
{ 
    @Query(value = "select arrive.time,air_lines.image,arrive.flight,arrive.destination_uzb," +
            "arrive.destination_eng,arrive.destination_rus,arrive.status,arrive.status_time " +
            "from arrive inner join air_lines on air_lines.id = arrive.airline_id where arrive.arrive_date = (:date1)",nativeQuery = true)
    List<Object[]> getForArriveTerminal(@Param("date1") LocalDate date1);
}

当我从服务器检索数据时,我正在使用这个类

到达终点站Dto

public class ArriveTerminalDto {
   private String time;
   private BigInteger logo;
   private String flight;
   private String destinationUzb;
   private String destinationEng;
   private String destinationRus;
   private String status;
   private String statusTime;
  //getter setter}

服务等级

  public List<ArriveTerminalDto> getToShow(LocalDate date1)
    {
        List<ArriveTerminalDto> list = new ArrayList<>();
        List<Object[]> list1 = arriveRepository.getForArriveTerminal(date1);
        for(Object[] objects: list1)
        {
            ArriveTerminalDto arriveTerminalDto = new ArriveTerminalDto();
            arriveTerminalDto.setTime((String)objects[0]);
            arriveTerminalDto.setLogo((BigInteger) objects[1]);
            arriveTerminalDto.setFlight((String) objects[2]);
            arriveTerminalDto.setDestinationUzb((String) objects[3]);
            arriveTerminalDto.setDestinationRus((String) objects[4]);
            arriveTerminalDto.setDestinationEng((String) objects[5]);
            arriveTerminalDto.setStatus((String) objects[6]);
            list.add(arriveTerminalDto);
        }
        return list;
    }

这段代码有效,但它没有给我来自服务器的字节数组。当我尝试将 BigInteger 更改为 byte[] 数组时,它给了我来自邮递员的以下错误

{
    "timestamp": "2019-01-28T09:33:52.038+0000",
    "status": 500,
    "error": "Internal Server Error",
    "message": "java.math.BigInteger cannot be cast to [B",
    "path": "/arrive/terminal/date=2019-01-27"
}

将对象更改为 ArriveTerminalDto 但它仍然给我的以下回购错误

public interface ArriveRepository extends JpaRepository<ArriveEntity,Long>
{

    @Query(value = "select arrive.time,air_lines.image,arrive.flight,arrive.destination_uzb," +
            "arrive.destination_eng,arrive.destination_rus,arrive.status,arrive.status_time " +
            "from arrive inner join air_lines on air_lines.id = arrive.airline_id where arrive.arrive_date = (:date1)",nativeQuery = true)
    List<ArriveTerminalDto> getForArriveTerminal(@Param("date1") LocalDate date1);
}

标签: javaspringrestservicespring-data-jpa

解决方案


你为什么不看看Spring Content社区项目。该项目允许您将内容与 Spring Data 实体相关联。想想 Spring Data,但对于内容或非结构化数据。这也可以为您提供内容的 REST 端点,例如 Spring Data REST。

这种方法将为您的内容提供清晰的抽象,并实现许多不同类型的存储。它是基于流的,而不是基于字节的。如果您想传输非常大的文件,使用 byte[] 将不起作用。让数据库正确流式传输也是非常特殊的。当 Spring Content 已经有了时,您可能不想自己弄清楚所有这些。

这很容易添加到您现有的项目中。我不确定您是否正在使用 Spring Boot。我将给出一个非弹簧启动示例:

pom.xml

   <!-- Java API -->
   <dependency>
      <groupId>com.github.paulcwarren</groupId>
      <artifactId>spring-content-jpa</artifactId>
      <version>0.5.0</version>
   </dependency>
   <!-- REST API (if you want it) -->
   <dependency>
      <groupId>com.github.paulcwarren</groupId>
      <artifactId>spring-content-rest</artifactId>
      <version>0.5.0</version>
   </dependency>

配置

@Configuration
@EnableJpaStores
@Import("org.springframework.content.rest.config.RestConfiguration.class")
public class ContentConfig {

    // schema management
    // 
    @Value("/org/springframework/content/jpa/schema-drop-mysql.sql")
    private Resource dropContentTables;

    @Value("/org/springframework/content/jpa/schema-mysql.sql")
    private Resource createContentTables;

    @Bean
    DataSourceInitializer datasourceInitializer() {
        ResourceDatabasePopulator databasePopulator =
                new ResourceDatabasePopulator();

        databasePopulator.addScript(dropContentTables);
        databasePopulator.addScript(createContentTables);
        databasePopulator.setIgnoreFailedDrops(true);

        DataSourceInitializer initializer = new DataSourceInitializer();
        initializer.setDataSource(dataSource());
        initializer.setDatabasePopulator(databasePopulator);

        return initializer;
    }
}

要关联内容,请将 Spring Content 注释添加到您的帐户实体。

到达实体.java

@Entity
public class ArriveEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    .. existing fields...    


    @ContentId
    private String contentId;

    @ContentLength
    private long contentLength = 0L;

    // if you have rest endpoints
    @MimeType
    private String mimeType = "text/plain";
}

创建一个“商店”:

ArrivEntityContentStore.java

@StoreRestResource(path="arriveEntityContent)
public interface ArrivEntityContentStore extends ContentStore<ArriveEntity, String> {
}

这就是创建 REST 端点 @ 所需的全部内容/arriveEntityContent。当您的应用程序启动时,Spring Content 将查看您的依赖项(查看 Spring Content JPA/REST),查看您的ArrivEntityContentStore接口并为 JPA 注入该接口的实现。它还将注入一个@Controller将http请求转发到该实现的。这使您不必自己实施任何这些,我认为这就是您所追求的。

所以...

要使用 Java API 访问内容,请自动连接ArrivEntityContentStore并使用它的方法。

或者使用 REST API 访问内容:

curl -X POST /arriveEntityContent/{arriveEntityId}

使用 multipart/form-data 请求将图像存储在数据库中,并将其与 id 为的帐户实体相关联itemId

curl /arriveEntityContent/{arriveEntityId}

将再次获取它等等...支持完整的 CRUD。

这里有一些入门指南。参考指南在这里这里有一个教程视频。编码位从大约 1/2 处开始。

高温高压


推荐阅读