2017-06-14 164 views
1

我的實體被映射到數據庫表。在彈簧引導應用程序中模擬DB視圖

我需要重新映射到其他條件的表。最簡單的方法是創建一個數據庫視圖。

create view person_main_asg as (
select * from person_history 
where asg_end_date is null or asg_end_date > CURRENT_TIMESTAMP 
) 

問題是我沒有創建它的權限。

所以我需要在我的spring-boot應用程序中解決這個問題。

谷歌搜索我發現我可以添加一個過濾器到我的實體定義。

@Entity 
@FilterDef(name="person_history_main_asg") 
@Filter(name="person_history_main_asg", condition = "asg_end_date is null or asg_end_date > CURRENT_TIMESTAMP) ") 
@Table(name = "person_history") 
public class Person { 
///... 
} 

現在我需要啓用我的過濾器,因爲它默認情況下是禁用的。原來,這是一項艱鉅的任務。

其中一個solution是使用AOP/AspectJ。在我看來,更多的是一個黑客而不是答案,但主要問題是它需要通過添加我不允許做的javaagent:path/to/aspectjweaver.jar來修改虛擬機參數。

另一種解決方案是實現其目前被定義爲一個接口

public interface PersonRepository { 

    Person findByFullLoginEndingWith(String login); 

    List<Person> findByFirstNameContainingIgnoreCase(String firstName); 
    List<Person> findByLastNameContainingIgnoreCase(String lastName); 
} 

所以實現應該是

public interface PersonRepositoryCustom { 
    Person findByFullLoginEndingWith(String login); 

    List<Person> findByFirstNameContainingIgnoreCase(String firstName); 
    List<Person> findByLastNameContainingIgnoreCase(String lastName); 
} 

public interface PersonRepository extends Repository<Person, String>, JpaSpecificationExecutor<Person>, PersonRepositoryCustom { 
} 

public class PersonRepositoryImpl implements PersonRepositoryCustom { 

    @PersistenceContext 
    private EntityManager entityManager; 

    @Autowired 
    private PersonRepository personRepository; 

    public Person findOne(Specification<Person> spec) { 
     Filter filter = (Filter)entityManager.unwrap(Session.class).enableFilter("person_history_main_asg"); 
     Person result = personRepository.findOne(spec); 
     return result; 
    } 

    public Person findOne(String id) { 
     //... 
    } 

    public List<Person> findAll() { 
     //... 
    } 

    public List<Person> findAll(Specification<Person> spec) { 
     //... 
    } 

    //... 
} 

我有幾個問題,這個解決方案(除了一個倉庫它是散裝和沉重的)。

的EntityManager導致以下錯誤:無類型[javax.persistence.EntityManagerFactory]被定義的排位豆:預期單一匹配豆,但發現4

另外

@Autowired 
private PersonRepository personRepository; 

原因計算器因爲它是一個實例PersonRepositoryImpl這是自動裝配,但我需要通過Springboot訪問默認實現。

那麼我如何在我的應用程序中模擬數據庫視圖?

編輯:

目前我的實體映射到另一個表。 我的實體倉庫被定義爲

public interface PersonRepository extends Repository<Person, String>, JpaSpecificationExecutor<Person> { 

     T findOne(ID id); 
     List<T> findAll(); 

     Person findByFullLoginEndingWith(String login); 

     List<Person> findByFirstNameContainingIgnoreCase(String firstName); 
     List<Person> findByLastNameContainingIgnoreCase(String lastName); 
} 
+0

爲什麼你需要一個觀點呢?只需在存儲庫中寫入一個'find'方法,就可以將@Query(value =「select * from person_history where as_end_date is null or asg_end_date> CURRENT_TIMESTAMP」,nativeQuery = true)'放在它上面並完成。爲什麼使它更復雜呢。 –

+0

@M。 Deinum如果我實現我的資源庫PersonRepositoryImpl,那麼我需要提供findAll的實現(規範規範)。所以我需要從規範中提取條件並將它們與我的查詢結合起來。我不知道該怎麼做。或者可以請您提供一個解決方案草案作爲答案。 –

+0

你不需要實現。如問你爲什麼需要這種觀點?沒有必要? –

回答

1

你不需要的實現,你不需要過濾器,你不需要一個視圖。只需定義一個查詢方法並用@Query對其進行註釋。

public interface PersonRepository extends JpaRepository { 

    Person findByFullLoginEndingWith(String login); 

    List<Person> findByFirstNameContainingIgnoreCase(String firstName); 
    List<Person> findByLastNameContainingIgnoreCase(String lastName); 

    @Query(value="select * from person_history where asg_end_date is null or asg_end_date > CURRENT_TIMESTAMP", nativeQuery=true) 
    List<Person> findPersonMain(); 
} 

這就是你所需要的,沒有自定義實現等作爲春節數據JPA會知道如何處理這一點。目前它是一個本地查詢,但你可以重寫它到一個JPQL。

============================================== =======================

編輯者的Oleg Pavliv:

的解決方案是使用@Where代替@Filter(取自評論的主題)。

@Entity 
@Where(clause = "asg_end_date is null or asg_end_date > GETDATE()) ") 
@Table(name = "person_history") 
public class Person { 
///... 
} 
+0

請檢查我的編輯到OP。我的存儲庫擴展了ReadOnlyRepository和JpaSpecificationExecutor。如果我只是按照你的建議添加一個方法findPersonMain,它將不會被考慮在內。 –

+0

我仍然不明白你爲什麼需要這個視圖,或者你的人被映射到另一個表的事實與此有關。正如我所提到的,你不需要視圖。你爲什麼需要它? –

+0

我的實體映射到Person表。我需要重新映射到另一個表,使用額外的條件來獲得相同的結果。最簡單的方法是創建一個視圖。您的實現不起作用,因爲它與擴展ReadOnlyRepository和JpaSpecificationExecutor的當前存儲庫定義不兼容。如果我只是按照你的建議添加一個方法,它將不會被考慮,結果選擇語句將不包含查詢條件。 –

相關問題