wenhao / jpa-spec

A JPA Query By Specification framework.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

关联查询时,每使用关联表的一个条件,就会多一个join

hankuikuide opened this issue · comments

比如下面的例子
Specification specification = Specifications.and()
.between("age", 10, 35)
.eq("addresses.street", "Chengdu")
.eq("addresses.city", "china")
.build();
用到了addresses的两个条件:street,city,在生成Sql时addresses关联了两次:
如:select * from person left join addresses on x=x left join addresses on x=x ******
这是什么问题呢

有空就看

比如下面的例子
Specification specification = Specifications.and()
.between("age", 10, 35)
.eq("addresses.street", "Chengdu")
.eq("addresses.city", "china")
.build();
用到了addresses的两个条件:street,city,在生成Sql时addresses关联了两次:
如:select * from person left join addresses on x=x left join addresses on x=x ******
这是什么问题呢

这是因为,将addresses加到join中时没有过滤重复导致的,把AbstractSpecification类按下面这么改就可以了

abstract class AbstractSpecification<T> implements Specification<T>, Serializable {
    public String getProperty(String property) {
        if (property.contains(".")) {
            return StringUtils.split(property, ".")[1];
        }
        return property;
    }

    public From getRoot(String property, Root<T> root) {
        if (property.contains(".")) {
            String joinProperty = StringUtils.split(property, ".")[0];
            Set<Join<T, ?>> joins = root.getJoins();
            for (Join<T, ?> join : joins) {
                if(join.getAttribute().getName().equals(joinProperty)) {
                    return root;
                }
            }
            return root.join(joinProperty, JoinType.LEFT);
        }
        return root;
    }
}

比如下面的例子
Specification specification = Specifications.and()
.between("age", 10, 35)
.eq("addresses.street", "Chengdu")
.eq("addresses.city", "china")
.build();
用到了addresses的两个条件:street,city,在生成Sql时addresses关联了两次:
如:select * from person left join addresses on x=x left join addresses on x=x ******
这是什么问题呢

这是因为,将addresses加到join中时没有过滤重复导致的,把AbstractSpecification类按下面这么改就可以了

abstract class AbstractSpecification<T> implements Specification<T>, Serializable {
    public String getProperty(String property) {
        if (property.contains(".")) {
            return StringUtils.split(property, ".")[1];
        }
        return property;
    }

    public From getRoot(String property, Root<T> root) {
        if (property.contains(".")) {
            String joinProperty = StringUtils.split(property, ".")[0];
            Set<Join<T, ?>> joins = root.getJoins();
            for (Join<T, ?> join : joins) {
                if(join.getAttribute().getName().equals(joinProperty)) {
                    return root;
                }
            }
            return root.join(joinProperty, JoinType.LEFT);
        }
        return root;
    }
}

老哥,这么做这个条件直接没了啊

好的,我看看