Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/379.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用springframework.data.jpa.repository.Query查找两个日期和时间之间的所有结果_Java_Hibernate_Jpa_Spring Data Jpa_Spring Data - Fatal编程技术网

Java 如何使用springframework.data.jpa.repository.Query查找两个日期和时间之间的所有结果

Java 如何使用springframework.data.jpa.repository.Query查找两个日期和时间之间的所有结果,java,hibernate,jpa,spring-data-jpa,spring-data,Java,Hibernate,Jpa,Spring Data Jpa,Spring Data,我正在为这样一个简单的任务而挣扎,我不知道我做错了什么 基于个人研究,我似乎在编码我应该做的事情,以便使用Spring数据搜索两个日期之间的所有记录。据我所知,“@Temporal(TemporalType.DATE)”具有“魔力” 存储库 import java.math.BigDecimal; import java.util.Date; import java.util.List; import javax.persistence.TemporalType; import org.sp

我正在为这样一个简单的任务而挣扎,我不知道我做错了什么

基于个人研究,我似乎在编码我应该做的事情,以便使用Spring数据搜索两个日期之间的所有记录。据我所知,“@Temporal(TemporalType.DATE)”具有“魔力”

存储库

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import javax.persistence.TemporalType;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.jpa.repository.Temporal;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import com.mybank.accountmanagement.model.Transaction;

    @Repository
    public interface TransactionRepository extends JpaRepository<Transaction, Long> {
    
        
@Query(value = "SELECT * FROM transactions WHERE account_id=:idAccount AND CAST(created_at AS date) BETWEEN :fromDate AND :toDate ", nativeQuery = true)
List<Transaction> findByAccountIdWithCreationDateBetween(@Param("idAccount") Long idAccount,
        @Param("fromDate") @Temporal(TemporalType.DATE) Date fromDate,
        @Param("toDate") @Temporal(TemporalType.DATE) Date toDate);
        
    }
审计模型

package com.mybank.accountmanagement.model;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;

@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
@JsonIgnoreProperties(value = { "createdAt", "updatedAt" }, allowGetters = true)
public abstract class AuditModel implements Serializable {
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "created_at", nullable = false, updatable = false)
    @CreatedDate
    private Date createdAt;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "updated_at", nullable = false)
    @LastModifiedDate
    private Date updatedAt;

    public Date getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(Date createdAt) {
        this.createdAt = createdAt;
    }

    public Date getUpdatedAt() {
        return updatedAt;
    }

    public void setUpdatedAt(Date updatedAt) {
        this.updatedAt = updatedAt;
    }
}
在搜索“from date”:“2020-08-02”、“toDate”:“2020-08-02”时,我要返回的内容

但它没有返回任何记录

***编辑

