第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

需要將大型 QueryRunner 結(jié)果流式傳輸?shù)轿募?,似乎存?chǔ)在內(nèi)存中

需要將大型 QueryRunner 結(jié)果流式傳輸?shù)轿募?,似乎存?chǔ)在內(nèi)存中

我正在嘗試構(gòu)建一個(gè) Java 應(yīng)用程序,該應(yīng)用程序可以將任意 SQL SELECT 查詢的非常大的結(jié)果集流式傳輸?shù)?JSONL 文件中,特別是通過 SQLServer 但希望與任何 JDBC 一起運(yùn)行DataSource。在 Python 中,這很容易將 sql 客戶端結(jié)果視為生成器,然后調(diào)用json.dumps(). 但是,在這段代碼中,它似乎在寫出之前將所有內(nèi)容都放入了內(nèi)存中,這通常會(huì)導(dǎo)致堆和垃圾收集異常。我需要運(yùn)行它的查詢非常大,最多可以帶回 10GB 的原始數(shù)據(jù)。執(zhí)行時(shí)間不是主要問題,只要它每次都有效。我試過在每一行之后調(diào)用flush(這很荒謬),這似乎對(duì)小數(shù)據(jù)集有幫助,但對(duì)大數(shù)據(jù)集沒有幫助。任何人都可以提出一個(gè)我可以用來輕松實(shí)現(xiàn)這一目標(biāo)的策略嗎?在我的 SQL 客戶端類中,我使用 Apache DbUtilsQueryRunner并MapListHandler創(chuàng)建一個(gè)Maps 列表,這是我需要的靈活性(與 Java 中需要指定模式和類型的更傳統(tǒng)方法相比):public List<Map<String, Object>> query(String queryText) {    try {        DbUtils.loadDriver("com.microsoft.sqlserver.jdbc.Driver");        // this function just sets up all the connection properties. Ommitted for clarity        DataSource ds = this.initDataSource();        StatementConfiguration sc = new StatementConfiguration.Builder().fetchSize(10000).build();        QueryRunner queryRunner = new QueryRunner(ds, sc);        MapListHandler handler = new MapListHandler();        return queryRunner.query(queryText, handler);    } catch (Exception e) {        logger.error(e.getMessage());        e.printStackTrace();        return null;    }}JsonLOutputWriter班級(jí):JsonLOutputWriter(String filename) {    GsonBuilder gsonBuilder = new GsonBuilder();    gsonBuilder.serializeNulls();    this.gson = gsonBuilder.create();    try {        this.writer = new PrintWriter(new File(filename), ENCODING);    } catch (FileNotFoundException | UnsupportedEncodingException e) {        e.printStackTrace();    }}void writeRow(Map row) {    this.writer.println(this.gson.toJson(row));}void flush() {    this.writer.flush();}主要方法:JsonLOutputWriter writer = new JsonLOutputWriter(outputFile)for (Map row : client.query(inputSql)) {    writer.writeRow(row);}writer.flush()
查看完整描述

1 回答

?
一只甜甜圈

TA貢獻(xiàn)1836條經(jīng)驗(yàn) 獲得超5個(gè)贊

基本上這不能在DbUtils開箱即用的情況下完成。我擺脫了QueryRunner并且MapListHandler因?yàn)樘幚沓绦騽?chuàng)建了一個(gè)ArrayList. 我不是基于拉,而是基于推,創(chuàng)建了一個(gè)非常相似的方法MyQueryRunner,它需要 aMyRowHandler而不是返回一個(gè)集合,而是迭代ResultSet并調(diào)用我的輸出函數(shù)。


我確信有更優(yōu)雅的方法可以做到這一點(diǎn)并返回某種行緩沖區(qū),但這是我需要的 80/20 并且適用于大型數(shù)據(jù)集。


行處理程序


public class RowHandler {

    private static final RowProcessor ROW_PROCESSOR = new BasicRowProcessor();

    private JsonLOutputWriter writer;


    public RowHandler(JsonLOutputWriter writer) {

        this.writer = writer;

    }


    int handle(ResultSet rs) throws SQLException {

        AtomicInteger counter = new AtomicInteger();

        while (rs.next()) {

            writer.writeRow(this.handleRow(rs));

            counter.getAndIncrement();

        }

        return counter.intValue();

    }


    protected Map<String, Object> handleRow(ResultSet rs) throws SQLException {

        return this.ROW_PROCESSOR.toMap(rs);

    }


}

查詢處理程序


class CustomQueryRunner extends AbstractQueryRunner {


    private final RowHandler rh;


    CustomQueryRunner(DataSource ds, StatementConfiguration stmtConfig, RowHandler rh) {

        super(ds, stmtConfig);

        this.rh = rh;

    }


    int query(String sql) throws SQLException {

        Connection conn = this.prepareConnection();

        return this.query(conn, true, sql);

    }


    private int query(Connection conn, boolean closeConn, String sql, Object... params)

            throws SQLException {

        if (conn == null) {

            throw new SQLException("Null connection");

        }

        PreparedStatement stmt = null;

        ResultSet rs = null;

        int count = 0;

        try {

            stmt = this.prepareStatement(conn, sql);

            this.fillStatement(stmt, params);

            rs = this.wrap(stmt.executeQuery());

            count = rh.handle(rs);

        } catch (SQLException e) {

            this.rethrow(e, sql, params);

        } finally {

            try {

                close(rs);

            } finally {

                close(stmt);

                if (closeConn) {

                    close(conn);

                }

            }

        }

        return count;

    }

}


查看完整回答
反對(duì) 回復(fù) 2022-05-12
  • 1 回答
  • 0 關(guān)注
  • 137 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)