连接查询
优质
小牛编辑
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,不能是数组或集合类型。