主頁 > 後端開發 > Apache Druid資料查詢套件詳解計數、排名和分位數計算(送JSON-over-HTTP和SQL兩種查詢詳解)

Apache Druid資料查詢套件詳解計數、排名和分位數計算(送JSON-over-HTTP和SQL兩種查詢詳解)

2022-09-09 06:19:45 後端開發

5. 資料查詢

欲看此文,必看如下兩篇文章:

Druid支持JSON-over-HTTP和SQL兩種查詢方式,除了標準的SQL操作外,Druid還支持大量的唯一性操作,利用Druid提供的演算法套件可以快速的進行計數,排名和分位數計算,

file

5.1 準備作業

5.1.1 匯入大量資料

準備大量資料提供查詢,我們插入1萬條隨機打車資料

http://localhost:8010/taxi/batchTask/100000

file

5.2.2 查看資料攝取行程

我們發現資料攝取行程正在運行,可以等待資料攝取任務結束

file

5.3 原生查詢

Druid 最開始的時候是不支持 SQL 查詢的,原生查詢是通過查詢 Broker 提供的 http server 來實作的

5.3.1 查詢語法
curl -L -H'Content-Type:application/json' -XPOST --data-binary  @<query_json_file> <queryable_host>:<port>/druid/v2/?pretty
5.3.2 查詢案例
5.3.2.1 編輯查詢JSON
# 創建查詢目錄
mkdir query
# 編輯查詢的JSON
vi query/filter1.json

json 內容如下

{
    "queryType":"timeseries",
    "dataSource":"message",
    "granularity":"month",
    "aggregations":[
     {
            "type":"count",
            "name":"taxiNum"
     }
    ],
    "filter":{"type":"selector","dimension":"status","value":1},
    "intervals":["2021-06-07/2022-06-07"]
}
5.3.2.2 引數解釋
  • queryType:查詢型別,timeseries代表時間序列查詢
  • dataSource:資料源,指定需要查詢的資料源是什么
  • granularity:分組粒度,指定需要進行分組的粒度是什么樣的
  • aggregations:聚合查詢:里面我們聚合了count,對資料進行統計
  • filter:資料過濾,需要查詢那些資料
  • intervals:查詢時間的范圍,注意時間范圍是前閉后開的,后面的日期是查詢不到的
5.3.2.3 執行查詢命令

在命名行中執行下面的命令會將查詢json發送到對應的broker中進行查詢--data-binary指定的查詢json的路徑

curl -L -H 'Content-Type:application/json' -XPOST --data-binary @query/filter1.json http://192.168.64.177:8082/druid/v2/?pretty

我們查詢了每個月發起打車的人數有多少

file

5.4 查詢型別

druid查詢采用的是HTTP RESTFUL方式,REST介面負責接收客戶端的查詢請求,客戶端只需要將查詢條件封裝成JSON格式,通過HTTP方式將JSON查詢條件發送到broker節點,查詢成功會回傳JSON格式的結果資料,了解一下druid提供的查詢型別

5.4.1 時間序列查詢

timeseries時間序列查詢對于指定時間段按照查詢規則回傳聚合后的結果集,查詢規則中可以設定查詢粒度,結果排序方式以及過濾條件,過濾條件可以使用嵌套過濾,并且支持后聚合,

5.4.1.1 查詢屬性

時間序列查詢主要包括7個主要部分

