连接查询

优质
小牛编辑
133浏览
2023-12-01

MongoDB提供了lookup操作,用于实现两个表的关联聚合,但聚合操作编写起来比较麻烦,而且不符合面向对象的思维。为简化开发,bugu-mongo提供了一个JoinQuery类,用于实现两个表的连接查询。

JoinQuery借鉴了SQL左连接的概念:

  • 当前表为左表,被连接的表为右表;
  • 通过指定左键、右键进行关联;
  • 对于不存在关联的数据,只会返回左表的数据,右表的数据为null。

创建JoinQuery

通过调用BuguDao中的joinQuery()方法,就可以创建一个JoinQuery对象:

UserDao dao = new UserDao();
JoinQuery<User, Customer> query = dao.joinQuery(Customer.class);  //User是左表,Customer是右表

设置查询条件

首先,需要指定左键、右键:

query.keys("left_key", "right_key");

JoinQuery的用法与BuguQuery类似,例如支持连缀书写、支持排序、支持分页等。

可以设置左表、右表的匹配条件:

UserDao userDao = new UserDao();
CustomerDao customerDao = new CustomerDao();

BuguQuery<User> leftMatch = userDao.query().greaterThan("age", 30);
BuguQuery<Customer> rightMatch = customerDao.query().greaterThanEquals("star", 5);

List<JoinResult<User, Customer>> list = userDao.joinQuery(Customer.class).keys("username", "name")
            .match(leftMatch, rightMatch)
            .results();

也可以只设置其中的一个匹配条件:

//只设置左表的匹配条件
BuguQuery<User> leftMatch = userDao.query().greaterThan("age", 30);
List<JoinResult<User, Customer>> list = userDao.joinQuery(Customer.class).keys("username", "name")
            .match(leftMatch, null)
            .results();

可以指定返回、不返回某些字段:

List<JoinResult<User, Customer>> list = userDao.joinQuery(Customer.class).keys("username", "name")
            .notReturnFields(new String[]{"contact"}, new String[]{"note"})
            .results();

也可以指定只返回左表的字段:

List<JoinResult<User, Customer>> list = userDao.joinQuery(Customer.class).keys("username", "name")
            .returnLeftFieldsOnly()
            .results();

可以排序和分页:

List<JoinResult<User, Customer>> list = dao.joinQuery(Customer.class).keys("username", "name")
            .sort("{age : 1}", "{star: -1}")
            .pageSize(10).pageNumber(1)
            .results();

返回值

JoinQuery的返回结果,是由JoinResult组成的列表。JoinResult是组合对象,其定义如下:

public class JoinResult<L, R> {

    private L leftEntity;
    private R[] rightEntity;

    ...getter and setter...
}

通过JoinResult的getLeftEntity()方法,可以获得左表对象;通过getRightEntity()方法,可以获得右表对象。注意,右表对象是一个数组。

例:

List<JoinResult<User, Customer>> list = dao.joinQuery(Customer.class).keys("username", "name")
                .sort("{age : 1}", null).results();
    for(JoinResult<User, Customer> result : list){
        User user = result.getLeftEntity();
        System.out.println("user age: " + user.getAge());
        Customer[] customers = result.getRightEntity();
        for(Customer c : customers){
            System.out.println("  customer star: " + c.getStar());
        }
    }

更多的JoinQuery的示例代码,请参考源代码中的JUnit单元测试。

注意

bugu-mongo的JoinQuery,有如下限制:

1、只支持MongoDB 3.4以上的版本。

2、如果用@Ref属性和@Id属性进行关联,则@Ref需要设置reduced=true。

3、左键leftKey,不能是数组或集合类型。