为什么find方法需要写完整sql

我在使用find方法的时候,发现查询方法没有findByName这种,只有

  1. List<User> users = User.dao.find("select * from user where age>18");


这种方法已经引用了User.dao了,为什么不直接写where后面的就行了,还需要把前面都写了呢,不是太理解。初学,如果提的幼稚多包涵,感觉应该这样写好理解

List<User> users = User.dao.find("age>18 and name ='abc'");



评论区

JFinal

2018-06-24 12:12

这个原因就多了,下面仅仅随手举几个原因:
1:CRUD 功能中,其中 CUD 都是不用写 sql 的,因为这部分功能的 sql 灵活性与复杂度在多数情况下并不高。 但用于查询的 sql 可能是千变万化的,所以在总体设计上是将 sql 完全开放出来,不要做任何干预,否则会造成认知成本的上升。 仅仅开放一个 find(String sql, Object... prara) 就足以应对千变万化的场景,例如多表关联的场景

2:在你建议的设计方式之下,为了满足关联查询,避免 select * 的这些问题,就必然还是要引入 jfinal 现有的设计方式的 API,学习成本会上升

3:避免 select *,这样会损失性能,假定支持 find("age>18 and name ='abc'"); 这样的形式,必然就会是 select *

4:你建议的设计方式并不能省多少代码,对比一下下面两个:
find("age>18 and name ='abc'");
find("select id from user age>18 and name ='abc'");

综上,带来的好处并不多,但带来和弊端会更多,做任何设计都是一个权衡取舍的过程,没有完美的设计

等你的开发经验多了,就更能体会 jfinal 这样设计的原因

foam103

2018-06-24 14:19

@JFinal 谢谢波总回复,再追问一个问题,就是文档这块

5.10
public void relation() {
String sql = "select b.*, u.user_name from blog b inner join user u on b.user_id=u.id where b.id=?";
Blog blog = Blog.dao.findFirst(sql, 123);
String name = blog.getStr("user_name");
}

这个user_name不属于Blog,为什么可以通过get字段到呢,是不是jfinal自动临时追加的?那是不是我随便找一个表,,然后后面跟sql只要没问题,都可以通过这个随便找的表对象get到sql字段呢。

JFinal

2018-06-24 14:45

@foam103 sql 天然就是可以多表关联查询,并且可以在 select 中指定返回多个表的字段

只是传统的 ORM 框架如果 hibernate 是基于 java bean 的,所以才无法获取到这些 select 出来的字段

而 jfinal 的 ORM 的 Model 天然就支持这种关联跨表获取数据。不仅如此,jfinal 的 Model 还照样可以有 getter setter 方法,也可以用 jfinal 官方生成器极速生成 setter getter

jfinal 的 ORM 结合了传统 Java bean 与 Model 的优点。而传统的 ORM 依赖于 bean 这种固定的无法扩展的盒子自然是无法装下千变万化的 sql 返回值的

热门反馈

扫码入社