الانتقال إلى المحتوى الرئيسي
مكتبة Java client للتواصل مع خادم DB عبر بروتوكولاته. يدعم التطبيق الحالي واجهة HTTP interface فحسب. توفر المكتبة واجهة برمجة تطبيقات خاصة بها لإرسال الطلبات إلى الخادم، كما توفر أدوات للعمل مع تنسيقات البيانات الثنائية المختلفة (RowBinary* & Native*).

الإعداد



التهيئة

يتم تهيئة كائن Client عبر com.clickhouse.client.api.Client.Builder#build(). يمتلك كل client سياقه الخاص، ولا تُشارَك أي كائنات بين الـ clients. يوفر Builder طرق ضبط تُيسّر عملية الإعداد.مثال:
showLineNumbers
Client هو AutoCloseable ويجب إغلاقه عند انتهاء الحاجة إليه.

المصادقة

تُهيَّأ المصادقة لكل عميل في مرحلة التهيئة. وتتوفر ثلاث طرق مصادقة مدعومة: بكلمة المرور، أو برمز الوصول، أو بشهادة SSL للعميل.تتطلب المصادقة بكلمة مرور تعيين اسم المستخدم وكلمة المرور من خلال استدعاء setUsername(String) وsetPassword(String):
showLineNumbers
تتطلب المصادقة عبر رمز الوصول ضبط رمز الوصول من خلال استدعاء setAccessToken(String):
showLineNumbers
تتطلب المصادقة عبر شهادة SSL للعميل تحديد اسم المستخدم، وتفعيل مصادقة SSL، وضبط شهادة العميل ومفتاحه من خلال استدعاء setUsername(String) وuseSSLAuthentication(boolean) وsetClientCertificate(String) وsetClientKey(String) على التوالي:
showLineNumbers
قد يصعب استكشاف أخطاء مصادقة SSL وإصلاحها في بيئة الإنتاج لأن كثيرًا من الأخطاء الصادرة عن مكتبات SSL لا توفّر معلومات كافية. على سبيل المثال، إذا لم تتطابق شهادة العميل مع المفتاح، فسينهي الخادم الاتصال فورًا (وفي حالة HTTP، تكون هذه مرحلة بدء الاتصال حيث لا تُرسل أي طلبات HTTP، وبالتالي لا يُرسل أي رد).استخدم أدوات مثل openssl للتحقق من الشهادات والمفاتيح:
  • التحقق من سلامة المفتاح: openssl rsa -in [key-file.key] -check -noout
  • التحقق من أن شهادة العميل تتضمن CN مطابقًا لمستخدم:
    • استخراج CN من شهادة المستخدم - openssl x509 -noout -subject -in [user.cert]
    • التحقق من ضبط القيمة نفسها في قاعدة البيانات select name, auth_type, auth_params from system.users where auth_type = 'ssl_certificate' (سيُظهر الاستعلام auth_params بشيء مثل {"common_names":["some_user"]})

التهيئة

يتم تعريف جميع الإعدادات عبر طرق النسخة (المعروفة أيضاً بطرق الإعداد)، مما يجعل نطاق وسياق كل قيمة واضحاً. تُعرَّف معاملات الإعداد الرئيسية ضمن نطاق واحد (العميل أو العملية) ولا تتجاوز بعضها البعض.يتم تحديد الإعداد أثناء إنشاء الـ client. راجع com.clickhouse.client.api.Client.Builder.

إعداد العميل


تعريف العميل

يوجد حقلان في سجل الاستعلام يُحدِّدان التطبيق الذي أنشأ الطلب: client_name وhttp_user_agent. يستخدم بروتوكول native TCP الحقلَ client_name لتعريف التطبيق، بينما يستخدم بروتوكول HTTP الحقلَ http_user_agent لهذا الغرض. يوفر الـ Client builder الأسلوبَ setClientName لضبط القيم الصحيحة لكلا البروتوكولين. يُضبط الحقل http_user_agent وفق التنسيق الشائع لترويسة User-Agent: application-name[/version] [(operating-system; architecture; ...)]. تتكرر هذه المجموعة من القيم لكل طبقة: التطبيق، ومكتبة الـ client، ومكتبة الـ HTTP client. ويأتي ما يُحدَّد عبر الأسلوب setClientName في مقدمة القائمة.على سبيل المثال:
showLineNumbers
سيؤدي ذلك إلى القيمة التالية لـ http_user_agent:
يمكن للتطبيق تعيين رأس HTTP الخاص به User-Agent للتعريف عن نفسه. غير أن الجزء clickhouse-java-v2/0.9.6-SNAPSHOT سيُلحَق بنهاية الرأس.

