文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

利用Mybatis向PostgreSQL中插入并查询JSON字段

2024-04-02 19:55

关注

前言:

这里我使用的是TimescaleDB,加了一个时间戳字段,不过没差。关于PostgreSQL中Json数据类型的操作,可以参考官网。

应用场景介绍

将TCP发过来的数据包(通过消息队列发过来)解析出数据(一个数据包含有多帧,一帧中含有多条信息),并和本地规则表的格式对应起来。以JsonLineMsg实体类代表对应的一帧数据:

package tsdb.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.sql.Timestamp;
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class JsonLineMsg {
    private Timestamp timeStamp; // 时间戳

    private String keyAndRuleData; // key value,key为根据规则表生成的唯一标识,value为TCP解析出的对应的数据。这个字段对应数据库中的Json类型字段,String类型进入数据库还需转换为Json格式。
}

对应psql的表结构为:

上面JsonLineMsg实体类的一个对象就代表的一帧中的所有数据项many(key:value)keyAndRuleData字段用来存储所有数据项,在psql中对应一个类型为json(或jsonb)的字段。

数据insert

为了查询JSON中的字段,在insert的过程中有些注意事项,如果插入时JSON格式不正确,查询JSON字段是总返回null

记录一下:为了降低数据库打开关闭的耗时,每积累20帧持久化一次。

note:

一帧中包含多条信息,一条信息对应一个key:value,所以每次从规则表生成的key和TCP解析出的value都要加到一个代表一帧所有数据的JSON串中。

要注意的代码如下:

                 // 存储一帧的所有key:value
                StringBuilder json = new StringBuilder();
                json.append("{");
                // frmLen 帧中信息个数
                for (int j = 0; j < frmLen; j++) {
                    StatRule stat = frm.getStat(j);
                    assert stat != null;
                    // 一条stat的key和value
                    int key = stat.getKey();
                    long value = System.nanoTime();
//                    String value = ParseStat.Parse(datas, stat);
                    json.append("\"");  // key左右必须加引号,key必为String类型
                    json.append(key);
                    json.append("\"");
                    json.append(":");
//                    json.append("\"");
                    json.append(value); // value左右不是必须加引号,若是String则加
//                    json.append("\"");
                    if ((j != statLen - 1)) {
                        json.append(",");
                    }
                }
                json.append("}");
                JsonLineMsg jsonLineMsg = new JsonLineMsg(new Timestamp(System.currentTimeMillis()), json.toString());

要注意的就是这个keyvalue加入数据库的类型如果为text(即java字符串)就要加引号,所以key两头必须加,value看情况。

对应的XML中的语句:

    <insert id="batchInsertJsonLineMsg"
            useGeneratedKeys="true" >
        insert into jsonlinemsg (timestamp ,keyandruledata ) values
        <foreach item="item" collection="list" separator="," close=";">
            (#{item.timeStamp},(#{item.keyAndRuleData})::json)
        </foreach>
    </insert>

这个::json就是将非json类型转为json类型,否则JAVA中String类型会对应其他的数据库字段类型,插入会报错。

note: psql 4种类型转换 https://www.postgresql.org/docs/14/sql-syntax-lexical.html

插入后用Navicat查看:

如果查看到类似于 "{"1":"1_234"}"{\"1\":\"1_123\"}这样,格式就是不正确的,查询JSON中字段会返回null。

数据select

  <select id="selectValueData" resultType="String">
        select keyandruledata::json ->>#{key}  from jsonlinemsg where timestamp = (#{time}::timestamp)
    </select>

要注意的就是这个::json,至于 -> 还是 ->>可以参考开头的官网链接。

ps: timescaledb官网推荐用jsonb,但是我测试发现jsonb查询插入都比不上json,不知道为啥
ps: 发现了,原来是转换为tsdb时,索引没建立起来,重新建表又测试了一遍,确实jsonb读取快。

BATCH 批量插入

// 获取连接的方法,设置ExecutorType.BATCH以及关闭自动提交
    public static SqlSession getSessionForBatch(String xmlPath, Properties properties) throws IOException {
        return MybatisUtil.getSqlSessionFactory(xmlPath, properties).openSession(ExecutorType.BATCH,false);
    }
    public void update(List<PropUrl> propUrlLst) throws IOException {
        // ExecutorType.BATCH
        try (SqlSession session = MybatisUtil.getSessionForBatch(myBatisConfigXmlPath)) {
            InitTsdbUrlTableMapper mapper = (InitTsdbUrlTableMapper) session.getMapper(mapperClazz);

            for (int i = 0; i < propUrlLst.size(); i++) {
                mapper.updatePropMatchRule(propUrlLst.get(i));
                // 每50次提交一次防止内存溢出
                if ((i+1) % 50 == 0) {
                    session.commit();
                    session.clearCache();
                }
            }
            session.commit();
            session.clearCache();

            log.info("update successfully ->{}", propUrlLst);
        }
    }

到此这篇关于利用Mybatis向PostgreSQL中插入并查询JSON字段的文章就介绍到这了,更多相关Mybatis查询JSON字段内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