須要根據當前用戶的權限過濾須要顯示的數據。
好比有一張旅館表,主鍵爲hotel_code,該值的構成爲6位行政區劃+4位流水號。杭州用戶只能看到3301開頭的旅館信息,而3302開頭的只能看到寧波的旅館信息。
如:java
hotel_code | hotel_name |
---|---|
3301888999 | 杭州測試旅館 |
3302888999 | 寧波測試旅館 |
3303888999 | 溫州測試旅館 |
3304888999 | 嘉興測試旅館 |
用戶表中有個filter_code字段,過濾匹配start_with的數據。如fitler_code=33,則匹配顯示整個浙江省的數據;filter_code=3301則顯示杭州市的數據。spring
springbootspringboot
spring data jpa框架
JPA自身並無提供Filter功能,而是由hibernate實現的,
@Filter是Entity上的註解,在添加該註解以後,hibernate會在相應查詢語句中添加where子句以達到過濾的目的。
仍是直接看代碼吧。測試
Hotel實體類:ui
@Entity @Data @FilterDef(name = "filterByHotelCode", parameters = { @ParamDef(name = "filterCode", type = "string") }) @Filters({ @Filter(name = "filterByHotelCode", condition = "hotel_code like :filterCode") }) public class Hotel { @Id @Column(name = "hotel_code") private String hotelCode; private String hotelName; }
DAO:hibernate
public interface HotelRepository extends JpaRepository<Hotel, String> {}
HotelService:code
// @EnableFilter爲自定義註解以實現切面開啓Filter // @Transactional 是使用Filter功能的前提、必要條件 @EnableFilter @Transactional public PageModel<Hotel> queryByPage(String queryKey, Pageable pageable) { Page<Hotel> hotelPage = hotelRepository.findHotelsByKey(queryKey, pageable); return PageModel.build(hotelPage, pageable.getOffset()); }
自定義註解:get
public @interface EnableFilter { }
切面AOP:string
@Component @Aspect public class DataFilterAdvice { @PersistenceContext private EntityManager entityManager; @Around("@annotation(org.vigack.annotation.EnableFilter)") public Object doProcess(ProceedingJoinPoint joinPoint) throws Throwable { try{ ManagerDTO manager = (ManagerDTO) SecurityUtils.getSubject().getSession(false).getAttribute("MANAGER"); Filter filter = entityManager.unwrap(Session.class).enableFilter("filterByHotelCode"); filter.setParameter("filterCode", manager.getFilterCode() + "%"); return joinPoint.proceed(); }catch (Throwable ex){ ex.printStackTrace(); throw ex; }finally { entityManager.unwrap(Session.class).disableFilter("filterByHotelCode"); } } }
Filter的condition比較簡單,對於動態的條件支持度不夠,好比用戶的filter_code若是是一個list,那麼實現起來就麻煩了。
這個過濾對於懶加載不起做用
若是經過主鍵直接查詢,那麼過濾器將不起做用