تحديد العملية

يتضمن سجل الاستعلام حقلين إضافيين هما query_id وlog_comment، يمكن استخدامهما لتحديد عملية معينة وإضافة معلومات إضافية إلى سجل الاستعلام.query_id هو معرّف فريد للعملية. يمكن تعيينه من قِبل التطبيق عن طريق استدعاء الدالة setQueryId في الفئة QuerySettings.
showLineNumbers
log_comment هو تعليق يمكن إضافته إلى سجل الاستعلام. يمكن للتطبيق ضبطه عبر استدعاء الدالة logComment من الفئة QuerySettings.
showLineNumbers

إعدادات الخادم

يمكن تعيين إعدادات جانب الخادم على مستوى العميل مرةً واحدة أثناء الإنشاء (راجع الدالة serverSetting في Builder)، وعلى مستوى العملية (راجع serverSetting في class إعدادات العملية).
showLineNumbers
⚠️ عند تعيين الخيارات عبر طريقة setOption (سواء في Client.Builder أو في فئة إعدادات العملية)، يجب أن يُسبَق اسم إعداد الخادم بالبادئة clickhouse_setting_. قد يكون com.clickhouse.client.api.ClientConfigProperties#serverSetting() مفيدًا في هذه الحالة.

HTTP Header مخصص

يمكن تعيين HTTP headers مخصصة لجميع العمليات (على مستوى العميل) أو لعملية واحدة فقط (على مستوى العملية).
showLineNumbers
عند تعيين الخيارات عبر الـ method الخاصة بـ setOption (سواء في Client.Builder أو class إعدادات العملية)، يجب أن يبدأ اسم الـ header المخصص بالبادئة http_header_. وقد تكون الـ method الخاصة بـ com.clickhouse.client.api.ClientConfigProperties#httpHeader() مفيدةً في هذه الحالة.

التعريفات الشائعة

ClickHouseFormat

تعداد الصيغ المدعومة. يتضمن جميع الصيغ التي يدعمها ClickHouse.
  • raw - يجب على المستخدم تحويل ترميز البيانات الخام
  • full - يمكن للعميل تحويل ترميز البيانات بنفسه ويقبل تدفق بيانات خام
  • - - هذه العملية غير مدعومة في ClickHouse لهذا التنسيق
يدعم إصدار client هذا:

واجهة برمجة تطبيقات الإدراج

insert(String tableName, InputStream data, ClickHouseFormat format)

يقبل البيانات على شكل InputStream من البايتات بالتنسيق المحدد. ومن المتوقع أن تكون data مُرمَّزةً وفق format.التوقيعات
المعاملاتtableName - اسم الجدول الهدف.data - تدفق إدخال لبيانات مُرمَّزة.format - التنسيق الذي تُرمَّز به البيانات.settings - إعدادات الطلب.القيمة المُعادةمستقبل من نوع InsertResponse - نتيجة العملية ومعلومات إضافية كمقاييس جانب الخادم.أمثلة
showLineNumbers

insert(String tableName, List<?> data, InsertSettings settings)

يُرسل طلب كتابة إلى قاعدة البيانات. يتم تحويل قائمة الكائنات إلى تنسيق فعّال ثم إرسالها إلى الخادم. يجب تسجيل الفئة الخاصة بعناصر القائمة مسبقًا باستخدام الطريقة register(Class, TableSchema).التوقيعات
المعاملاتtableName - اسم الجدول الهدف.data - كائنات DTO (Data Transfer Object) الخاصة بالمجموعة.settings - إعدادات الطلب.القيمة المُعادةمستقبل من النوع InsertResponse - يمثّل نتيجة العملية ومعلومات إضافية كمقاييس جانب الخادم.أمثلة
showLineNumbers

InsertSettings

خيارات الإعداد لعمليات الإدراج.طرق الإعداد

استجابة الإدراج

كائن Response يحتوي على نتيجة عملية الإدراج. لا يكون متاحاً إلا إذا تلقّى الـ Client استجابةً من الـ server.
يجب إغلاق هذا الكائن في أقرب وقت ممكن لتحرير الاتصال، إذ لا يمكن إعادة استخدامه حتى تُقرأ جميع بيانات الاستجابة السابقة بالكامل.

واجهة برمجة تطبيقات الاستعلام

query(String sqlQuery)

