最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時間:2022年07月22日 14:59:59   作者:T.Y.Bao  
這篇文章主要介紹了利用Mybatis向PostgreSQL中插入并查詢JSON字段,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下

前言:

這里我使用的是TimescaleDB,加了一個時間戳字段,不過沒差。關(guān)于PostgreSQL中Json數(shù)據(jù)類型的操作,可以參考官網(wǎng)

應(yīng)用場景介紹

將TCP發(fā)過來的數(shù)據(jù)包(通過消息隊列發(fā)過來)解析出數(shù)據(jù)(一個數(shù)據(jù)包含有多幀,一幀中含有多條信息),并和本地規(guī)則表的格式對應(yīng)起來。以JsonLineMsg實體類代表對應(yīng)的一幀數(shù)據(jù):

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為根據(jù)規(guī)則表生成的唯一標識,value為TCP解析出的對應(yīng)的數(shù)據(jù)。這個字段對應(yīng)數(shù)據(jù)庫中的Json類型字段,String類型進入數(shù)據(jù)庫還需轉(zhuǎn)換為Json格式。
}

對應(yīng)psql的表結(jié)構(gòu)為:

上面JsonLineMsg實體類的一個對象就代表的一幀中的所有數(shù)據(jù)項many(key:value),keyAndRuleData字段用來存儲所有數(shù)據(jù)項,在psql中對應(yīng)一個類型為json(或jsonb)的字段。

數(shù)據(jù)insert

為了查詢JSON中的字段,在insert的過程中有些注意事項,如果插入時JSON格式不正確,查詢JSON字段是總返回null。

記錄一下:為了降低數(shù)據(jù)庫打開關(guān)閉的耗時,每積累20幀持久化一次。

note:

  • foreach批量插入 、 mybatis ExecutorType.BATCH模式插入 、 for循環(huán)insert
  • 其實實際意義上來說,包括在程序里面for循環(huán)還是在sql里面for循環(huán)都不算是批量操作。只有將ExecutorType設(shè)置為BATCH模式才是真正意義上的批量操作。 并且事實證明在sql循環(huán)時設(shè)置batch與否其實執(zhí)行時間差別不是很大,幾乎可以忽略不計。所以其實如果不是特別要求性能??梢灾苯釉趕ql中使用for循環(huán)即可 。謹慎使用batch,如果需要使用batch,請在需要的函數(shù)上面設(shè)置batch,不要全局使用。因為batch也是有副作用的。 比如在Insert操作時,在事務(wù)沒有提交之前,是沒有辦法獲取到自增的id,;此外,對于update、delete無法返回更新、插入條數(shù)。這在某型情形下是不符合業(yè)務(wù)要求的。上面的是搬運的,不過后來有看了看,還是應(yīng)該用BATCH的Executor來批量導(dǎo)入,實際項目中foreach不可控,指不定啥時候就報錯了,文章最后記錄了ExecutorType為BATCH寫法的關(guān)鍵部分) foreach的xml拼接sql是最不推薦的方式,使用時有大段的xml和sql語句要寫,很容易出錯,工作效率很低。更關(guān)鍵點是,雖然效率尚可,但是真正需要效率的時候你掛了,要你何用? 批處理執(zhí)行是有大數(shù)據(jù)量插入時推薦的做法,使用起來也比較方便。
  • 關(guān)于批處理的方式的具體說明,可以參考推文強烈推薦MyBatis 三種批量插入方式的比較或者去StackOverFlow查一下,講解的比較全面,總之,還是用ExecutorType為BATCH寫法比較靠譜。

一幀中包含多條信息,一條信息對應(yīng)一個key:value,所以每次從規(guī)則表生成的key和TCP解析出的value都要加到一個代表一幀所有數(shù)據(jù)的JSON串中。

要注意的代碼如下:

                 // 存儲一幀的所有key:value
                StringBuilder json = new StringBuilder();
                json.append("{");
                // frmLen 幀中信息個數(shù)
                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加入數(shù)據(jù)庫的類型如果為text(即java字符串)就要加引號,所以key兩頭必須加,value看情況。

對應(yīng)的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類型轉(zhuǎn)為json類型,否則JAVA中String類型會對應(yīng)其他的數(shù)據(jù)庫字段類型,插入會報錯。

note: psql 4種類型轉(zhuǎn)換 https://www.postgresql.org/docs/14/sql-syntax-lexical.html

  • type 'string' 只能用于字面常量轉(zhuǎn)換、且不能用于數(shù)組中
  • typename ( 'string' ) 可用于運行時類型轉(zhuǎn)換
  • 'string'::type 可用于數(shù)組,可用于運行時類型轉(zhuǎn)換
  • CAST ( 'string' AS type ) 可用于數(shù)組,可用于運行時類型轉(zhuǎn)換

插入后用Navicat查看:

