在hibernate 中比 SimplePropertyPreFilter 还要好用的过滤类 ComplexPropertyPreFilter(级联过滤,关系映射过滤类,复杂的属性预过滤器)!!!!

在hibernate 中比 SimplePropertyPreFilter 还要好用的过滤类

比官方自带的过滤类(SimplePropertyPreFilter )还好用,那肯定是自定义的啦!


先讲下结果吧,看是不是诸位要的:

  • 能过滤类中的属性类,无论是Set集合,List集合,还是EJB都能过滤
  • 能解决多对多,或者是一对多,一对一等关系映射死循环,数据返回数据多,杂,乱等特点
  • 做json的主宰,想要返回的数据是哪些字段就返回哪些字段
  • 简单上手

好吧上代码:

package intercepter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.PropertyPreFilter;
import com.alibaba.fastjson.serializer.SerializerFeature;
import model.wudun.Articles;
import model.wudun.Comment;
import model.wudun.Member;

import java.util.*;

/**
 * @Author:wj
 * @Date:Created in 15:16 2018/1/5
 * @Description:用 fasjson 对 hibernate 级联关系进行过滤
 */
public class ComplexPropertyPreFilter  implements PropertyPreFilter {

    private Map<Class<?>, String[]> includes = new HashMap<>();
    private Map<Class<?>, String[]> excludes = new HashMap<>();

    static {
        JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.DisableCircularReferenceDetect.getMask();
    }

    public ComplexPropertyPreFilter() {

    }

    public ComplexPropertyPreFilter(Map<Class<?>, String[]> includes) {
        super();
        this.includes = includes;
    }

    public boolean apply(JSONSerializer serializer, Object source, String name) {

        //对象为空。直接放行
        if (source == null) {
            return true;
        }

        // 获取当前需要序列化的对象的类对象
        Class<?> clazz = source.getClass();

        // 无需序列的对象、寻找需要过滤的对象,可以提高查找层级
        // 找到不需要的序列化的类型
        for (Map.Entry<Class<?>, String[]> item : this.excludes.entrySet()) {
            // isAssignableFrom(),用来判断类型间是否有继承关系
            if (item.getKey().isAssignableFrom(clazz)) {
                String[] strs = item.getValue();

                // 该类型下 此 name 值无需序列化
                if (isHave(strs, name)) {
                    return false;
                }
            }
        }

        // 需要序列的对象集合为空 表示 全部需要序列化
        if (this.includes.isEmpty()) {
            return true;
        }

        // 需要序列的对象
        // 找到不需要的序列化的类型
        for (Map.Entry<Class<?>, String[]> item : this.includes.entrySet()) {
            // isAssignableFrom(),用来判断类型间是否有继承关系
            if (item.getKey().isAssignableFrom(clazz)) {
                String[] strs = item.getValue();
                // 该类型下 此 name 值无需序列化
                if (isHave(strs, name)) {
                    return true;
                }
            }
        }

        return false;
    }

    /*
     * 此方法有两个参数,第一个是要查找的字符串数组,第二个是要查找的字符或字符串
     */
    public static boolean isHave(String[] strs, String s) {

        for (int i = 0; i < strs.length; i++) {
            // 循环查找字符串数组中的每个字符串中是否包含所有查找的内容
            if (strs[i].equals(s)) {
                // 查找到了就返回真,不在继续查询
                return true;
            }
        }

        // 没找到返回false
        return false;
    }

    public Map<Class<?>, String[]> getIncludes() {
        return includes;
    }

    public void setIncludes(Map<Class<?>, String[]> includes) {
        this.includes = includes;
    }

    public Map<Class<?>, String[]> getExcludes() {
        return excludes;
    }

    public void setExcludes(Map<Class<?>, String[]> excludes) {
        this.excludes = excludes;
    }

    public static void main(String[] args) {
        // use instanceOf,用来判断对象是否是类的实例
        // use isAssignableFrom(),用来判断类型间是否有继承关系
        // use isInstance(),用来判断对象是否是类的实例
        //setExcludes(),进行过滤的类!!!!

        Class<?> intClass = Integer.class;

        // Create various objects.
        String str = "Hello";
        Date date = new Date();
        Integer i = new Integer(10);

        // Is str an instance of class Integer?
        boolean check1 = intClass.isInstance(str);
        System.out.println("str is an Integer? " + check1);

        // Is date an instance of class Integer?
        boolean check2 = intClass.isInstance(date);
        System.out.println("date is an Integer? " + check2);

        // Is i an instance of class Integer?
        boolean check3 = intClass.isInstance(i);
        System.out.println("i is an Integer? " + check3);

        System.out.println(Articles.class.isInstance(new Comment()));
        System.out.println(Comment.class.isInstance(new Articles()));

        System.out.println(Articles.class.isAssignableFrom(Member.class));

//这里是测试代码!! 博主一些EJB类  不要纠结导不出来!!!!  不要纠结导不出来!!!!  不要纠结导不出来!!!! 
       List<Articles> articlesList = new ArrayList<>(0);
        Articles articles = new Articles();
        articles.setId("articles_1");

        Comment comment = new Comment();
        comment.setCommentId("comment_1");

        Member member = new Member();

        member.setId("member_1");

        articles.setMember(member);

        Set<Articles> articlesSet = new LinkedHashSet<>(0);
        articlesSet.add(articles);
        member.setArticlesCollect(articlesSet);


        Set<Member> memberSet = new LinkedHashSet<>(0);
        memberSet.add(member);
        articles.setMemberSet(memberSet);


        Set<Comment> commentSet = new LinkedHashSet<>(0);
        commentSet.add(comment);
        articles.setComments(commentSet);


        member.setCommentSet(commentSet);

        comment.setMember(member);

        articlesList.add(articles);
        ComplexPropertyPreFilter filter = new ComplexPropertyPreFilter();

        filter.setExcludes(new HashMap<Class<?>, String[]>() {

            private static final long serialVersionUID = -8411128674046835592L;//我也不知道这是干嘛的   删除或者不写不会影响其功能和效果

            {   //对象 Articles中  : 多对多属性:giveRewardSet(Set集合)  memberSet(Set集合)
                put(Articles.class, new String[] { "giveRewardSet","memberSet"});//放入过滤的对象,然后是需要过滤的对象里的属性
                //对象Comment :commentId(Comment对象中普通的属性),  member(Comment对象中对象属性)
                put(Comment.class, new String[] { "commentId", "member" });
                //对象Member :nickname(Member对象中普通的属性) 多对多属性: articlesCollect(Set集合)
                put(Member.class, new String[] { "nickname", "articlesCollect" });
                //当然  多对一  一对一也是可以过滤的啦!!!   如果还有不清楚的欢迎询问
            }
        });
        System.out.println(JSON.toJSONString(articlesList, filter));
    }
}

谢谢!若有问题欢迎踩…
由于被博主遇到这个问题深感头疼 然后机缘巧合的状况下刷到博客,觉得该博主博客不是很详细没有很好的说明这个实体类的强大性能,然后博主觉得这篇博客埋没于码海中是在可以故此转发 , 脱茂!!:
https://www.cnblogs.com/sandyfog/articles/3679804.html
                                                                                                                        向老前辈致敬

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值