屬性 描述 是否必須
queryType 該字串總是"timeseries"; 該欄位告訴Apache Druid如何去解釋這個查詢
dataSource 用來標識查詢的的字串或者物件,與關系型資料庫中的表類似,查看資料源可以獲得更多資訊
descending 是否對結果集進行降序排序,默認是false, 也就是升序排列
intervals ISO-8601格式的JSON物件,定義了要查詢的時間范圍
granularity 定義了查詢結果的粒度,參見 Granularity
filter 參見 Filters
aggregations 參見 聚合
postAggregations 參見Post Aggregations
limit 限制回傳結果數量的整數值,默認是unlimited
context 可以被用來修改查詢行為,包括 Grand Total 和 Zero-filling,詳情可以看 背景關系引數部分中的所有引數型別
5.4.1.2 案例
{
    "queryType":"topN",
    "dataSource":"taxi_message",
    "dimension":"local",
    "threshold":2,
    "metric":"age",
    "granularity":"month",
    "aggregations":[
     {
        "type":"longMin",
        "name":"age",
        "fieldName":"age"
     }
     ],
    "filter":{"type":"selector","dimension":"sex","value":"女"},
    "intervals":["2021-06-07/2022-06-07"]
}
5.4.2 TopN查詢

topn查詢是通過給定的規則和顯示維度回傳一個結果集,topn查詢可以看做是給定排序規則,回傳單一維度的group by查詢,但是topn查詢比group by性能更快,metric這個屬性是topn專屬的按照該指標排序,

5.4.2.1 查詢屬性

topn的查詢屬性如下

屬性 描述 是否必須
queryType 該字串總是"TopN",Druid根據該值來確定如何決議查詢
dataSource 定義將要查詢的字串或者物件,與關系型資料庫中的表類似, 詳情可以查看 資料源 部分,
intervals ISO-8601格式的時間間隔,定義了查詢的時間范圍
granularity 定義查詢粒度, 參見 Granularities
filter 參見 Filters
aggregations 參見Aggregations 對于數值型別的metricSpec, aggregations或者postAggregations必須指定,否則非必須
postAggregations 參見postAggregations 對于數值型別的metricSpec, aggregations或者postAggregations必須指定,否則非必須
dimension 一個string或者json物件,用來定義topN查詢的維度列,詳情參見DimensionSpec
threshold 在topN中定義N的一個整型數字,例如:在top串列中回傳多少個結果
metric 一個string或者json物件,用來指定top串列的排序,更多資訊可以參見TopNMetricSpec
context 參見Context
5.4.2.2 案例

查詢每個季度年齡最小的女性的前兩個的城市

vi query/topN.json
{
    "queryType":"topN",
    "dataSource":"message",
    "dimension":"local",
    "threshold":2,
    "metric":"age",
    "granularity":"quarter",
    "aggregations":[
     {
            "type":"longMin",
            "name":"age",
         	"fieldName":"age"
     }
      ],
    "filter":{"type":"selector","dimension":"sex","value":"女"},
    "intervals":["2021-06-07/2022-06-07"]
}
5.4.2.3 執行查詢
curl -L -H 'Content-Type:application/json' -XPOST --data-binary @query/topN.json http://192.168.64.177:8082/druid/v2/?pretty

file

5.4.5 分組查詢

在實際應用中經常需要進行分組查詢,等同于sql陳述句中的Group by查詢,如果對單個維度和指標進行分組聚合計算,推薦使用topN查詢,能夠獲得更高的查詢性能,分組查詢適合多維度,多指標聚合查詢

5.4.5.1 查詢屬性

下表內容為一個GroupBy查詢的主要部分:

屬性 描述 是否必須
queryType 該字串應該總是"groupBy", Druid根據該值來確定如何決議查詢
dataSource 定義將要查詢的字串或者物件,與關系型資料庫中的表類似, 詳情可以查看 資料源 部分,
dimension 一個用來GroupBy的json List,詳情參見DimensionSpec來了解提取維度的方式
limitSpec 參見limitSpec
having 參見Having
granularity 定義查詢粒度,參見 Granularities
filter 參見Filters
aggregations 參見Aggregations
postAggregations 參見Post Aggregations
intervals ISO-8601格式的時間間隔,定義了查詢的時間范圍
subtotalsSpec 一個JSON陣列,回傳頂級維度子集分組的附加結果集,稍后將更詳細地描述它,
context 參見Context
5.4.5.2 案例

每一季度統計年齡在21-31的男女打車的數量

