最近遇到一个情况,需要修改数据库里的一些数据,这些数据是用 json 形式保存的,要给某些 key 对应的 value+1.如果用 sql 写会很复杂,如果能用 java 写好程序触发一下拿到结果就好了,但是这样做要发布到正式环境,调试也是非常不方便,每次发布要等好久。
于是想到用户 java 的自定义类加载器和 springboot 的 bean 动态加载结合起来,提供一个页面,在本地写好代码,copy 到页面上,点击运行就可以生效。有复杂的导出表格需求也可以实现。(明明当初做管理端的时候弄了那么多数据统计功能,结果还是不能满足业务线的需求)
大概流程是:点击运行后,把输入的代码变成文件流喂给类加载器,加载新定义的类,然后再加载到 spring 的 bean 容器里面,触发一下这个 bean 的运行,拿到结果返回给页面(有点像在线面试题的感觉)。
具体细节感觉还是有很多优化的点,想问下有没有类似的现成的工具?最好能和 springboot 结合起来,毕竟复杂逻辑还是要依靠已存在的一些 bean 。(如果没有的话就尝试糊一个好了 2333 )
1
crclz 2021-08-07 16:17:35 +08:00
你用这么 hack 的东西,还不如把正式环境暴露给你的开发机呢。
|
2
Cbdy 2021-08-07 16:17:37 +08:00 1
不用这么麻烦,你可以直接在服务端解释执行一些代码,JVM 上本身就支持一些脚本语言(甚至是 Java ),
可以看这个例子: https://github.com/cbdyzj/lib17/blob/master/repositories/boot/src/main/java/org/jianzhao/boot/service/ScriptService.java 当然,你也可以动态加载类去做,比如用 java.net.URLClassLoader |
3
857681664 2021-08-07 16:29:23 +08:00 via Android
用 mysql 的 json 函数会非常复杂吗,我都是用 sql 迁移 json 字段的
|
8
cp19890714 2021-08-07 16:48:23 +08:00 via Android
完全不是新鲜玩意,tomcat 动态加载 war 包。
或者用 js,java 自带 js 引擎。 |
9
Suddoo 2021-08-07 18:53:43 +08:00
MySQL 5.7 就支持 JSON 操作了,比这还低?
|
10
jorneyr 2021-08-07 22:21:11 +08:00
Spring 里面调用 groovy 做这些也可以,groovy 兼容 Java 。
|
11
lonenol 2021-08-07 22:34:58 +08:00
功能很简单。。直接用 java 代码,也能编译成 class 文件,然后去执行都行。。
不过最好不要这么做,太容易出问题。。万一没兜住,给线上表来了个全量更新啥的,哭都没地方哭 |
12
securityCoding 2021-08-08 13:30:13 +08:00 via Android
这样,你搭建一个分布式调度平台,比如 xxl-job 。大部分都提供了动态运行代码功能。
|
13
ljzxloaf 2021-08-08 15:02:47 +08:00 1
动态加载 class 不是什么难事,但是你这样不是等于直接上生产调试?理论上你可以把所以的业务逻辑都弄成动态的,问题是必要性在哪? OSGI 发展这么久为什么被 JPMS 干掉了,因为它所谓的热部署 /热替换根本没啥必要。Web 服务都是集群,无损上下线简单得很,要啥热部署 /热替换。
“但是这样做要发布到正式环境,调试也是非常不方便,每次发布要等好久” 这是啥理由,造点数据调试不就行了。 如果只是偶尔手动修改数据,直接用 sql 。如果经常需要手动修改数据,那应该反思的是,为啥要手动修改数据,用户的数据我们没有权限修改,除非是 bug 。 |
14
ljzxloaf 2021-08-08 15:07:30 +08:00 1
@ljzxloaf #13 正常的业务需求走开发测试部署流程,不正常的需求也尽量走正常流程,除非你 100%能 hold 住。你这么玩是否定了测试的价值。
|
16
fengpan567 2021-08-10 18:05:32 +08:00
生产环境这么玩铁定会出事故
|
17
hcen1997 2021-08-12 11:29:04 +08:00
生产环境暴露动态代码加载过不去安全检查吧?
这个需求就是普通的更改数据嘛, 不过数据不是简单的一个字段, 而是字段->json-> 字段的形式 那只需要在 dao 层加入一个 json 地址解析就行了啊 +1 需求的功能接口加一个字段 : jsonPath 对于上层应用还是调用 字段加 1 的函数 但是对于 dao 层, 先获取 json 字符串, 解析, 根据 jsonPath 更新数据, 转回 json 字符串, -> 存回数据库 我觉得分层抽象的原理用在这个需求上刚刚好 |
19
hcen1997 2021-08-12 13:20:07 +08:00
@EscYezi json 地址是指 对象中字段的地址
比如 数据库中存了 '{"t1":{"t2":1}}' 那么 json 地址就是 t1.t2 调用完函数后, 数据库中的值就会变成 '{"t1":{"t2":2}}' 为啥不直接传递 json? 随意啊, 想怎么写怎么写, |
20
aguesuka 2021-08-13 11:41:39 +08:00
osgi 是编程语言发展的弯路, 不要开倒车
|