يُرسل sqlQuery كما هو. يُحدَّد تنسيق الاستجابة من خلال إعدادات الاستعلام. سيحتفظ QueryResponse بمرجع إلى تدفق الاستجابة الذي يجب أن يستهلكه قارئ يدعم التنسيق المحدد.التوقيعات
المعاملاتsqlQuery - عبارة SQL واحدة. يُرسَل الاستعلام كما هو إلى الخادم.settings - إعدادات الطلب.القيمة المُعادةمستقبل من النوع QueryResponse - مجموعة بيانات نتائج ومعلومات إضافية كمقاييس جانب الخادم. يجب إغلاق كائن الاستجابة بعد الانتهاء من استهلاك مجموعة البيانات.أمثلة

query(String sqlQuery, Map<String, Object> queryParams, QuerySettings settings)

يُرسل sqlQuery كما هو. كما يُرسل معاملات الاستعلام لكي يتمكن الخادم من تجميع تعبير SQL.التوقيعات
المعاملاتsqlQuery - تعبير SQL مع العناصر النائبة {}.queryParams - مجموعة من المتغيرات لإكمال تعبير SQL على الخادم.settings - إعدادات الطلب.القيمة المُعادةمستقبل من النوع QueryResponse - مجموعة بيانات نتائج ومعلومات إضافية كمقاييس جانب الخادم. يجب إغلاق كائن الاستجابة بعد الانتهاء من استهلاك مجموعة البيانات.أمثلة
showLineNumbers

queryAll(String sqlQuery)

يُرسل استعلامات للبيانات بتنسيق RowBinaryWithNamesAndTypes. يُعيد النتيجة على شكل مجموعة. أداء القراءة مماثل لأداء القارئ، إلا أنه يتطلب ذاكرة أكبر لاستيعاب مجموعة البيانات بالكامل.التوقيعات
المعاملاتsqlQuery - تعبير SQL للاستعلام عن البيانات من الخادم.القيمة المُعادةمجموعة البيانات الكاملة ممثَّلةً بقائمة من كائنات GenericRecord التي توفر وصولاً على شكل صفوف إلى بيانات النتائج.أمثلة
showLineNumbers

QuerySettings

خيارات التهيئة لعمليات الاستعلام.طرق الإعداد

QueryResponse

كائن الاستجابة الذي يحتوي على نتيجة تنفيذ الاستعلام. لا يكون متاحاً إلا إذا تلقّى الـ client استجابةً من الـ server.
يجب إغلاق هذا الكائن في أقرب وقت ممكن لتحرير الاتصال، لأن هذا الاتصال لا يمكن إعادة استخدامه حتى تتم قراءة جميع بيانات الاستجابة السابقة بالكامل.

أمثلة

واجهة برمجة التطبيقات المشتركة

getTableSchema(String table)

يجلب مخطط الجدول الخاص بـ table.التوقيعات
المعاملاتtable - اسم الجدول الذي سيتم جلب بيانات المخطط الخاصة به.database - قاعدة البيانات التي يُعرَّف فيها الجدول الهدف.القيمة المُعادةيُعيد كائن TableSchema يحتوي على قائمة بأعمدة الجدول.

getTableSchemaFromQuery(String sql)

يسترجع المخطط من عبارة SQL.التوقيعات
المعاملاتsql - عبارة SQL من نوع “SELECT” التي سيتم إرجاع مخططها.القيمة المُعادةيُعيد كائن TableSchema يحتوي على أعمدة تتطابق مع تعبير sql.

TableSchema

register(Class<?> clazz, TableSchema schema)

يُجمِّع طبقة التسلسل وإلغاء التسلسل لـ Java Class لاستخدامها في كتابة/قراءة البيانات باستخدام schema. ستُنشئ هذه الدالة مُسلسِلاً ومُفككَ تسلسل لزوج getter/setter والعمود المقابل. يُحدَّد تطابق العمود باستخراج اسمه من اسم الدالة. على سبيل المثال، سيرتبط getFirstName بالعمود first_name أو firstname.التوقيعات
المعاملاتclazz - فئة تمثّل POJO المستخدم لقراءة البيانات وكتابتها.schema - مخطط البيانات المستخدم للمطابقة مع خصائص POJO.أمثلة
showLineNumbers

أمثلة الاستخدام