vi query/groupBy.json
{
    "queryType":"groupBy",
    "dataSource":"taxi_message",
    "granularity":"Quarter",
    "dimensions":["sex"],
    "aggregations":[
     {
            "type":"count",
            "name":"taxiNum"
     }
    ],
    "filter":{
		"type":"bound",
		"dimension":"age",
		"lower":"21",
		"upper":"31", 
		"alphaNumeric":true 
    },
    "intervals":["2021-06-07/2022-06-07"]
}
5.4.5.3 執行查詢
curl -L -H 'Content-Type:application/json' -XPOST --data-binary @query/groupBy.json http://192.168.64.177:8082/druid/v2/?pretty

file

5.5 查詢組件

在介紹具體的查詢之前,我們先來了解一下各種查詢都會用到的基本組件,如Filter,Aggregator,Post-Aggregator,Query,Interval等,每種組件都包含很多的細節

5.5.1 Filter

Filter就是過濾器,在查詢陳述句中就是一個JSON物件,用來對維度進行篩選和過濾,表示維度滿足Filter的行是我們需要的資料,類似sql中的where字句,Filter包含的型別如下:

5.5.1.1 選擇過濾器

Selector Filter的功能類似于SQL中的where key=value,它的json示例如下

"Filter":{"type":"selector","dimension":dimension_name,"value":target_value}

使用案例

vi query/filter1.json
{
    "queryType":"timeseries",
    "dataSource":"taxi_message",
    "granularity":"month",
    "aggregations":[
     {
            "type":"count",
            "name":"taxiNum"
     }
    ],
    "filter":{"type":"selector","dimension":"status","value":1},
    "intervals":["2021-06-07/2022-06-07"]
}
5.5.1.2 正則過濾器

Regex Filter 允許用戶使用正則運算式進行維度的過濾篩選,任何java支持的標準正則運算式druid都支持,它的JSON格式如下:

"filter":{"type":"regex","dimension":dimension_name,"pattern":regex}

使用案例,我們搜索姓名包含數字的的用戶進行聚合統計

vi query/filter2.json
{
    "queryType":"timeseries",
    "dataSource":"taxi_message",
    "granularity":"month",
    "aggregations":[
     {
            "type":"count",
            "name":"taxiNum"
     }
    ],
    "filter":{"type":"regex","dimension":"username","pattern":"[0-9]{1,}"},
    "intervals":["2021-06-07/2022-06-07"]
}

執行查詢

curl -L -H 'Content-Type:application/json' -XPOST --data-binary @query/filter2.json http://192.168.64.177:8082/druid/v2/?pretty

file

5.5.1.3 邏輯過濾器

Logincal Expression Filter包含and,not,or三種過濾器,每一種都支持嵌套,可以構建豐富的邏輯運算式,與sql中的and,not,or類似,JSON運算式如下:

"filter":{"type":"and","fields":[filter1,filter2]}
"filter":{"type":"or","fields":[filter1,filter2]}
"filter":{"type":"not","fields":[filter]}

使用案例,我們查詢每一個月,進行打車并且是女性的數量

vi query/filter3.json
{
    "queryType":"timeseries",
    "dataSource":"taxi_message",
    "granularity":"month",
    "aggregations":[
     {
            "type":"count",
            "name":"taxiNum"
     }
    ],
    "filter":{
        "type":"and",
        "fields":[
            {"type":"selector","dimension":"status","value":1},
            {"type":"selector","dimension":"sex","value":"女"}
        ]
    },
    "intervals":["2021-06-07/2022-06-07"]
}

進行資料查詢

curl -L -H 'Content-Type:application/json' -XPOST --data-binary @query/filter3.json http://192.168.64.177:8082/druid/v2/?pretty

file

5.5.1.4 包含過濾器

In Filter類似于SQL中的in, 比如 where username in('zhangsan','lisi','zhaoliu'),它的JSON格式如下:

{
	"type":"in",
	"dimension":"local",
	"values":['四川省','江西省','福建省']
}

使用案例,我們查詢每一個月,在四川省、江西省、福建省打車的人數

