关于 Java 和 Spring boot 开发体验的一些疑惑,请高手解答

19 天前
 woodytang

之前写前端比较多,最近开始用 Spring boot 开发 api 使用的是 JPA Hibernate orm+jdk21 方案,我不知道为什么感觉国内很多人不喜欢这个 Hibernate ,但是我自己用下来感觉非常好,它最牛逼的是可以按照 Entity 生成数据库结构,非常智能,所以你只要把实体定义好,一切都 ok 了,很容易维护。 有个插件 JPA buddy ,非常好用,可以很好规范代码。 JPA 也可以自定义 sql ,很灵活,除了在转成 json 的时候,会遇到无限循环的问题,其他感觉都很好。 感觉 Spring boot 写后端,除了 JAVA 本身有点啰嗦,还有编译很浪费时间,其他都还蛮不错的。

但是 JPA 通过 Entity 生成数据库的时候,为什么字段顺序和 Entity 是不一样的,是打乱的,,id 的位置会随机出现~~我槽,这就像要喝汤的时候飞进了一个苍蝇,我看网上有很多人说要 hack 一下,官方无解,但这个太离谱了。

然后就是 CommandLineRunner ,我本来的需求是需要给项目 seed 一点初始化数据,这个 CommandLineRunner 只在启动的时候自动执行,不能通过 cli 命令执行,,泥马这个 CommandLineRunner 和 Command 一点关系都没有啊,我内个去,所以 seed 数据只能在 CommandLineRunner 加 if 条件。你去看人家 PHP laravel 都有 artisan cil 工具啊,这个可是天天都要用的,为啥你没有啊~~~你 Tomcat 都可以监听指令,为啥就不做一个监听 命令行指令的。 后来我看了一个 spring boot cli 的插件,结果完全不是这个概念。。

为什么这么成熟的框架连这些基本都做不好啊谁可以告诉我一下

然后我现在在看 liquidbase 和 flyway ,还是 flyway 吧,直接 sql 多优雅,liquidbase 那个语法不能忍受~~

谁能告诉我怎么才能优雅的搞后端呢?

3220 次点击
所在节点    程序员
34 条回复
JYii
18 天前
1.只有很多单表操作我才会倾向于 JPA 。复杂联表查询、CTE 子查询,sql 长的要命那种一般都在数据库客户端上调试写好了,直接搬到 mybatis xml 中。

2.生产没有使用过 entity 去操作表结构,因为 DDL 操作都要提单过 DBA 操作。

3.CommandLineRunner 接口定义就是应用启动后去执行自定义逻辑,此操作生命周期内只有一次。想自己调用,留个接口随便玩。

4.没听过不知道

5.哪有什么优雅不优雅,以前我喜欢复杂的设计模式,现在我只想一把梭完了回家
Bingchunmoli
18 天前
见过几十张表连接或者复杂 sql 一两百行,就知道这些人是用不了 jpa 的,性能能劣化到没法使用
woodytang
18 天前
1.只有很多单表操作我才会倾向于 JPA 。复杂联表查询、CTE 子查询,sql 长的要命那种一般都在数据库客户端上调试写好了,直接搬到 mybatis xml 中。
请教一下,复杂查询这样写
@Query("""
SELECT c
FROM Comment c
WHERE c.parentId IN :parentIds
ORDER BY c.createdAt DESC
""")
List<Comment> findByParentIds(List<Long> parentIds);
不就可以自定义了吗,用 mybatis 有什么额外好处吗?


2.生产没有使用过 entity 去操作表结构,因为 DDL 操作都要提单过 DBA 操作。
撸个人项目,没 DBA ,主要想体验一下 spring boot ,否则可能会选用轻量化的方案

3.CommandLineRunner 接口定义就是应用启动后去执行自定义逻辑,此操作生命周期内只有一次。想自己调用,留个接口随便玩。
请教一下,是通过 http 调用吗?


4.没听过不知道
数据库版本管理,因为你有 DBA ,可能不用管这块

5.哪有什么优雅不优雅,以前我喜欢复杂的设计模式,现在我只想一把梭完了回家
:D ,我主要是想提供维护性,不想把不理解的东西写到代码里
woodytang
18 天前
@Bingchunmoli 复制的主要是查询吧,查询可以自定义 sql ,jpa 主要管理实体和数据库对应一致很方便
Nosub
18 天前
个人浅见:spring data jpa 和 mybatis 本质上是两种建模方式,一个从数据库表到 Java 对象,一个从 Java 对象到数据库表,换一种说法就是一个是面向对象,一个是面向集合,关系数据库本身是集合理论,而用 SQL 实现继承,多态,多重继承很复杂,很多人会用 SQL 实现同样的功能,但是他不知道在 Java 中的对应关系,还有我个人觉得 Hibernate 很复杂,就像很多人说的,写着写着自己就写不下去了,还是觉得 mybatis 写的舒服,简单说就是驾驭不了。
woodytang
18 天前
@Nosub 说得太好了,我大概有点懂了,像我这样平时不怎么写 sql 的,JPA 的方式比较直观,因为它是更声明式,而不是面向过程的,ORM 主要维护业务实体关系,因为我无论是前段还是后端,都喜欢使用 domain 设计风格,所以这种面向业务的方案很适合我,但是如果遇到复杂的查询和业务关系,还是你说的面向集合,查询组合关系比较简单,我觉得可能是因为我是新手吧,还没遇到更复杂的场景
sagaxu
18 天前
国内不喜欢的是 HQL ,并非 Hibernate 本身,JPA 单表根据签名自动合成查询还是很好用的。HQL 最大的问题是,当你写出来的时候,脑子里还是人肉要翻译成 SQL ,然后才能判断这个语句是否高效,那么 HQL 解决了什么问题?并没有,还不如直接写 SQL 简单可控。

