2016-09-02 22 views
4

我有一個用戶實體:從控制器|中的結果集中排除列春季數據JPA

public class SpringUsers implements Serializable { 
    private String password; 
    // other fields omitted 
    @Basic 
    @Column(name = "password") 
    public String getPassword() { 
     return password; 
    } 

    public void setPassword(String password) { 
     this.password = password; 
    } 
} 

而其倉庫:

public interface SpringUsersRepository extends CrudRepository<SpringUsers, Integer> { 
    SpringUsers findByUsername(String username); 
    List<SpringUsers> findByUserId(Integer userId); 
} 

而且我有一個控制器的方法,應該讓所有註冊用戶使用相同的用戶id列表(是內部使用)作爲當前已驗證用戶:

public List<SpringUsers> getRegisteredUsers() { 
    CustomUserDetails authenticatedUserDetails = getCustomUserDetails(); 
    List<SpringUsers> registered = springUsersRepository.findByUserId(
     authenticatedUserDetails.getUserMyId()); 
    return registered.stream().map(v -> { 
     v.setPassword(null); 
     return v; 
    }).collect(Collectors.toList()); 
} 

我並不想通過密碼(即使它加密)的前端 - 所以我通過用戶流並將密碼設置爲null,如上所示。

但是,我想知道是否沒有可能僅僅在查詢結果中不包含用戶密碼?


版本信息:

春季啓動1.4.0 & 休眠5.0.9.Final

回答

5

您可以使用@Query有選擇性的包含一些字段:

// Include all fields you wanna query for using u.x syntax 
// AFAIK there is no exclusion syntatic sugar 
@Query("select u.id, u.username from SpringUsers u where u.id = ?1") 
List<SpringUsers> findByUserId(Integer userId); 

你也可以使用Projections。首先通過引入投影接口定義投影:

interface NoPasswordUser { 
    Long getId(); 
    String getUsername(); 
    // Do not include getPassword(); 
} 

然後在你的倉庫使用它:

public interface SpringUsersRepository extends CrudRepository<SpringUsers, Integer> { 
    NoPasswordUser findByUsername(String username); 
    List<NoPasswordUser> findByUserId(Integer userId); 
} 

無論如何,最好是不通過REST或任何遠程接口暴露你的實體。你可以使用DTO來解決這個問題,這個post可能在這方面很有用。

+1

Yap,預測似乎是一種方法---如果我找不到其他解決方案,我會這樣做。謝謝你的提示! – baao

1

我不認爲有一種方法可以在從db獲取實體時忽略某些字段,因爲這些實體不會處於一致狀態 - 它們的數據將與數據庫中的數據不同。其他選項存在,但(自定義查詢,投影)。

一種選擇是在查詢直接

select new my.company.SafeUser(u.username, u.email) from User u 

使用constructor expressions,並填寫一些POJO,只有需要的數據無論如何,我認爲你應該發送的DTO的前端,並在它暴露你需要的屬性在前端。這種方法有很多優點,例如上面的例子中初始化它們的天氣,或者循環結果。