我已经搜索了正确的答案,但是很遗憾,没有找到QueryDsl SQL模块的任何有效解决方案。 我正在尝试在自定义属性上使用左连接来获取具有0..n关系的简单实体:
<script>
import firestore from 'firebase/firestore'
import { mapGetters } from 'vuex'
import SingleMessage from './SingleMessage'
import MessageForm from './MessageForm'
export default {
name: 'messages',
components: {
SingleMessage,
MessageForm,
},
data() {
return {
channelsRef: firebase.firestore().collection('channels'),
messages: [],
channel: '',
unsubscribe: null
}
},
computed: {
...mapGetters(['currentChannel']),
},
watch: {
currentChannel: function(newValue, oldValue) {
this.messages = [];
if (this.unsubscribe) {
this.unsubscribe();
this.addListeners(newValue);
} else {
this.addListeners(newValue);
}
}
},
methods: {
addListeners(newValue) {
this.unsubscribe = this.channelsRef
.doc(newValue.id)
.collection('messages')
.onSnapshot(snapshot => {
snapshot.docChanges().forEach(change => {
if (change.type == 'added') {
let doc = change.doc
this.messages.push({
id: doc.id,
content: doc.data().content,
timestamp: doc.data().timestamp,
user: doc.data().user,
});
}
});
});
console.log('[addListeners] channel:', newValue.id)
}
}
}
</script>
为了能够填充dto,我将结果转换如下:
class Parent {
private Long id;
private String uuid;
private Set<Child> children;
}
class Child {
private Long id;
private String uuidRef;
}
有些父行具有多个子关系。 一切工作正常,除非我为分页目的添加查询额外的限制和偏移量。我们希望获得前20个结果,所以我要添加.offset(0).limit(20)。
在db中,有2个父记录,每个记录有2个子行。经过变换/分组后,我只能得到18行/对象。我知道这是由于SQL查询本身造成的,因为它返回左连接的行作为单独的结果行,并且转换在内存中完成,但是我想知道这是否可以以某种方式在SQL模块上处理。我不想使用JPA,因为这是一个很小的项目,只有很少的表,并且JPA / Hibernate会显得过大。 SQL模块非常适合此:)
在PostgreSQL 11.2中使用QueryDsl SQL 4.2.1
答案 0 :(得分:0)
我想说的是,JPA也不会“正确”地处理该问题,至少在尝试一次性获取父母及其子女时不会如此。正如您已经注意到的那样,问题在于偏移量和限制将应用于结果,并且如果父级具有多个子级,则联接会导致较少的父级被加载(或者如果只有一个父级,则只有一部分父级的子级被加载)。许多)。因此,您必须将偏移量和限制应用于代表每行父对象的对象。
您可以尝试这样的操作(我不知道QueryDsl,所以我只会使用伪SQL):
select ... from parent p join children c on ...
where p.id in ( select distinct id from parent order by whatever offset x limit y )
因此,您要做的是确定子查询中20个父母的ID,然后将这些父母及其孩子加载,这可能会导致超过20个结果行(如果您的2个父母有2个父母,则您的情况下为22行)儿童和其他18个孩子最多只能有1个。