国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
Kettle實(shí)戰(zhàn)100篇 第9篇 Mysql數(shù)據(jù)庫(kù)數(shù)據(jù)導(dǎo)出到Excel

我們?cè)诘?篇的時(shí)候已經(jīng)介紹了將Excel的數(shù)據(jù)導(dǎo)入到Mysql數(shù)據(jù)庫(kù)中,那么,本章我們將介紹將數(shù)據(jù)從數(shù)據(jù)庫(kù)導(dǎo)出到Excel中.

較少數(shù)據(jù)導(dǎo)出

我們數(shù)據(jù)庫(kù)表數(shù)據(jù)如下圖:

數(shù)據(jù)庫(kù)中總共存在36條數(shù)據(jù),這是數(shù)據(jù)比較少的情況

新建轉(zhuǎn)換

我們選擇 文件 -> 新建 ->轉(zhuǎn)換

建立導(dǎo)出Excel的轉(zhuǎn)換,輸入轉(zhuǎn)換名稱(chēng)然后保存

表輸入

既然是從數(shù)據(jù)庫(kù)表導(dǎo)出數(shù)據(jù),所以我們的ETL的第一個(gè)步驟就是表輸入

新建數(shù)據(jù)庫(kù)連接

在選擇表輸入組件時(shí),我們首先需要?jiǎng)?chuàng)建我們的數(shù)據(jù)庫(kù)連接

點(diǎn)擊新建按鈕,在彈出的數(shù)據(jù)庫(kù)編輯框中填入數(shù)據(jù)庫(kù)信息,如下圖:

在輸入完成后,我們可以點(diǎn)擊測(cè)試按鈕對(duì)數(shù)據(jù)庫(kù)連接進(jìn)行測(cè)試,以查看數(shù)據(jù)庫(kù)是否可用

信息無(wú)誤后,點(diǎn)擊確定

此時(shí),我們可以輸入我們的查詢(xún)SQL語(yǔ)句對(duì)表進(jìn)行查詢(xún)以獲取結(jié)果

點(diǎn)擊預(yù)覽按鈕,彈出預(yù)覽記錄數(shù)量限制數(shù)量設(shè)置,即可以預(yù)覽數(shù)據(jù):

預(yù)覽無(wú)誤,說(shuō)明我們的信息是正確的,我們的表輸入最終屬性配置信息如下圖:

因?yàn)槲覀兛倲?shù)只有36條記錄,因此在記錄數(shù)量限制這里不妨可以設(shè)置一個(gè)最大值,此處我設(shè)置的是40

Microsoft Excel輸出

因?yàn)槲覀冏罱K是通過(guò)Excel輸出,因此我們從轉(zhuǎn)換的核心對(duì)象樹(shù)的輸出欄 選擇Microsoft Excel輸出組件

設(shè)置輸出組件的屬性

因?yàn)楸容^簡(jiǎn)單,因此我們只需要設(shè)置導(dǎo)出的Excel文件名稱(chēng)即可,如下圖:

運(yùn)行

此時(shí)我們的ETL轉(zhuǎn)換已創(chuàng)建完成,如下圖:

此時(shí),我們點(diǎn)擊Spoon界面上的運(yùn)行按鈕,執(zhí)行該轉(zhuǎn)換過(guò)程,導(dǎo)出Excel結(jié)果如下:

針對(duì)較少的數(shù)據(jù),利用Kettle非常輕松的幫助我們導(dǎo)出了數(shù)據(jù)到Excel中.

較多數(shù)據(jù)導(dǎo)出Excel

我們?cè)谏蟼€(gè)步驟中將數(shù)據(jù)庫(kù)表中較少數(shù)據(jù)(36條)導(dǎo)出到了Excel中,這幾乎沒(méi)什么難度,那么如果我們的數(shù)據(jù)庫(kù)表中數(shù)據(jù)比較多時(shí),是否也能按這種方式導(dǎo)出呢?

答案肯定是否定的,因?yàn)槿绻覀円淮尾樵?xún)數(shù)據(jù)較多的話(huà),很可能導(dǎo)致內(nèi)存溢出的異?;蛘逰ettle直接就崩潰了.

此時(shí)我們可以使用分頁(yè)技術(shù),來(lái)將我們的數(shù)據(jù)按頁(yè)碼批量導(dǎo)出

我們數(shù)據(jù)庫(kù)擁有fund表,此時(shí),我們想通過(guò)Kettle將fund表的記錄全部導(dǎo)出,我們應(yīng)該怎么做呢?

分頁(yè)導(dǎo)出

我們首先先按照分頁(yè)來(lái)進(jìn)行數(shù)據(jù)的導(dǎo)出

新建轉(zhuǎn)換

文件 -> 新建 -> 轉(zhuǎn)換

保存轉(zhuǎn)換名為:分頁(yè)導(dǎo)出數(shù)據(jù)

設(shè)置分頁(yè)變量

我們都知道Mysql中可以使用limit關(guān)鍵字來(lái)進(jìn)行分頁(yè)查詢(xún)數(shù)據(jù),因此第一步,我們需要通過(guò)生成記錄組件定義兩個(gè)變量,分別是:

  • pageSize:每頁(yè)查詢(xún)數(shù)據(jù)大小
  • offset:數(shù)據(jù)庫(kù)位移位置

表輸入

設(shè)置好變量后,我們可以拖入表輸入組件,進(jìn)行相關(guān)的屬性設(shè)置

分別設(shè)置SQL查詢(xún)語(yǔ)句,注意我們?cè)赟QL語(yǔ)句中使用了Mysql的limit分頁(yè),并且通過(guò)前面的變量來(lái)代替相關(guān)的值

如下圖:

Microsoft Excel輸出

最后,我們通過(guò)Excel輸出組件配置導(dǎo)出到Excel

這里我們需要注意的是,擴(kuò)展類(lèi)型我們需要選擇xlsx格式(因?yàn)?7格式會(huì)有總記錄的條數(shù)限制)

運(yùn)行

此時(shí),我們的最終轉(zhuǎn)換如下圖:

最終查看我們導(dǎo)出的數(shù)據(jù)如下:

全部導(dǎo)出

上面我們使用了分頁(yè)的方式將我們的數(shù)據(jù)按頁(yè)碼導(dǎo)到了Excel中,如果我們想把數(shù)據(jù)表中的全部數(shù)據(jù)都導(dǎo)入到Excel,應(yīng)該如何做呢?

此時(shí),我們可以把分頁(yè)導(dǎo)出轉(zhuǎn)換作為一個(gè)作業(yè)子項(xiàng),我們?cè)谧鳂I(yè)子項(xiàng)中設(shè)置分頁(yè)條件,輪訓(xùn)總頁(yè)碼進(jìn)行批量導(dǎo)出,核心點(diǎn)在于我們只需要設(shè)置offsetSize變量,然后輪訓(xùn)進(jìn)行替換即可

我們需要兩個(gè)計(jì)算頁(yè)碼的公式

根據(jù)記錄總數(shù)計(jì)算總頁(yè)碼:

var totalPage= (totalRows+pageSize-1) / pageSize;

計(jì)算Mysql中的offset值

var nowOffSize= pageSize * page ;

作業(yè)圖

我們先來(lái)梳理一下我們這個(gè)全部導(dǎo)出作業(yè)需要做的事情:

  • 首先需要查詢(xún)目標(biāo)表的總記錄數(shù),然后根據(jù)我們?cè)O(shè)置的每頁(yè)查詢(xún)大小計(jì)算出總頁(yè)數(shù)
  • 輪訓(xùn)分頁(yè)導(dǎo)出記錄到Excel 組件

因此,我們起碼需要一個(gè)作業(yè)和兩個(gè)轉(zhuǎn)換,才能幫助我們完成數(shù)據(jù)的全部導(dǎo)出任務(wù)

先來(lái)看我們已經(jīng)完成的作業(yè)圖,如下圖:

接下來(lái)我們逐步分析我們每個(gè)步驟的邏輯

新建作業(yè)

新建全部導(dǎo)出作業(yè)

