簡體   English   中英

Spring JPA NoRepositoryBean查詢

[英]Spring JPA NoRepositoryBean Queries

如何使用@Query@NoRepositoryBean方法中使用@MappedSuperclass

我有@MappedSuperclass Temporal(基本具有長id)

@MappedSuperclass
public abstract class Temporal extends Basis<Long> {

    private Long temporalCode;
    private Date dateBegin;
    private Date dateEnd;
    // getters/setters
}

@NoRepositoryBean TemporalRepository

@NoRepositoryBean
public interface TemporalRepository<T extends Temporal> extends JpaRepository<T, Long> {
//    this two are ok
    List<T> findByTemporalCode(Long temporalCode);
    List<T> findByTemporalCodeAndDateBeginBeforeAndDateEndAfter(Long temporalCode, Date dateBegin, Date dateEnd);

//    query not working because Temporal is not an @Entity
//    @Query("select t from Temporal t 
//         where (t.dateBegin < ?1 or t.dateBegin is null) 
//         and (t.dateEnd < ?1 or t.dateEnd is null) ")
//    List<T> findByDate(Date date);
}

更新:
例如,我有臨時實體Worker:

@Entity
public class Worker extends Temporal {
//    fields and methods here
}

public interface WorkerRepo extends TemporalRepository<Worker> {
//    Looks like it will work but I don't want to write the same method in each TemporalRepository subclass
//    @Query("select w from Worker w where (w.dateBegin < ?1 or w.dateBegin is null) and (w.dateEnd < ?1 or w.dateEnd is null) ")
//    List<Worker> findByDate(Date date);
}

實際上,您可以使用SpEL表達式。 Spring Data JPA參考
因此我們可以用#{#entityName}替換超類的名稱

參考示例:

@MappedSuperclass
public abstract class AbstractMappedType {
  …
  String attribute
}

@Entity
public class ConcreteType extends AbstractMappedType { … }

@NoRepositoryBean
public interface MappedTypeRepository<T extends AbstractMappedType>
  extends Repository<T, Long> {

  @Query("select t from #{#entityName} t where t.attribute = ?1")
  List<T> findAllByAttribute(String attribute);
}

public interface ConcreteRepository
  extends MappedTypeRepository<ConcreteType> { … }

我的示例的解決方案:

@NoRepositoryBean
public interface TemporalRepository<T extends Temporal> extends JpaRepository<T, Long> {
    List<T> findByTemporalCode(Long temporalCode);

    List<T> findByTemporalCodeAndDateBeginBeforeAndDateEndAfter(Long temporalCode, Date dateBegin, Date dateEnd);

    @Query("select t from #{#entityName} t 
        where (t.dateBegin < ?1 or t.dateBegin is null)
        and (t.dateEnd < ?1 or t.dateEnd is null)")
    List<T> findByDate(Date dateBegin);
}

KI認為您無法執行此操作,因為@NoRepositoryBean用於告訴spring不要為此接口創建存儲庫代理bean。 除了具體的存儲庫接口之外,該接口還用於公開一些其他方法。 在這種情況下,您必須extend這樣的接口,我將再舉一個例子來說明這一點:

考慮我有StudentTeacher實體:

現在我的界面為:

@NoRepositoryBean
public interface ReadOnlyRepository<T, ID extends Serializable> extends JpaRepository<T, ID> {
  T findById(int id);
}

現在我們必須編寫一個具體的回購接口,例如:

public interface StudentRepository extends ReadOnlyRepository<Student, Long> {
  //override the methods of `ReadOnlyRepository` with @query
}

public interface TeacherRepository extends ReadOnlyRepository<Teacher, Long> { 

//override the methods of `ReadOnlyRepository` with @query
}

通過這種方式,可以通過簡單地聲明名為查詢Student.findByIdTeacher.findById JPA來手動定義Student和Teacher的查詢。 使用這種方法,您可以輕松地為您的應用程序場景量身定制基礎接口。

因此,@NoRepositoryBean用於避免創建存儲庫bean。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM