各位的代码里还在用 SQL 语句吗?怎么管理的

2018-11-11 14:51:38 +08:00
 magicdu
如题,大家或者大家的公司怎么处理业务逻辑复杂的 SQL 语句呢,用 mybatis 呢?还是干脆舍弃了 SQL 呢,采用其他的方式呢?
14736 次点击
所在节点    Java
104 条回复
xhinliang
2018-11-11 19:24:39 +08:00
我们手写 SQL,支撑了一亿多日活。
SabaPing
2018-11-11 19:46:57 +08:00
scala, 纯

fp, 用 doobie 交互数据库, 直接在代码里撸 raw sql.
linbiaye
2018-11-11 19:48:11 +08:00
我们的方案是 mybatis, 简单的 CURD 交给插件,复杂的手写。表结构变了插件直接重新生成一下,插件和手撸的互不干扰。
atcdef
2018-11-11 19:49:01 +08:00
坚持手写 SQL 一百年不动摇
gowk
2018-11-11 19:58:39 +08:00
@tabris17 嗯,大部分 trivial shit code 用用 ORM 也无可厚非
alamaya
2018-11-11 20:23:50 +08:00
对性能没啥要求的系统,用啥都行,怎么方便怎么来
对性能有要求的只能手写
Aidenboss
2018-11-11 20:37:03 +08:00
简单的场景用 JPA 就够了,复杂的 JPA 也支持自定义 SQL 啊。
用 JPA 有个好处不用写 mapper
beginor
2018-11-11 20:43:48 +08:00
ORM 性能确实不佳,但是能满足大量的简单的增删改查,开发效率比较高, 复杂查询可以用自定义 SQL 解决。 我司用 .net 平台, 采用的 NHibernate + dapper 的组合。
dawncold
2018-11-11 20:46:24 +08:00
我司手写复杂 SQL,但也不至于连 insert into 也是手写,对数据库操作有简单封装,主要是对结果进行封装:获取一行、获取一列、获取某行的某列、执行任意 SQL,如果有特别需要 insert into 也是手写,不使用 ORM,这样很直观,心里有底吧。

对结果简单封装后用起来和 ORM 差不多,比如获取一个订单:

```python
purchase = db().get('SELECT * FROM purchase WHERE id=%(purchase_id)s', purchase_id=123)
print(purchase.shopper_id)
print(purchase.sales_channel_id)
```
等等读取操作和用 object 的感觉一样,但如果要更新 purchase 则需要写 SQL:
```
db().execute('UPDATE purchase SET processed_at=CURRENT_TIMESTAMP WHERE id=%(purchase_id)s', purchase_id=123)
```

获取一些订单:
purchases = db().list('SELECT * FROM purchase WHERE created_at>=CURRENT_DATE')
for purchase in purchases:
print(purchase.id)

获取订单某个字段:
shopper_id = db().get_scalar('SELECT shopper_id FROM purchase WHERE id=%(purchase_id)s', purchase_id=123)

获取订单 ids:
purchase_ids = db().list_scalar('SELECT id FROM purchase WHERE created_at>=CURRENT_DATE')


对数据库的变动写 migration 脚本,按顺序部署时应用到数据库中。

开发环境中模块对表的读写有管理,不是某个模块想写哪就写哪,想读谁就读谁,但这个在生产环境不检查。
TommyLemon
2018-11-11 23:32:47 +08:00
大部分需求都用这个自动化 ORM 库,不需要写代码,逻辑太复杂或对性能要求高的地方就手写 SQL。
它会自动将前端传的 JSON 参数转为 SQL 语句执行并返回结果,
期间自动校验权限、结构、内容,自动防 SQL 注入。
github。com/TommyLemon/APIJSON
TommyLemon
2018-11-11 23:38:03 +08:00
@TommyLemon
前端传一个 JSON:
{
"User": {
"id": 82001
},
"[]": {
"count": 10,
"page": 1,
"Comment": {
"userId@": "User/id",
"@order": "date-"
}
}
}

后端完全自动化解析,不用写代码。
1.自动生成
SELECT * FROM User WHERE id = 82001 LIMIT 1 OFFSET 0

2.自动生成
SELECT * FROM Comment WHERE userId = ${User.id} ORDER BY date DESC LIMIT 10 OFFSET 10
TommyLemon
2018-11-11 23:47:19 +08:00
@actar
@ltoddy
@skypyb
@gowk
@fuyufjh
@tabris17
@beginor
Hibernate, Spring Data JPA, QueryDSL 表达力都不够强,
除了单表的增删改查,其它复杂一点的,例如 JOIN 写起来比原生的 SQL 还麻烦,
首先是一堆括号,然后 <, >, !=, <=, >= 等符号还得用 lt, gt, ne, lte, gte 等别扭的写法。
Star 都已经被自动化的 APIJSON 超过了。
https://github.com/TommyLemon/APIJSON
xy90321
2018-11-11 23:59:24 +08:00
我接触下来,真的称得上业务的一般都不存在简单的 CRUD
最起码一定都是连表,左右结合是家常便饭的那种...
这种时候 ORM 简直一无是处
TommyLemon
2018-11-12 00:01:54 +08:00
@TommyLemon 括号倒是不用手写,但阅读起来麻烦。
TommyLemon
2018-11-12 00:05:31 +08:00
@xy90321
一般的互联网应用还是大量存在简单的 CRUD 和 不是比较复杂但不是很复杂的查询 需求的,用 APIJSON 很合适。
对于一堆需要写 1 屏以上 SQL 才能实现需求的 ERP 项目,还是老老实实写原生 SQL 或 Mybatis 这种接近原生 SQL 的代码吧。
TommyLemon
2018-11-12 00:05:57 +08:00
@TommyLemon CRUD 和 比较复杂但不是很复杂的查询
timepast
2018-11-12 00:27:54 +08:00
@linbiaye 什么插件?
BBCCBB
2018-11-12 08:37:25 +08:00
mybatis+mapper, 爽
liuxey
2018-11-12 08:46:46 +08:00
@TommyLemon #32 实在话,三表之上的内外连接家常便饭

如果楼主公司的业务有大量定制 sql 语句,还是放 xml 最清晰吧,毕竟分离了。。
tairan2006
2018-11-12 08:47:02 +08:00
写 java 用过 mybatis-plus,还是挺爽的

Python 和 Go 还是用 orm 居多,都还行

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/506707

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX