须要根据当前用户的权限过滤须要显示的数据。
好比有一张旅馆表,主键为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,那么实现起来就麻烦了。
这个过滤对于懒加载不起做用
若是经过主键直接查询,那么过滤器将不起做用