用到许多数据库关系化映射中间件,hibernate,jpa,iBATIS,最近研究nodejs,发现一款不可多得的orm开源工具sequelize,支持promise,映射配置/查询/数据输出等都是json格式,非常顺心,官方文档很标准但完全说不透其强大的功能,很多都需要实际用到才能体会,就像json一样变化多端,你猜不透它有多少种变化。
好,下面来看一个需求案例:
一条这样的普通查询语句:
select * from product join producton product.id=place.productid and place.city=1100 where product.price>100 limit 10
用sequelize的query来写,如果写成这样:
models.product.findAll({
where: ["price>=?", 100 ],
include: [{
model:models.product,
where: { city:1100 }
}],
limit:12
})
实际上运行的sql是这个:
select product.*, place.* from (select * from product where product.price>100 limit 10) join place on product.id=place.productid and place.city=1100
想要的结果是错误的,分页时没有把city:1100 条件限制了,结果有差异,那怎么办?
于是找方法,看到有人使用加subQuery:false条件来处理,如下:
models.product.findAll({
where: ["price>=?", 100 ],
include: [{
model:models.product,
where: { city:1100 }
}],
limit:10,
subQuery:false //不让在子查询里分页,全局处理
})
这样对于只含一个include关联的查询倒是问题不大,如果include多个对象,关联的对象有1对多,多对多的关系,就不好控制了。
我的解决方法是,在需要一对一关联的表中加入required:true,这样就会将这个条件放在分页之前执行,
models.product.findAll({
where: ["price>=?", 100 ],
include: [{
model:models.product,
where: { city:1100 },
required:true //inner join方式
}],
limit:10,
})
运行时sql如下:
select product.*,place.* from product join place on product.id=place.productid and place.city=1100 where product.price>100 limit 10
required参数一般是指关联对象是外联还是内联,内联required=true可以表示内联条件优先,分页在后。
以上内容进仅供参考,使用场景不同,理解也不一样。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。