تجد شيفرة الأمثلة الكاملة في المستودع داخل مجلد ‘example`:
  • client-v2 - المجموعة الأساسية من الأمثلة.
  • demo-service - مثال على كيفية استخدام العميل في تطبيق Spring Boot.
  • demo-kotlin-service - مثال على كيفية استخدام العميل في تطبيق Ktor ‏(Kotlin).

قراءة البيانات

ثمة طريقتان شائعتان لقراءة البيانات:
  • الطريقة query() التي تُرجع الكائن منخفض المستوى QueryResponse، والذي يحتوي على InputStream للبيانات. تُستخدم عادةً مع ClickHouseBinaryFormatReader لإجراء عمليات قراءة متدفقة، لكنها يمكن استخدامها أيضًا مع أي تنفيذ مخصص آخر للقارئ. كما يوفّر QueryResponse إمكانية الوصول إلى البيانات الوصفية لمجموعة النتائج والمقاييس.
  • الطريقة queryAll() مع استخدام GenericRecord للوصول بسهولة إلى الصفوف. في هذه الحالة، تُحمَّل مجموعة النتائج بالكامل إلى الذاكرة.
  • الطريقة queryRecords() التي تُرجع com.clickhouse.client.api.query.Records - وهو مكرّر لكائنات GenericRecord. تستخدم هذه الطريقة نهجًا متدفقًا (من دون تحميل أي بيانات إلى الذاكرة) وتستفيد من GenericRecord للوصول إلى البيانات.
ملاحظة: يستلزم أسلوب البث قراءةً سريعة، وإلا قد يتسبب في انتهاء مهلة الكتابة على الخادم، إذ تُقرأ البيانات مباشرةً من تدفق الشبكة.

قراءة المصفوفات

طرق ClickHouseBinaryFormatReader
  • getList(...) - يقرأ أي Array(...) باعتباره List<T>. خيار افتراضي جيد لعمليات القراءة المرنة المقيّدة بالنوع. يدعم المصفوفات المتداخلة.
  • getByteArray(...), getShortArray(...), getIntArray(...), getLongArray(...), getFloatArray(...), getDoubleArray(...), getBooleanArray(...) - الأفضل للمصفوفات أحادية البعد ذات القيم المتوافقة مع الأنواع الأولية.
  • getStringArray(...) - مخصّص لـ Array(String) (وكذلك لقيم enum الممثلة كأسماء).
  • getObjectArray(...) - خيار عام لأي نوع عنصر في Array(...)، بما في ذلك المصفوفات المتداخلة. استخدمه لقراءة المصفوفات التي تحتوي على قيم يمكن أن تكون NULL والمصفوفات المتداخلة.
تتوفر التحميلات الزائدة المستندة إلى الفهرس والمستندة إلى الاسم لجميع الطرق. يبدأ الفهرس من 1. تتيح الطرق المستندة إلى الفهرس الوصول المباشر إلى العمود. تتطلب الطرق المستندة إلى الاسم البحث عن الفهرس في كل مرة.
طرق GenericRecord
  • getList(...) - يقرأ أي Array(...) باعتباره List<T>. خيار افتراضي جيد لعمليات القراءة المرنة المقيّدة بالأنواع. يدعم المصفوفات المتداخلة.
  • getByteArray(...), getShortArray(...), getIntArray(...), getLongArray(...), getFloatArray(...), getDoubleArray(...), getBooleanArray(...) - الأفضل للمصفوفات أحادية البعد ذات القيم المتوافقة مع الأنواع البدائية.
  • getStringArray(...) - لـ Array(String) (وقيم enum الممثلة على شكل أسماء).
  • getObjectArray(...) - خيار عام لأي نوع عنصر في Array(...)، بما في ذلك المصفوفات المتداخلة. استخدمه لقراءة المصفوفات التي تحتوي على قيم قابلة لأن تكون NULL والمصفوفات المتداخلة.
تتوفر التحميلات الزائدة المستندة إلى الفهرس والمستندة إلى الاسم لجميع الطرق. يبدأ الفهرس من 1. تُتيح الطرق المستندة إلى الفهرس وصولاً مباشراً إلى العمود. أما الطرق المستندة إلى الاسم فتستلزم البحث في الفهرس في كل مرة.

دليل الترحيل

كان العميل القديم (V1) يستخدم com.clickhouse.client.ClickHouseClient#builder كنقطة انطلاق. أما العميل الجديد (V2) فيعتمد نمطًا مشابهًا عبر com.clickhouse.client.api.Client.Builder. وأبرز الفروقات هي:
  • لا يُستخدم أي service loader لجلب التنفيذ الفعلي. وتمثّل com.clickhouse.client.api.Client فئة واجهة لمختلف أنواع التنفيذ مستقبلًا.
  • عدد مصادر التهيئة أقل: يُمرَّر أحدها إلى الـ builder، ويكون الآخر ضمن إعدادات العملية (QuerySettings، InsertSettings). كان الإصدار السابق يتضمّن تهيئة لكل عقدة، وكان يقرأ متغيرات البيئة في بعض الحالات.

تطابق معاملات الإعداد

توجد 3 فئات enum مرتبطة بالتهيئة في V1:
  • com.clickhouse.client.config.ClickHouseDefaults - معلمات التهيئة التي يُفترض تعيينها في معظم حالات الاستخدام، مثل USER وPASSWORD.
  • com.clickhouse.client.config.ClickHouseClientOption - معلمات تهيئة خاصة بالعميل، مثل HEALTH_CHECK_INTERVAL.
  • com.clickhouse.client.http.config.ClickHouseHttpOption - معلمات تهيئة خاصة بواجهة HTTP، مثل RECEIVE_QUERY_PROGRESS.
صُمِّمت لتجميع المعاملات وتوفير فصل واضح بينها. غير أن ذلك أفضى في بعض الحالات إلى التباس (هل ثمة فرق بين com.clickhouse.client.config.ClickHouseDefaults#ASYNC وcom.clickhouse.client.config.ClickHouseClientOption#ASYNC؟). يستخدم client الجديد V2 الفئة com.clickhouse.client.api.Client.Builder بوصفها مرجعًا موحدًا لجميع خيارات تهيئة الـ client الممكنة. كما تتوفر الفئة com.clickhouse.client.api.ClientConfigProperties التي تسرد جميع أسماء معاملات التهيئة.يوضح الجدول أدناه الخيارات القديمة المدعومة في الـ client الجديد ومعانيها الجديدة.المفتاح: ✔ = مدعوم، ✗ = مُسقَط

الفروق العامة

  • يستخدم Client V2 عددًا أقل من الفئات الخاصة لزيادة قابلية النقل. على سبيل المثال، يعمل V2 مع أي تنفيذ لـ java.io.InputStream من أجل كتابة البيانات إلى الخادم.
  • يكون إعداد async في Client V2 مضبوطًا على off افتراضيًا. وهذا يعني عدم وجود مؤشرات ترابط إضافية وتحكمًا أكبر من التطبيق في العميل. ينبغي أن يكون هذا الإعداد off في معظم حالات الاستخدام. سيؤدي تمكين async إلى إنشاء مؤشر ترابط منفصل لكل طلب. ولا يكون ذلك منطقيًا إلا عند استخدام منفّذ يتحكم فيه التطبيق (انظر com.clickhouse.client.api.Client.Builder#setSharedOperationExecutor)

كتابة البيانات

  • استخدم أي تنفيذ لـ java.io.InputStream. الإصدار V1 com.clickhouse.data.ClickHouseInputStream مدعوم، لكنه غير مستحسن.
  • بمجرد اكتشاف نهاية مجرى الإدخال، ستتم معالجتها وفقًا لذلك. في السابق، كان يجب إغلاق مجرى الإخراج الخاص بالطلب.
V1 إدراج بيانات بتنسيق TSV.
إدراج بيانات بتنسيق TSV - الإصدار V2.
  • توجد طريقة واحدة فقط لاستدعائها. لا حاجة إلى إنشاء كائن طلب إضافي.
  • يُغلَق تدفّق جسم الطلب تلقائيًا عند نسخ جميع البيانات.
  • تتوفر واجهة برمجة تطبيقات جديدة منخفضة المستوى com.clickhouse.client.api.Client#insert(java.lang.String, java.util.List<java.lang.String>, com.clickhouse.client.api.DataStreamWriter, com.clickhouse.data.ClickHouseFormat, com.clickhouse.client.api.insert.InsertSettings). صُمِّم com.clickhouse.client.api.DataStreamWriter لتطبيق منطق مخصص لكتابة البيانات. على سبيل المثال، لقراءة البيانات من قائمة انتظار.

قراءة البيانات

  • تُقرأ البيانات بتنسيق RowBinaryWithNamesAndTypes افتراضيًا. وحاليًا لا يُدعَم عند الحاجة إلى ربط البيانات سوى هذا التنسيق.
  • يمكن قراءة البيانات كمجموعة من السجلات باستخدام الأسلوب List<GenericRecord> com.clickhouse.client.api.Client#queryAll(java.lang.String). يقرأ هذا الأسلوب البيانات إلى الذاكرة ثم يحرّر الاتصال. ولا حاجة إلى أي معالجة إضافية. يتيح GenericRecord الوصول إلى البيانات، ويجري بعض التحويلات.
آخر تعديل في ٢٥ يونيو ٢٠٢٦