如果查看到類似于 "{"1":"1_234"}"、{\"1\":\"1_123\"}這樣,格式就是不正確的,查詢JSON中字段會返回null。

數(shù)據(jù)select

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

要注意的就是這個::json,至于 -> 還是 ->>可以參考開頭的官網(wǎng)鏈接。

ps: timescaledb官網(wǎng)推薦用jsonb,但是我測試發(fā)現(xiàn)jsonb查詢插入都比不上json,不知道為啥
ps: 發(fā)現(xiàn)了,原來是轉(zhuǎn)換為tsdb時,索引沒建立起來,重新建表又測試了一遍,確實jsonb讀取快。

BATCH 批量插入

// 獲取連接的方法,設(shè)置ExecutorType.BATCH以及關(guān)閉自動提交
    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次提交一次防止內(nèi)存溢出
                if ((i+1) % 50 == 0) {
                    session.commit();
                    session.clearCache();
                }
            }
            session.commit();
            session.clearCache();

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

到此這篇關(guān)于利用Mybatis向PostgreSQL中插入并查詢JSON字段的文章就介紹到這了,更多相關(guān)Mybatis查詢JSON字段內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java實現(xiàn)中文字符串與unicode互轉(zhuǎn)工具類

    Java實現(xiàn)中文字符串與unicode互轉(zhuǎn)工具類

    這篇文章主要為大家詳細介紹了Java實現(xiàn)中文字符串與unicode互轉(zhuǎn)的工具類,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-04-04
  • Java利用位運算實現(xiàn)加減運算詳解

    Java利用位運算實現(xiàn)加減運算詳解

    這篇文章主要為大家介紹了如何使用位運算來實現(xiàn)加減功能,也就是在整個運算過程中不能出現(xiàn)加減符號。文中的示例代碼講解詳細,感興趣的可以了解一下
    2022-12-12
  • Java中的Pair詳細

    Java中的Pair詳細

    這篇文章主要介紹Java中的很有意思的Pair,下面文章會以Pair用法展開,感興趣的小伙伴可以參考下面文章的具體內(nèi)容
    2021-10-10
  • Java設(shè)計模式之單例模式詳解

    Java設(shè)計模式之單例模式詳解

    這篇文章主要為大家詳細介紹了Java設(shè)計模式之單例模式的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • Java實現(xiàn)的文本字符串操作工具類實例【數(shù)據(jù)替換,加密解密操作】

    Java實現(xiàn)的文本字符串操作工具類實例【數(shù)據(jù)替換,加密解密操作】

    這篇文章主要介紹了Java實現(xiàn)的文本字符串操作工具類,可實現(xiàn)數(shù)據(jù)替換、加密解密等操作,涉及java字符串遍歷、編碼轉(zhuǎn)換、替換等相關(guān)操作技巧,需要的朋友可以參考下
    2017-10-10
  • Java異常 Factory method''sqlSessionFactory''rew exception;ested exception is java.lang.NoSuchMethodError:

    Java異常 Factory method''sqlSessionFactory''rew exception;este

    這篇文章主要介紹了Java異常 Factory method ‘sqlSessionFactory‘ threw exception; nested exception is java.lang.NoSuchMethodError:,本文介紹了springboot 引入mybatis-plus后報錯的解決方案,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • Java實現(xiàn)矩陣乘法以及優(yōu)化的方法實例

    Java實現(xiàn)矩陣乘法以及優(yōu)化的方法實例

    這篇文章主要給大家介紹了關(guān)于Java實現(xiàn)矩陣乘法以及優(yōu)化的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • Java 判斷線程池所有任務(wù)是否執(zhí)行完畢的操作

    Java 判斷線程池所有任務(wù)是否執(zhí)行完畢的操作

    這篇文章主要介紹了Java 判斷線程池所有任務(wù)是否執(zhí)行完畢的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • SpringBoot集成SpringSecurity和JWT做登陸鑒權(quán)的實現(xiàn)

    SpringBoot集成SpringSecurity和JWT做登陸鑒權(quán)的實現(xiàn)

    這篇文章主要介紹了SpringBoot集成SpringSecurity和JWT做登陸鑒權(quán)的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • SpringBoot新特性之全局懶加載機制

    SpringBoot新特性之全局懶加載機制

    這篇文章主要介紹了SpringBoot新特性之全局懶加載機制,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07

最新評論

莆田市| 伊春市| 徐水县| 吕梁市| 徐闻县| 侯马市| 平潭县| 白河县| 荥阳市| 刚察县| 鄂伦春自治旗| 苗栗市| 青田县| 修水县| 桃源县| 清镇市| 陆河县| 开封市| 巴林右旗| 禄丰县| 江山市| 广水市| 文登市| 定南县| 华池县| 白朗县| 会东县| 达孜县| 静宁县| 清徐县| 汝南县| 永济市| 宁陕县| 惠东县| 克东县| 维西| 凯里市| 巴东县| 井陉县| 棋牌| 兴海县|