vi query/filter4.json
{
    "queryType":"timeseries",
    "dataSource":"taxi_message",
    "granularity":"month",
    "aggregations":[
     {
            "type":"count",
            "name":"taxiNum"
     }
    ],
    "filter":{
        "type":"in",
        "dimension":"local",
        "values":["四川省","江西省","福建省"]
    },
    "intervals":["2021-06-07/2022-06-07"]
}

進行資料查詢

curl -L -H 'Content-Type:application/json' -XPOST --data-binary @query/filter4.json http://192.168.64.177:8082/druid/v2/?pretty

file

5.5.1.5 區間過濾器

Bound Filter是比較過濾器,包含大于,等于,小于三種,它默認支持的就是字串比較,是基于字典順序,如果使用數字進行比較,需要在查詢中設定alpaNumeric的值為true,需要注意的是Bound Filter默認的大小比較為>=或者<=,因此如果使用<或>,需要指定lowerStrict值為true,或者upperStrict值為true,它的JSON格式如下: 21 <=age<=31

{
"type":"bound",
"dimension":"age",
"lower":"21",  #默認包含等于
"upper":"31",  #默認包含等于
"alphaNumeric":true #數字比較時指定alphaNumeric為true
}

使用案例,我們查詢每一個月,年齡在21-31之間打車人的數量

vi query/filter5.json
{
    "queryType":"timeseries",
    "dataSource":"taxi_message",
    "granularity":"month",
    "aggregations":[
     {
            "type":"count",
            "name":"taxiNum"
     }
    ],
    "filter":{
		"type":"bound",
		"dimension":"age",
		"lower":"21",
		"upper":"31", 
		"alphaNumeric":true 
    },
    "intervals":["2021-06-07/2022-06-07"]
}

進行資料查詢

curl -L -H 'Content-Type:application/json' -XPOST --data-binary @query/filter5.json http://192.168.64.177:8082/druid/v2/?pretty

file

5.5.2 聚合粒度

聚合粒度通過granularity配置項指定聚合時間跨度,時間跨度范圍要大于等于創建索引時設定的索引粒度,druid提供了三種型別的聚合粒度分別是:Simple,Duration,Period

5.5.2.1 Simple的聚合粒度

Simple的聚合粒度通過druid提供的固定時間粒度進行聚合,以字串表示,定義查詢規則的時候不需要顯示設定type配置項,druid提供的常用Simple粒度:

all,none,minute,fifteen_minute,thirty_minute,hour,day,month,Quarter(季度),year;

  • all:會將起始和結束時間內所有資料聚合到一起回傳一個結果集,

  • none:按照創建索引時的最小粒度做聚合計算,最小粒度是毫秒為單位,不推薦使用性能較差;

  • minute:以分鐘作為聚合的最小粒度;

  • fifteen_minute:15分鐘聚合;

  • thirty_minute:30分鐘聚合

  • hour:一小時聚合

  • day:天聚合

  • month:月聚合

  • Quarter:季度聚合

  • year:年聚合

撰寫測驗,我們這里按照季度聚合,并且我們過濾年齡是21-31的資料,并且按照地域以及性別進行分組

vi query/filter6.json
{
    "queryType":"groupBy",
    "dataSource":"taxi_message",
    "granularity":"Quarter",
    "dimensions":["local","sex"],
    "aggregations":[
     {
            "type":"count",
            "name":"taxiNum"
     }
    ],
    "filter":{
		"type":"bound",
		"dimension":"age",
		"lower":"21",
		"upper":"31", 
		"alphaNumeric":true 
    },
    "intervals":["2021-06-07/2022-06-07"]
}

進行查詢

curl -L -H 'Content-Type:application/json' -XPOST --data-binary @query/filter6.json http://192.168.64.177:8082/druid/v2/?pretty

file

5.5.2.2 Duration聚合粒度

duration聚合粒度提供了更加靈活的聚合粒度,不只局限于Simple聚合粒度提供的固定聚合粒度,而是以毫秒為單位自定義聚合粒度,比如兩小時做一次聚合可以設定duration配置項為7200000毫秒,所以Simple聚合粒度不能夠滿足的聚合粒度可以選擇使用Duration聚合粒度,

注意:使用Duration聚合粒度需要設定配置項type值為duration

撰寫測驗,我們按照

vi query/filter7.json
{
    "queryType":"groupBy",
    "dataSource":"taxi_message",
    "granularity":{
    	"type":"duration",
    	"duration":7200000
    },
    "dimensions":["local","sex"],
    "aggregations":[
     {
            "type":"count",
            "name":"taxiNum"
     }
    ],
    "filter":{
		"type":"bound",
		"dimension":"age",
		"lower":"21",
		"upper":"31", 
		"alphaNumeric":true 
    },
    "intervals":["2021-06-07/2021-06-10"]
}

資料查詢

curl -L -H 'Content-Type:application/json' -XPOST --data-binary @query/filter7.json http://192.168.64.177:8082/druid/v2/?pretty

file

5.5.2.3 Period聚合粒度

Period聚合粒度采用了日期格式,常用的幾種時間跨度表示方法,一小時:PT1H,一周:P1W,一天:P1D,一個月:P1M;使用Period聚合粒度需要設定配置項type值為period,

撰寫測驗,我們按照一天進行聚合

vi query/filter8.json
{
    "queryType":"groupBy",
    "dataSource":"taxi_message",
    "granularity":{
    	"type":"period",
		"period":"P1D"
    },
    "dimensions":["sex"],
    "aggregations":[
     {
            "type":"count",
            "name":"taxiNum"
     }
    ],
    "filter":{
		"type":"bound",
		"dimension":"age",
		"lower":"21",
		"upper":"31", 
		"alphaNumeric":true 
    },
    "intervals":["2021-06-07/2021-06-10"]
}

資料查詢

curl -L -H 'Content-Type:application/json' -XPOST --data-binary @query/filter8.json http://192.168.64.177:8082/druid/v2/?pretty

file

5.5.3 聚合器

Aggregator是聚合器,聚合器可以在資料攝入階段和查詢階段使用,在資料攝入階段使用聚合器能夠在資料被查詢之前按照維度進行聚合計算,提高查詢階段聚合計算性能,在查詢程序中,使用聚合器能夠實作各種不同指標的組合計算,

5.5.3.1 公共屬性

聚合器的公共屬性介紹

  • type:宣告使用的聚合器型別;

  • name:定義回傳值的欄位名稱,相當于sql語法中的欄位別名;

  • fieldName:資料源中已定義的指標名稱,該值不可以自定義,必須與資料源中的指標名一致;

5.5.3.2 計數聚合

計數聚合器,等同于sql語法中的count函式,用于計算druid roll-up合并之后的資料條數,并不是攝入的原始資料條數,在定義資料模式指標規則中必須添加一個count型別的計數指標count;

比如想查詢Roll-up 后有多少條資料,查詢的JSON格式如下

vi query/aggregator1.json
{
    "queryType":"timeseries",
    "dataSource":"taxi_message",
    "granularity":"Quarter",
    "aggregations":[
     	{
            "type":"count",
            "name":"count"
     	}
    ],
    "filter":{
		"type":"bound",
		"dimension":"age",
		"lower":"21",
		"upper":"31", 
		"alphaNumeric":true 
    },
    "intervals":["2021-06-07/2022-06-07"]
}
5.5.3.3 求合聚合

求和聚合器,等同于sql語法中的sum函式,用戶指標求和計算,druid提供兩種型別的聚合器,分別是long型別和double型別的聚合器;

第一類就是longSum Aggregator ,負責整數型別的計算,JSON格式如下:

{"type":"longSum","name":out_name,"fieldName":"metric_name"}

第二類是doubleSum Aggregator,負責浮點數計算,JSON格式如下:

{"type":"doubleSum","name":out_name,"fieldName":"metric_name"}

示例

vi query/aggregator2.json
{
    "queryType":"timeseries",
    "dataSource":"taxi_message",
    "granularity":"Quarter",
    "aggregations":[
     	{
            "type":"longSum",
            "name":"ageSum",
            "fieldName":"age"
     	}
    ],
    "filter":{
		"type":"bound",
		"dimension":"age",
		"lower":"21",
		"upper":"31", 
		"alphaNumeric":true 
    },
    "intervals":["2021-06-07/2022-06-07"]
}

5.6 Druid SQL

Druid SQL是一個內置的SQL層,是Druid基于JSON的本地查詢語言的替代品,它由基于 Apache Calcite的決議器和規劃器提供支持

? Druid SQL將SQL轉換為查詢Broker(查詢的第一個行程)上的原生Druid查詢,然后作為原生Druid查詢傳遞給資料行程,除了在Broker上 轉換SQL) 的(輕微)開銷之外,與原生查詢相比,沒有額外的性能損失,

5.6.1 基本查詢
5.6.1.1 查詢資料總條數

可以在druid的控制臺進行查詢

select count(1) from "taxi_message"

file

5.6.1.2 查詢當前打車人數

我們可以統計出來當前的打車的人數

5.6.2 聚合功能

聚合函式可以出現在任何查詢的SELECT子句中,可以使用類似語法過濾任何聚合器 AGG(expr) FILTER(WHERE whereExpr),過濾的聚合器僅聚合與其過濾器匹配的行,同一SQL查詢中的兩個聚合器可能具有不同的篩選器,

只有COUNT聚合可以接受DISTINCT,

功能 筆記
COUNT(*) 計算行數,
COUNT(DISTINCT expr) 計算expr的不同值,可以是string,numeric或hyperUnique,默認情況下,這是近似值,使用HyperLogLog的變體,要獲得準確的計數,請將“useApproximateCountDistinct”設定為“false”,如果這樣做,expr必須是字串或數字,因為使用hyperUnique列無法進行精確計數,另見APPROX_COUNT_DISTINCT(expr),在精確模式下,每個查詢只允許一個不同的計數,
SUM(expr) 求和數,
MIN(expr) 采用最少的數字,
MAX(expr) 取最大數字,
AVG(expr) 平均數,
APPROX_COUNT_DISTINCT(expr) 計算expr的不同值,可以是常規列或hyperUnique列,無論“useApproximateCountDistinct”的值如何,這始終是近似值,另見COUNT(DISTINCT expr)
APPROX_COUNT_DISTINCT_DS_HLL(expr, [lgK, tgtHllType]) 計算expr的不同值,可以是常規列或HLL草圖列,的lgKtgtHllType引數的HLL草圖檔案中描述,無論“useApproximateCountDistinct”的值如何,這始終是近似值,另見COUNT(DISTINCT expr),該DataSketches擴展必須加載使用此功能,
APPROX_COUNT_DISTINCT_DS_THETA(expr, [size]) 計算expr的不同值,可以是常規列或Theta sketch列,該size引數在Theta sketch檔案中描述,無論“useApproximateCountDistinct”的值如何,這始終是近似值,另見COUNT(DISTINCT expr),該DataSketches擴展必須加載使用此功能,
APPROX_QUANTILE(expr, probability, [resolution]) 計算numeric或approxHistogram exprs的近似分位數,“概率”應該在0和1之間(不包括),“解析度”是用于計算的質心數,解析度越高,結果越精確,但開銷也越高,如果未提供,則默認解析度為50. 必須加載近似直方圖擴展才能使用此功能,
APPROX_QUANTILE_DS(expr, probability, [k]) 計算數值或Quantiles草圖 exprs的近似分位數,“概率”應該在0和1之間(不包括),該k引數在Quantiles草圖檔案中描述,該DataSketches擴展必須加載使用此功能,
APPROX_QUANTILE_FIXED_BUCKETS(expr, probability, numBuckets, lowerLimit, upperLimit, [outlierHandlingMode]) 計算數字或固定桶直方圖 exprs的近似分位數,“概率”應該在0和1之間(不包括),的numBucketslowerLimitupperLimit,和outlierHandlingMode引數在固定桶中描述直方圖檔案,在近似直方圖擴展必須加載使用此功能,
BLOOM_FILTER(expr, numEntries) 根據生成的值計算布隆過濾器,在假定正比率增加之前expr使用numEntries最大數量的不同值,有關其他詳細資訊,請參閱bloom filter擴展檔案
5.6.2.1 查詢資料總條數

可以在druid的控制臺進行查詢

select count(1) from "taxi_message"

file

5.7 客戶端API

我們在這里實作SpringBoot+Mybatis實作SQL查詢ApacheDruid資料

5.7.1 引入Pom依賴
<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.0</version>
        </dependency>


        <dependency>
            <groupId>org.apache.calcite.avatica</groupId>
            <artifactId>avatica</artifactId>
            <version>1.18.0</version>
        </dependency>

        <dependency>
            <groupId>org.apache.calcite.avatica</groupId>
            <artifactId>avatica-server</artifactId>
            <version>1.18.0</version>
        </dependency>
    </dependencies>
5.7.1.1 配置資料源連接

在application.yml中配置資料庫的連接資訊

  • 連接時需注意Druid時區和JVM時區,不設定時區時默認采用JVM時區
  • 檔案參考地址:https://calcite.apache.org/avatica/docs/client_reference.html
spring:
  datasource:
    # 連接池資訊
    url: jdbc:avatica:remote:url=http://192.168.64.177:8082/druid/v2/sql/avatica/
    # 驅動資訊
    driver-class-name: org.apache.calcite.avatica.remote.Driver
5.7.2 撰寫代碼
5.7.2.1 撰寫物體類
public class TaxiMessage {

    private String __time;
    private Integer age;
    private Integer createDate;
    private String local;
    private String sex;
    private Integer status;
    private String statusText;
    private String username;
	//setter getter 忽略

    @Override
    public String toString() {
        return "TaxiMessage{" +
                "__time='" + __time + '\'' +
                ", age=" + age +
                ", createDate=" + createDate +
                ", local='" + local + '\'' +
                ", sex='" + sex + '\'' +
                ", status=" + status +
                ", statusText='" + statusText + '\'' +
                ", username='" + username + '\'' +
                '}';
    }
}

5.7.2.2 撰寫mapper

所有欄位名、表名必須使用如下方式標識 \"表名\"

@Mapper
public interface TaxiMessageMapper {
    @Select("SELECT * FROM \"taxi_message\" where username=#{username}")
    public TaxiMessage findByUserName(String username);
}
5.7.2.3 撰寫Service
@Service
public class TaxiMessageService {
    @Autowired
    private TaxiMessageMapper taxiMessageMapper;

    public TaxiMessage findByUserName(String username) {
        return taxiMessageMapper.findByUserName(username);
    }
}
5.7.2.4 撰寫啟動類
@SpringBootApplication
@MapperScan(basePackages = "com.heima.druid.mapper")
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class);
    }
}
5.7.2.5 撰寫測驗類
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class DruidTest {
    @Autowired
    private TaxiMessageService taxiMessageService;

    @Test
    public void test() {
        TaxiMessage taxiMessage = taxiMessageService.findByUserName("eFQfLXmXD4");
        System.out.println(taxiMessage);
        Assert.assertNotNull(taxiMessage);
    }
}
5.7.2.6 運行測驗

file

本文由傳智教育博學谷教研團隊發布,

如果本文對您有幫助,歡迎關注點贊;如果您有任何建議也可留言評論私信,您的支持是我堅持創作的動力,

轉載請注明出處!

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/505929.html

標籤:Java

上一篇:Java 將Excel轉為UOS

下一篇:etcd v3版本生產級集群搭建以及實作一鍵啟動腳本

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more