390 Star 1.6K Fork 482

闲.大赋(李家智) / BeetlSQL

 / 详情

postgresql数据库jsonb类型字段

已完成
创建于  
2022-07-15 15:12

postgre数据库的表有一个字段是jsonb类型的,请问这个在实体里面应该用什么接收,或者通过什么方式可以转换

评论 (23)

随风老大 创建了任务

可以用String 接收

也可以参考 https://www.kancloud.cn/xiandafu/beetlsql3_guide/1958117 自定义转换处理

好的,谢谢,使用jsonb类型,在执行插入的时候,只能用${}直接合并到sql上,如果使用#{} 占位符的方式 报错,不知道为什么
输入图片说明

我看这文章:
https://www.enterprisedb.com/blog/processing-postgresql-json-jsonb-data-java

String[] json = {"{\"customer_name\": \"John\", \"items\": { \"description\": \"milk\", \"quantity\": 4 } }",
 "{\"customer_name\": \"Susan\", \"items\": { \"description\": \"bread\", \"quantity\": 2 } }",
 "{\"customer_name\": \"Mark\", \"items\": { \"description\": \"bananas\", \"quantity\": 12 } }",
 "{\"customer_name\": \"Jane\", \"items\": { \"description\": \"cereal\", \"quantity\": 1 } }"};

try {
 String sql = "INSERT INTO sales VALUES (?, ?::JSON)";
 PreparedStatement ps = conn.prepareStatement(sql);
 
 for (int i=0; i<4; i++) {
  ps.setInt (1, i+1);
  ps.setObject (2, json[i]);
  ps.executeUpdate();
 }
 conn.commit();

} catch (Exception e) {
   System.out.println(e.getMessage());
   e.printStackTrace();
}

说明jsonb 需要“?::JSON” 这么干才能插入,因此,BeetelSQL缺少这功能,我今天看看吧,这俩天能不能把自动生成sql语句完善一下,postgres的jsonb 的生成改成“?::JSON”

我使用这种方式将::JSON加了上去,临时解决方案(避免了sql注入)

1、使用属性注解转换方式报错 插入的时候没有执行,未进断点
输入图片说明
输入图片说明
输入图片说明

使用字符串类型 成功插入
输入图片说明

不清楚在什么情况下 属性转换会失效

输入图片说明
跟踪发现是因为这个里面将参数封装到map中,导致注解@PgJsonb属性转换失效,是不是要在封装map之前先进行注解扫描转换

使用提供的AutoMapper解决
输入图片说明

厉害了,你先这么搞,我今天研究一下看看怎么回事,总体上,beetlsql应该能做到内置得insert语句能使用json.

我看看insert自动生成语句碰到postgres得jsonb时候,怎么生成“?:JSON”

好的,感谢,还有一个问题,就是 pg使用的分区表,分区字段是create_time,
但是分区表设置主键必须为 id+分区键,这样就造成了beetlsql获取到的主键是两个,
导致无法使用内置的updateTemplateById方法,是不是可以直接在@Table上加一个功能指定主键呢?

关怀与pg分区,你能提供一个链接么,我没看到哪里需要是id+分区键,一般不是 专门指定分区字段么?
我看网上例子,各是各的

CREATE TABLE orders (
    id serial,
    user_id int4,
    create_time timestamp(0) 
) PARTITION BY RANGE(create_time);

https://gitee.com/xiandafu/beetlsql/tree/callable2/sql-db-support/postgres/src/main/java/org/beetl/sql/postgres

@随风老大 我在新分支上 做了一个初步支持,你可以下载源码执行试试。可以解决::JSON问题。具体参考代码PostgresTest.java。 主要逻辑是

输入图片说明

Json注解的实现JacksonConvert , 新版本增加了toAutoSqlPart

输入图片说明

这样,可以内置的sql生成,如insert,insertTemplate,update,updateTempate都支持了

大佬,我已经把新的融进去了,可以使用,就是这个类 没看明白是怎么使用,望大佬明示
输入图片说明

这个没啥用,当时做实验用的。 这个是beetl函数,如果注册到beetlsql里后,可以在sql模板里调用,比如

update xxx set data=${jsonCast(dataStr)} ...

生成的对应的sql是

update xxx set data=?::jsonb

对应的jdbc参数? 包含此值(参考list.add(sqlparas)

输入图片说明
大佬,批量保存jsonb,自动生成脚本,好像不对,报错

05:52:25:缺少符号(PARSER_MISS_ERROR):$$ 位于0行 资源:logSysShared.$insert
缺少输入在 '$$' 后面, 期望 '~>'
0|insert into log_sys_shared (id ,create_user ,create_time ,modify_user ,modify_time ,sys_code ,mod_code ,log_classify ,log_type ,ext_attr ) values (#{ id } ,#{ createUser } ,#{ createTime } ,#{ modifyUser } ,#{ modifyTime } ,#{ sysCode } ,#{ modCode } ,#{ logClassify } ,#{ logType } ,#{ $$::JSON } )
org.antlr.v4.runtime.InputMismatchException
at org.beetl.core.parser.BeetlAntlrErrorStrategy.recoverInline(BeetlAntlrErrorStrategy.java:166)
at org.antlr.v4.runtime.Parser.match(Parser.java:206)
at org.beetl.core.parser.BeetlParser.textStatment(BeetlParser.java:1812)
at org.beetl.core.parser.BeetlParser.statement(BeetlParser.java:436)
at org.beetl.core.parser.BeetlParser.prog(BeetlParser.java:166)
at org.beetl.core.engine.DefaultTemplateEngine.createProgram(DefaultTemplateEngine.java:59)
at org.beetl.core.GroupTemplate.loadTemplate(GroupTemplate.java:520)
at org.beetl.core.GroupTemplate.lambda$getTemplateByLoader$1(GroupTemplate.java:481)
at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660)
at org.beetl.core.impl.cache.DefaultBeetlCache.get(DefaultBeetlCache.java:61)
at org.beetl.core.GroupTemplate.getTemplateByLoader(GroupTemplate.java:481)
at org.beetl.core.GroupTemplate.getTemplate(GroupTemplate.java:455)
at org.beetl.sql.core.engine.template.BeetlTemplateEngine.getSqlTemplate(BeetlTemplate

好的,我今天看看,我已经改好了insert,update等相关方法,我明天发布一下就可以用了

用新版本吧,改好了,目前内置的update,insert,batch等生成的sql语句都会带上::jsonb @随风老大

@随风老大 官网版本已经发布,可以参考官网文档AttributeConvert了解如何实现此功能

另外pg使用的分区表,不太懂你说的

收到,十分感谢,
我的分区表需要设置ID为主键,
但是分区表设置主键的话,必须加上分区键,
所以是这个样子 PRIMARY KEY (id,create_time)
建表脚本
CREATE TABLE que_signin(
id varchar(32) NOT NULL,
create_user varchar(32),
create_time timestamp(3) NOT NULL,
modify_user varchar(32),
modify_time timestamp(3),
remark varchar(255),
biz_attr jsonb DEFAULT '{}',
PRIMARY KEY (id,create_time)
)
PARTITION BY RANGE (
"create_time" "pg_catalog"."timestamp_ops"
);

已经调整了 ,入上id1,id2都是主键,但使用assignId=true 让pojo定义主键

输入图片说明

https://gitee.com/xiandafu/beetlsql/blob/master/sql-test/src/main/java/org/beetl/sql/test/MyTestEntity.java

目前仓库一直发布不上去,你可以等周末看看。或者拿下源码自己install到本地

看样beetlsql得支持强制使用pojo的主键设置了,这样就行

@Table(name="",forceAssingId=true)

恩,pojo这样设置更灵活

目前新版本已经支持这种方式

闲.大赋(李家智) 任务状态待办的 修改为已完成

登录 后才可以发表评论

状态
负责人
里程碑
Pull Requests
关联的 Pull Requests 被合并后可能会关闭此 issue
分支
开始日期   -   截止日期
-
置顶选项
优先级
参与者(3)
1167207 2016 12 21 1703044411 29 xiandafu 1678706040
Java
1
https://gitee.com/xiandafu/beetlsql.git
git@gitee.com:xiandafu/beetlsql.git
xiandafu
beetlsql
BeetlSQL

搜索帮助