再说 ORM ,一旦涉及到一对多甚至多对多的关系,那就不得不提 cache 和 lazy load 了,还有 1+n 查询,这些事情是自己做,还是交给 ORM 去做,仁者见仁,使用 ORM 就得很熟悉其工作机制,否则很容易写出损害性能的操作来。使用 ORM 提高的开发效率,也比较有限,偶尔由于不精通,踩到个坑,恐怕省下来的时间全都还回去。

最后说 JPA ,80%以上的需求都可以由 JPA 实现,少数情况写个 SQL 也就搞定了。

给运行中的程序发送管理指令,为什么不用 JMX 呢?如果只是每次都启动的命令行,你定义一个 bean ,然后 main 中根据参数决定初始化哪个 bean 不就好了?
zhenjiachen
18 天前
直接上 querydsl 配合 jpa ,比 mybatis 好用,flyway 最新版免费版只支持最新版数据库,不支持低一版本数据库,liquibase 可以配合 JPA buddy 直接生成文件,方便很多。
开发的时候初始数据我觉得可以用单元测试,因为单元测试可以回滚事物和 mock ,而且还能提高代码健壮性
higker
18 天前
建议使用 JDBC 手写,和 Servlet 来写 Web 项目。
yechentide
18 天前
Doma2
BBCCBB
18 天前
根据不同的条件拼接 sql 的时候 JPA 就难搞了.
jackOff
18 天前
楼上说的基本正确:
1-主要是企业项目不可能依附于某个人,肯定是有其他人接力维护
2-用 jpa 的好处是可以省很多代码,坏处就是实力不行的家伙用这玩意搞多表关联偷懒,或者大佬开辟的 jpa 基石后续维护很容易维护成狗屎,其他狗屎尚且还有评鉴的余地,jpa 一旦出现 BUG 就是很难定位,那后人就得不断品尝的这坨越来越大的狗屎。
3-而且企业开发代码目前版本要求是:
1-代码简单易读(保证人员调度可接力)
2-程序稳定易维护(禁止不打招呼炫技,用特殊算法请和项目其他成员解释,必须署名在内网留一篇可复现核实的技术文档),并且要开一次技术分享会来讲讲你这玩意解决了啥。这招出来后很多炫技刷 kpi 的就老实很多了,因为他得抽工作时间或者私人时间准备技术分享会了
3-降低架构设计成本(老板也是人精,越来越觉得这点业务也犯得着用上那么多架构技术?)
ikas
18 天前
java 10 多年前最流行的框架是 SSH...H 就是 hibernate

项目复杂度,开发时间,人员水平...无法平衡 导致它在国内用的少了.
woodytang
18 天前
@sagaxu JMX 这个我研究一下,谢谢。
如果只是每次都启动的命令行,你定义一个 bean ,然后 main 中根据参数决定初始化哪个 bean 不就好了?
恰恰不是每次启动就执行的命令,而是随时可以执行的指令。脚本语言搞这个很常见
woodytang
18 天前
@yechentide Doma2 看上去很不错的 query build ,我研究一下,谢谢!
sagaxu
18 天前
@woodytang 随时执行也是一样的,执行完就退出。用 @Lazy 注解要执行的命令的类,在入口类注入 ApplicationContext ,然后用 context.getBean 获取名字相应 bean 的时候就会执行那个命令。

需要注意的是,像脚本一样运行时,需排除定时任务等不必要的服务,也不要启动 http 服务,这个可以通过 profile 来实现。
billbob
18 天前
你不会角色 spring 就只有 JPA 吧? 你可以 jdbc,jdbcClient,r2dbc,都很优雅.
cppc
18 天前
你要开发命令行工具可以看看 spring shell
f0rb
18 天前
你要是个人项目的话,看看 DoytoQuery ,通过定义对象来控制生成的 SQL 语句,上面那个 Comment 的例子大概可以这样写:

@SuperBuilder
public class CommentQuery extends PageQuery {
private List<Long> parentIdIn;
}

CommentQuery commentQuery = CommentQuery.builder().parentIdIn(list).sort("createdAt,DESC").build();
List<Comment> comments = dataQueryClient.query(commentQuery);

更复杂的查询示例还有 TPC-H 的 22 个用来对数据库进行性能测试的查询语句。
之前推广的比较佛系,所以估计没什么人了解。
前几天还在这里发了个帖子想问问有没有人搞过推广的,想先推下 Go 版本的试试。
chihiro2014
18 天前
复杂的查询用 @Query 配合 projection

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

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

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

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

© 2021 V2EX