選擇 文件 -> 新建 作業(yè)

設(shè)置變量

我們?cè)诮⒆鳂I(yè)任務(wù)時(shí),因?yàn)樾枰褂梅猪?yè)技術(shù)對(duì)數(shù)據(jù)進(jìn)行查詢(xún),因此我們的分頁(yè)導(dǎo)出數(shù)據(jù)中的轉(zhuǎn)換SQL語(yǔ)句就不能使用常量,必須使用變量。因此我們的作業(yè)第一步是設(shè)置變量,如下圖:

我們主要定義了5個(gè)變量并賦予初始值,并且變量的方位都是在JVM中有效

  • offsetSize:該值是我們?cè)谑褂肕ySQL分頁(yè)查詢(xún)語(yǔ)句limit的offset位移值
  • pageSize:每頁(yè)查詢(xún)的數(shù)據(jù)大小,默認(rèn)2000
  • totalPage:總頁(yè)數(shù),我們?cè)谶@里實(shí)現(xiàn)定義好變量,后面方便我們使用它
  • currentPage:當(dāng)前頁(yè)碼,默認(rèn)值1
  • shellFirst:該變量是我們?cè)诓樵?xún)MySQL數(shù)據(jù)后需要追加到Excel的其實(shí)行數(shù)值,A1代表從第一行開(kāi)始寫(xiě)入數(shù)據(jù),隨著翻頁(yè)查詢(xún),shellFirst的值變化規(guī)則是A(offsetSize+1)

獲取目標(biāo)數(shù)據(jù)表總記錄數(shù)

第二步我們就需要新建一個(gè)轉(zhuǎn)換,用來(lái)獲取我們的目標(biāo)表總記錄條數(shù),轉(zhuǎn)換如下圖:

這個(gè)轉(zhuǎn)換很簡(jiǎn)單,只有兩個(gè)組件:表輸入、復(fù)制記錄到結(jié)果

表輸入組件是我們編寫(xiě)從數(shù)據(jù)庫(kù)查詢(xún)目標(biāo)表的統(tǒng)計(jì)SQL語(yǔ)句,如下圖:

統(tǒng)計(jì)fund表的總記錄SQL語(yǔ)句:

SELECT count(*) fundCount from fund

然后將我們的結(jié)果復(fù)制到結(jié)果即可

JavaScript腳本-計(jì)算總頁(yè)數(shù)

我們得到了目標(biāo)表的總記錄數(shù),接下來(lái)我們需要一段JavaScript腳本幫助我們計(jì)算得到總頁(yè)數(shù),腳本內(nèi)容如下:

  1. var preRows=previous_result.getRows();//獲取上一個(gè)步驟的結(jié)果集

  2. var subject="自定義日志輸出";

  3. var logFactory = new org.pentaho.di.core.logging.LogChannelFactory();

  4. var log= logFactory.create(subject);

  5. if(preRows==null || preRows.size()==0){
  6. false;
  7. }else{

  8. var countBySql=preRows.get(0).getInteger("fundCount");

  9. //賦值變量
  10. var pageSize=parent_job.getVariable("pageSize");

  11. log.logMinimal("pageSize:"+pageSize+",countRecords:"+countBySql);


  12. //計(jì)算總頁(yè)碼
  13. var totalPage=com.xiaominfo.kettle.util.PaginationUtils.totalPage(countBySql,pageSize);

  14. log.logMinimal("totalPage:"+totalPage);

  15. //設(shè)置總頁(yè)碼
  16. parent_job.setVariable("totalPage",totalPage);
  17. true;

  18. }


這里有幾個(gè)組件需要說(shuō)明一下:

檢查字段的值

初始化好我們的總頁(yè)碼后,接下來(lái)我們就需要設(shè)置輪訓(xùn)分頁(yè)條件了,如下圖

設(shè)置當(dāng)前的頁(yè)面小于等于總頁(yè)碼數(shù),符合條件即進(jìn)行分頁(yè)Excel導(dǎo)出轉(zhuǎn)換的操作,否則程序結(jié)束.

分頁(yè)導(dǎo)出Excel轉(zhuǎn)換

在分頁(yè)導(dǎo)出Excel轉(zhuǎn)換中,區(qū)別于較少數(shù)據(jù)的轉(zhuǎn)換,我們需要從父作業(yè)中獲取變量,然后傳遞到子轉(zhuǎn)換中的相關(guān)組件中使用變量,所以整個(gè)子轉(zhuǎn)換如下圖:

第一步是獲取變量,該操作和我們上面較少數(shù)據(jù)導(dǎo)出其實(shí)是大同小異,無(wú)非是把生成記錄組件中定義的變量替換使用父作業(yè)中的變量 ,如下圖:

定義子轉(zhuǎn)換中的相關(guān)變量。

第二步是表輸入組件,分頁(yè)查詢(xún)數(shù)據(jù),如下圖:

在表輸入組件中,我們使用定義的變量代替SQL語(yǔ)句中的limit分頁(yè)數(shù)值,然后勾選替換SQL語(yǔ)句里的變量選項(xiàng)已經(jīng)使用懶惰算法選項(xiàng),記錄數(shù)量限制為0(即不限制)

最后我們選擇Microsoft Excel 輸出組件,把我們的結(jié)果輸出到Excel中

因?yàn)槲覀儾⒎鞘且淮稳繉?dǎo)出,而是采取的分頁(yè),因此在設(shè)置好文件名及文件擴(kuò)展后,需要選擇如果文件已存在則使用現(xiàn)有文件輸出

工作表選項(xiàng)卡中如果輸出文件中已存在工作表也選擇繼續(xù)輸出至已存在的工作表中

然后是內(nèi)容選項(xiàng)卡:

此處需要設(shè)置楷書(shū)輸出子單元格的變量,即我們父作業(yè)中定義的shellFirst變量,在Excel的Sheet表格中即代表從哪一行開(kāi)始輸出數(shù)據(jù)

然后勾選在表的末尾開(kāi)始寫(xiě)(追加行)選項(xiàng),最后點(diǎn)擊確定保存

檢查頁(yè)碼條件

接下來(lái)我們需要檢查賦值我們的頁(yè)碼,通過(guò)JavaScript腳本來(lái)實(shí)現(xiàn),腳本內(nèi)容如下:

  1. var page=parent_job.getVariable('currentPage');

  2. var totalPage=parent_job.getVariable('totalPage');

  3. var subject="自定義日志";

  4. var log= new org.pentaho.di.core.logging.LogChannel(subject);


  5. if(page==totalPage){

  6. false;
  7. }else{
  8. //設(shè)置offsetSize的值
  9. var pageSize=parent_job.getVariable('pageSize');
  10. //在page++之前先計(jì)算offset的值
  11. //offset方法為page*pageSize
  12. var nowOffSize=com.xiaominfo.kettle.util.PaginationUtils.offset(page,pageSize);

  13. page++;

  14. parent_job.setVariable('currentPage',page);

  15. var shellFirst=parent_job.getVariable('shellFirst');

  16. //日志輸出
  17. log.logMinimal("offset:"+nowOffSize);
  18. parent_job.setVariable('offsetSize',nowOffSize);
  19. var shellNum=nowOffSize+1;
  20. var newShellFirst=shellFirst.substring(0,1)+shellNum;
  21. log.logMinimal("Shell單元格開(kāi)始輸出記錄行:"+newShellFirst);
  22. parent_job.setVariable('shellFirst',newShellFirst);


  23. true;
  24. }

該代碼邏輯主要步驟:

  • 判斷當(dāng)前頁(yè)碼是否已經(jīng)等于總頁(yè)碼,即如果是最后是總頁(yè)碼則程序返回false,不繼續(xù)執(zhí)行
  • 如果當(dāng)前頁(yè)碼小于總頁(yè)碼,首先計(jì)算下一個(gè)SQL語(yǔ)句翻頁(yè)的offset的值(因?yàn)槲以谟?jì)算的時(shí)候并非是從0開(kāi)始,因此這里的page++動(dòng)作需要在后面執(zhí)行),賦值下一個(gè)offset的值
  • 當(dāng)前頁(yè)碼+1,使用parent_job內(nèi)置對(duì)象重新賦值當(dāng)前頁(yè)碼變量
  • 由offset值計(jì)算得到在輸出Excel數(shù)據(jù)時(shí)從哪一行開(kāi)始輸出(不能計(jì)算錯(cuò)誤,否則導(dǎo)出的 Excel數(shù)據(jù)不是缺失就是被覆蓋錯(cuò)誤),重新賦值shellFirst變量