由于某种未知原因,我的记录与fromDate和toDate的确切日期匹配,因此从结果中标记出来

  • 使用较长的fromDate和toDate进行搜索

    curl--location--request GET'localhost:2000/transaction/1/bankstatement'--header'Content-Type:application/json'--data-raw'{ “起始日期”:“2020-08-01”, “toDate”:“2020-08-03” }"

  • 带来两项记录:

    [
        {
            "createdAt": "2020-08-02T16:29:08.085+00:00",
            "updatedAt": "2020-08-02T16:29:08.085+00:00",
            "id": 1,
            "amount": 1.00,
            "transactionType": 2,
            "accoout_id": 1
        },
        {
            "createdAt": "2020-08-02T16:29:11.185+00:00",
            "updatedAt": "2020-08-02T16:29:11.185+00:00",
            "id": 2,
            "amount": 2.00,
            "transactionType": 1,
            "accoout_id": 1
        }
    ]
    
    到目前为止还不错

  • 现在我在搜索确切日期时遇到了一个问题。我希望从上面的查询中得到相同的结果

    curl--location--request GET'localhost:2000/transaction/1/bankstatement'--header'Content-Type:application/json'--data-raw'{ “起始日期”:“2020-08-02”, “toDate”:“2020-08-02” }"

  • 毫无结果

    ***编辑。由于Kavithakaran Kanapathipillai提供的示例,我注意到它适用于新日期或2020-08-02T00:00:00.000+00:00,但在2020-08-02时失败。我仍然不明白为什么2020-08-02会失败,因为我不在乎时间,而且如果少尝试一天,它也会起作用:2020-08-01

    控制器

    import java.math.BigDecimal;
    import java.util.Date;
    import java.util.List;
    
    import javax.validation.Valid;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RestController;
    
    import com.mybank.accountmanagement.BankStatementFilter;
    
    import com.mybank.accountmanagement.model.Transaction;
    import com.mybank.accountmanagement.repository.TransactionRepository;
    import com.mybank.accountmanagement.service.TransactionService;
    
    @RestController
    public class TransactionController {
    
        @Autowired
        TransactionService transactionService;
    
        @Autowired
        TransactionRepository transactionRepository;
    
        @GetMapping("/transaction/{accountId}/bankstatement")
        public List<Transaction> bankStatement(@PathVariable(value = "accountId") Long accountId,
                @Valid @RequestBody BankStatementFilter bankStatementFilter) {
    
            return transactionRepository.findByAccountIdWithCreationDateBetween(accountId,
                    bankStatementFilter.getFromDate(), bankStatementFilter.getToDate());
        }
    
    }
    
    闻起来我用这个POJO BankStatementFilter做了些蠢事

    以下是我在将新日期()与2020-08-02进行比较时注意到的内容。既然我不在乎时间,对吗

    ***最后评论

    它现在正在工作。我把POJO换成了bellow。如果我正在做一些愚蠢的事情,我会感谢你的建议。顺便说一句,我最初的问题得到了100%的回答

    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    public class BankStatementFilter {
    
        private Date fromDate;
        private Date toDate;
    
        public Date getFromDate() {
            return fromDate;
        }
    
        public void setFromDate(String fromDate) {
    
            String pattern = "yyyy-MM-dd";
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
    
            try {
                this.fromDate = simpleDateFormat.parse(fromDate);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
    
        public Date getToDate() {
            return toDate;
        }
    
        public void setToDate(String toDate) {
            String pattern = "yyyy-MM-dd";
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
    
            try {
                this.toDate = simpleDateFormat.parse(toDate);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
    
    }
    

    您是否尝试过使用>=和
    • @Temporal.Date
      对spring数据存储库方法没有任何影响。只有在实体中对其进行注释时,它才会产生影响

    • 相反,也要执行以下操作来转换参数:

    @Query(value=“SELECT*FROM account\u id=:idAccount的交易记录”+
    “和演员阵容(于截止日期创建)”+
    “在演员阵容(:fromDate AS date)和演员阵容(:toDate AS date)之间”
    ,nativeQuery=true)
    列表由(@Param(“idAccount”)长idAccount查找,
    @参数(“fromDate”)日期fromDate,
    @参数(“toDate”)日期(toDate);
    
    • 这里是我与您的实体建立的示例项目,除了
      帐户
      ,因为如果您愿意比较,这不在问题中。您可以将项目作为maven导入IntelliJ并运行主应用程序,它将插入数据并返回


    您现在面临的问题是什么?是您的查询没有提供正确的输出吗?你能添加你现在得到的输出吗?我觉得你的问题很好。希望你能在问题中更清楚地解释你的问题。谢谢。我想有两个问题:(1)我误用了@Temporal。(2) 它不包括fromDate和toDate中具有确切日期的记录。我会在上面添加更多信息。你们是否检查过数据库和应用程序是否使用相同的时区?因为数据库中创建的_at的数据和响应是不同的。请您将您的陈述再扩展一点“不要使用本机查询,并尝试在您的案例中使用模型类进行快速、正确的反序列化,因为您已经定义了模型类”,您似乎建议使用一种与上述不同的方法,这是有充分理由的。如果我只是将“nativeQuery=true”替换为“nativeQuery=false”,我会按照您的建议(我想不会)将您的查询替换为:@query(value=“从事务ts中选择事务ts,其中ts.accountId=:id帐户和CAST(在as date创建)介于:fromDate和:toDate之间,nativeQuery=false)从这里阅读差异和实现请向上投票并接受anwser如果它对您有效我相信我的问题与Spring数据无关。相反,它在某种程度上与日期转换有关。我还要加上呼叫仓库的管理员,谢谢。我不知道“@Temporal.Date对您的spring数据存储库方法没有任何影响”。据我记忆所及,我在Spring数据存储库中使用了@Temporal。看来我丢了一分。第二,我必须做些什么,以便包括与日期匹配的记录。我的意思是,假设有日期为2020-08-02的记录,在我的过滤器中fromDate是2020-08-02,toDate也是2020-08-02。使用你的回答,它没有带来确切日期的记录,我将添加两个打印件来显示我的意思我实际使用你的代码设置了一个示例项目,我插入了一个记录,今天某个时候运行了查询,它拾取了记录。你的示例项目非常有帮助,给我带来了一个铃声。您正在使用new Date(),而我的控制器正从客户端(邮递员/curl)接收“2020-02-08”。现在我想我把日期序列化而不是Spring数据搞砸了。我刚刚试着从邮递员发送到控制器端点“fromDate”:“2020-08-02T00:00:00.000+00:00”,“toDate”:“2020-08-02T23:59:59.062+00:00”,效果非常好。嗯,还不清楚是什么错,因为我想忽略时间,只使用一天。这是我在CAST(:fromDate AS date)和CAST(:toDate AS date)之间所期望的,即使您发送
    2020-08-08
    ,它也需要创建一个java日期对象。最好的选择是打印出控制器内接收到的日期对象
    import java.util.Date;
    
    public class BankStatementFilter {
        
        private Date fromDate;
        private Date toDate;
        public Date getFromDate() {
            return fromDate;
        }
        public void setFromDate(Date fromDate) {
            this.fromDate = fromDate;
        }
        public Date getToDate() {
            return toDate;
        }
        public void setToDate(Date toDate) {
            this.toDate = toDate;
        }
    
    }
    
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    public class BankStatementFilter {
    
        private Date fromDate;
        private Date toDate;
    
        public Date getFromDate() {
            return fromDate;
        }
    
        public void setFromDate(String fromDate) {
    
            String pattern = "yyyy-MM-dd";
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
    
            try {
                this.fromDate = simpleDateFormat.parse(fromDate);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
    
        public Date getToDate() {
            return toDate;
        }
    
        public void setToDate(String toDate) {
            String pattern = "yyyy-MM-dd";
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
    
            try {
                this.toDate = simpleDateFormat.parse(toDate);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
    
    }
    
        @Query(value = "SELECT * FROM transactions WHERE account_id=:idAccount " +
                "AND CAST(created_at AS date) " +
                "BETWEEN CAST(:fromDate AS date) AND CAST(:toDate AS date)"
                , nativeQuery = true)
        List<Transaction> findBy(@Param("idAccount") Long idAccount,
                                 @Param("fromDate") Date fromDate,
                                 @Param("toDate") Date toDate);