執(zhí)行

整個(gè)作業(yè)過(guò)程完成,運(yùn)行該作業(yè),得到我們導(dǎo)出的該fund表的全部數(shù)據(jù)24332

FAQ

表輸入組件預(yù)覽數(shù)據(jù)、導(dǎo)出Excel數(shù)據(jù)亂碼

該問(wèn)題我在使用分頁(yè)查詢(xún)導(dǎo)出的時(shí)候碰到了亂碼的情況,我的情況比較特殊,我通過(guò)瀏覽已經(jīng)建立好的數(shù)據(jù)庫(kù)連接的中的數(shù)據(jù)時(shí)并非亂碼,而當(dāng)我使用表輸入組件中的預(yù)覽數(shù)據(jù)時(shí)缺產(chǎn)生了亂碼,因此我不得不設(shè)置我們的數(shù)據(jù)庫(kù)連接參數(shù)

亂碼主要分幾種情況

一、查看我們的數(shù)據(jù)庫(kù)的服務(wù)端字符集是否是UTF-8(常用字符集)

可以使用navicat連接到我們的數(shù)據(jù)庫(kù),然后使用命令行,輸入查詢(xún)語(yǔ)句進(jìn)行查看,如下:

  1. mysql> show variables like '%char%';
  2. +--------------------------+-----------------------------------------------+
  3. | Variable_name | Value |
  4. +--------------------------+-----------------------------------------------+
  5. | character_set_client | utf8mb4 |
  6. | character_set_connection | utf8mb4 |
  7. | character_set_database | utf8 |
  8. | character_set_filesystem | binary |
  9. | character_set_results | utf8mb4 |
  10. | character_set_server | utf8 |
  11. | character_set_system | utf8 |
  12. | character_sets_dir | D:\Users\xiaoymin\Bin\mariadb\share\charsets\ |
  13. +--------------------------+-----------------------------------------------+
  14. 8 rows in set (0.08 sec)

其中character_set_server就是我們的數(shù)據(jù)庫(kù)服務(wù)端編碼

我們也可以使用SQL語(yǔ)句查詢(xún)我們的表字段編碼,如下:

mysql> show full columns from fund;

如果我們第一步檢查是OK的,但是瀏覽數(shù)據(jù)依然是亂碼,那么我們就需要修改Kettle中的配置參數(shù)

點(diǎn)擊表輸入組件的編輯按鈕,對(duì)數(shù)據(jù)庫(kù)信息進(jìn)行編輯

1、選擇高級(jí)選項(xiàng)卡,添加相關(guān)字符碼

2、高級(jí)選項(xiàng)卡中設(shè)置names值,網(wǎng)上的解決方案大多是使用utf8,但是我本機(jī)使用后發(fā)現(xiàn)還是亂碼,因此我改成了gbk,這個(gè)大家自行根據(jù)自己的情況設(shè)定

set names gbk;

如下圖:

 

 

 

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶(hù)發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
Vue 3和Element組件庫(kù)的分頁(yè)功能實(shí)現(xiàn)
用云數(shù)據(jù)庫(kù)實(shí)現(xiàn)共享相冊(cè)_上
分頁(yè)的封裝
Extjs 分頁(yè)刪除 跳轉(zhuǎn)前一頁(yè)
sql 優(yōu)化之:實(shí)現(xiàn)小數(shù)據(jù)量和海量數(shù)據(jù)的通用分頁(yè)顯示存儲(chǔ)過(guò)程(系列四)
千萬(wàn)條數(shù)據(jù),Stack Overflow是如何實(shí)現(xiàn)快速分頁(yè)的?
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服