XOOPS ตัวสร้างแบบสอบถาม
XOOPS ตัวสร้างแบบสอบถามมีอินเทอร์เฟซที่ทันสมัยและคล่องแคล่วสำหรับการสร้างแบบสอบถาม SQL ช่วยป้องกันการฉีด SQL ปรับปรุงความสามารถในการอ่าน และจัดเตรียมฐานข้อมูลที่เป็นนามธรรมสำหรับระบบฐานข้อมูลหลายระบบ
สถาปัตยกรรมตัวสร้างแบบสอบถาม
หัวข้อที่มีชื่อว่า “สถาปัตยกรรมตัวสร้างแบบสอบถาม”mermaidgraph TD A[QueryBuilder] -->|builds| B[SELECT Queries] A -->|builds| C[INSERT Queries] A -->|builds| D[UPDATE Queries] A -->|builds| E[DELETE Queries]
F[Table] -->|chains| G[select] F -->|chains| H[where] F -->|chains| I[orderBy] F -->|chains| J[limit]
G -->|chains| K[join] G -->|chains| H H -->|chains| I I -->|chains| J
L[Execute Methods] -->|returns| M[Results] L -->|returns| N[Count] L -->|returns| O[First/Last]คลาส QueryBuilder
หัวข้อที่มีชื่อว่า “คลาส QueryBuilder”คลาสตัวสร้างแบบสอบถามหลักพร้อมอินเทอร์เฟซที่คล่องแคล่ว
ภาพรวมชั้นเรียน
หัวข้อที่มีชื่อว่า “ภาพรวมชั้นเรียน”namespace Xoops\Database;
class QueryBuilder{ protected string $table = ''; protected string $type = 'SELECT'; protected array $selects = []; protected array $joins = []; protected array $wheres = []; protected array $orders = []; protected int $limit = 0; protected int $offset = 0; protected array $bindings = [];}วิธีการคงที่
หัวข้อที่มีชื่อว่า “วิธีการคงที่”####โต๊ะ
สร้างตัวสร้างแบบสอบถามใหม่สำหรับตาราง
public static function table(string $table): QueryBuilderพารามิเตอร์:
| พารามิเตอร์ | พิมพ์ | คำอธิบาย |
|---|---|---|
$table | สตริง | ชื่อตาราง (มีหรือไม่มีคำนำหน้า) |
ผลตอบแทน: QueryBuilder - อินสแตนซ์ตัวสร้างแบบสอบถาม
ตัวอย่าง:
$query = QueryBuilder::table('users');$query = QueryBuilder::table('xoops_users'); // With prefixSELECT แบบสอบถาม
หัวข้อที่มีชื่อว่า “SELECT แบบสอบถาม”ระบุคอลัมน์ที่จะเลือก
public function select(...$columns): selfพารามิเตอร์:
| พารามิเตอร์ | พิมพ์ | คำอธิบาย |
|---|---|---|
...$columns | อาร์เรย์ | ชื่อคอลัมน์หรือนิพจน์ |
ผลตอบแทน: self - สำหรับการเชื่อมโยงเมธอด
ตัวอย่าง:
// Simple selectQueryBuilder::table('users') ->select('id', 'username', 'email') ->get();
// Select with aliasesQueryBuilder::table('users') ->select('id as user_id', 'username as name') ->get();
// Select all columnsQueryBuilder::table('users') ->select('*') ->get();
// Select with expressionsQueryBuilder::table('orders') ->select('id', 'COUNT(*) as total_items') ->groupBy('id') ->get();###ที่ไหน
เพิ่มเงื่อนไข WHERE
public function where(string $column, string $operator = '=', mixed $value = null): selfพารามิเตอร์:
| พารามิเตอร์ | พิมพ์ | คำอธิบาย |
|---|---|---|
$column | สตริง | ชื่อคอลัมน์ |
$operator | สตริง | ตัวดำเนินการเปรียบเทียบ |
$value | ผสม | ค่าที่จะเปรียบเทียบ |
ผลตอบแทน: self - สำหรับการเชื่อมโยงเมธอด
ผู้ประกอบการ:
| ตัวดำเนินการ | คำอธิบาย | ตัวอย่าง |
|---|---|---|
= | เท่ากับ | ->where('status', '=', 'active') |
!= หรือ <> | ไม่เท่ากับ | ->where('status', '!=', 'deleted') |
> | มากกว่า | ->where('price', '>', 100) |
< | น้อยกว่า | ->where('price', '<', 100) |
>= | มากกว่าหรือเท่ากับ | ->where('age', '>=', 18) |
<= | น้อยกว่าหรือเท่ากับ | ->where('age', '<=', 65) |
LIKE | จับคู่รูปแบบ | ->where('name', 'LIKE', '%john%') |
IN | ในรายการ | ->where('status', 'IN', ['active', 'pending']) |
NOT IN | ไม่อยู่ในรายการ | ->where('id', 'NOT IN', [1, 2, 3]) |
BETWEEN | พิสัย | ->where('age', 'BETWEEN', [18, 65]) |
IS NULL | เป็นโมฆะ | ->where('deleted_at', 'IS NULL') |
IS NOT NULL | ไม่เป็นโมฆะ | ->where('deleted_at', 'IS NOT NULL') |
ตัวอย่าง:
// Single conditionQueryBuilder::table('users') ->select('*') ->where('status', '=', 'active') ->get();
// Multiple conditions (AND)QueryBuilder::table('users') ->select('*') ->where('status', '=', 'active') ->where('age', '>=', 18) ->get();
// IN operatorQueryBuilder::table('products') ->select('*') ->where('category_id', 'IN', [1, 2, 3]) ->get();
// LIKE operatorQueryBuilder::table('users') ->select('*') ->where('email', 'LIKE', '%@example.com') ->get();
// NULL checkQueryBuilder::table('users') ->select('*') ->where('deleted_at', 'IS NULL') ->get();หรือที่ไหน
หัวข้อที่มีชื่อว่า “หรือที่ไหน”เพิ่มเงื่อนไข OR
public function orWhere(string $column, string $operator = '=', mixed $value = null): selfตัวอย่าง:
QueryBuilder::table('users') ->select('*') ->where('status', '=', 'active') ->orWhere('premium', '=', 1) ->get(); // SELECT * FROM users WHERE status = 'active' OR premium = 1WhereIn / WhereNotIn
หัวข้อที่มีชื่อว่า “WhereIn / WhereNotIn”วิธีการที่สะดวกสำหรับ IN/¤NOT IN
public function whereIn(string $column, array $values): selfpublic function whereNotIn(string $column, array $values): selfตัวอย่าง:
QueryBuilder::table('posts') ->select('*') ->whereIn('status', ['published', 'scheduled']) ->get();
QueryBuilder::table('comments') ->select('*') ->whereNotIn('spam_score', [8, 9, 10]) ->get();โดยที่ Null / โดยที่ NotNull
หัวข้อที่มีชื่อว่า “โดยที่ Null / โดยที่ NotNull”วิธีการที่สะดวกสบายสำหรับการตรวจสอบ NULL
public function whereNull(string $column): selfpublic function whereNotNull(string $column): selfตัวอย่าง:
QueryBuilder::table('users') ->select('*') ->whereNotNull('verified_at') ->get();###อยู่ที่ไหนระหว่าง
ตรวจสอบว่าค่าอยู่ระหว่างสองค่าหรือไม่
public function whereBetween(string $column, array $values): selfตัวอย่าง:
QueryBuilder::table('products') ->select('*') ->whereBetween('price', [10, 100]) ->get();
QueryBuilder::table('orders') ->select('*') ->whereBetween('created_at', ['2024-01-01', '2024-12-31']) ->get();เข้าร่วม
หัวข้อที่มีชื่อว่า “เข้าร่วม”เพิ่ม INNER JOIN
public function join( string $table, string $first, string $operator = '=', string $second = null): selfตัวอย่าง:
QueryBuilder::table('posts') ->select('posts.*', 'users.username', 'categories.name') ->join('users', 'posts.user_id', '=', 'users.id') ->join('categories', 'posts.category_id', '=', 'categories.id') ->where('posts.published', '=', 1) ->get();ซ้ายเข้าร่วม / ขวาเข้าร่วม
หัวข้อที่มีชื่อว่า “ซ้ายเข้าร่วม / ขวาเข้าร่วม”ประเภทการรวมทางเลือก
public function leftJoin( string $table, string $first, string $operator = '=', string $second = null): self
public function rightJoin( string $table, string $first, string $operator = '=', string $second = null): selfตัวอย่าง:
QueryBuilder::table('users') ->select('users.*', 'COUNT(posts.id) as post_count') ->leftJoin('posts', 'users.id', '=', 'posts.user_id') ->groupBy('users.id') ->get();กลุ่มโดย
หัวข้อที่มีชื่อว่า “กลุ่มโดย”จัดกลุ่มผลลัพธ์ตามคอลัมน์
public function groupBy(...$columns): selfตัวอย่าง:
QueryBuilder::table('orders') ->select('user_id', 'COUNT(*) as order_count', 'SUM(total) as total_spent') ->groupBy('user_id') ->get();
QueryBuilder::table('sales') ->select('department', 'region', 'SUM(amount) as total') ->groupBy('department', 'region') ->get();เพิ่มเงื่อนไข HAVING
public function having(string $column, string $operator = '=', mixed $value = null): selfตัวอย่าง:
QueryBuilder::table('orders') ->select('user_id', 'COUNT(*) as order_count') ->groupBy('user_id') ->having('order_count', '>', 5) ->get();สั่งซื้อโดย
หัวข้อที่มีชื่อว่า “สั่งซื้อโดย”ผลการสั่งซื้อ.
public function orderBy(string $column, string $direction = 'ASC'): selfพารามิเตอร์:
| พารามิเตอร์ | พิมพ์ | คำอธิบาย |
|---|---|---|
$column | สตริง | คอลัมน์เรียงลำดับโดย |
$direction | สตริง | ASC หรือ DESC |
ตัวอย่าง:
// Single orderQueryBuilder::table('users') ->select('*') ->orderBy('created_at', 'DESC') ->get();
// Multiple ordersQueryBuilder::table('posts') ->select('*') ->orderBy('category_id', 'ASC') ->orderBy('created_at', 'DESC') ->get();
// Random orderQueryBuilder::table('quotes') ->select('*') ->orderBy('RAND()') ->get();ขีดจำกัด / ออฟเซ็ต
หัวข้อที่มีชื่อว่า “ขีดจำกัด / ออฟเซ็ต”ขีดจำกัดและการชดเชยผลลัพธ์
public function limit(int $limit): selfpublic function offset(int $offset): selfตัวอย่าง:
// Simple limitQueryBuilder::table('posts') ->select('*') ->limit(10) ->get();
// Pagination$page = 2;$perPage = 20;$offset = ($page - 1) * $perPage;
QueryBuilder::table('posts') ->select('*') ->limit($perPage) ->offset($offset) ->get();วิธีดำเนินการ
หัวข้อที่มีชื่อว่า “วิธีดำเนินการ”ดำเนินการค้นหาและส่งกลับผลลัพธ์ทั้งหมด
public function get(): arrayผลตอบแทน: array - อาร์เรย์ของแถวผลลัพธ์
ตัวอย่าง:
$users = QueryBuilder::table('users') ->select('id', 'username', 'email') ->where('status', '=', 'active') ->orderBy('username') ->get();
foreach ($users as $user) { echo $user['username'] . ' (' . $user['email'] . ')' . "\n";}###ก่อน
ได้ผลลัพธ์แรก
public function first(): ?arrayผลตอบแทน: ?array - แถวแรกหรือ null
ตัวอย่าง:
$user = QueryBuilder::table('users') ->select('*') ->where('id', '=', 123) ->first();
if ($user) { echo 'Found: ' . $user['username'];}###สุดท้าย
รับผลลัพธ์สุดท้าย
public function last(): ?arrayตัวอย่าง:
$latestPost = QueryBuilder::table('posts') ->select('*') ->orderBy('created_at', 'DESC') ->last();รับจำนวนผลลัพธ์
public function count(): intผลตอบแทน: int - จำนวนแถว
ตัวอย่าง:
$activeUsers = QueryBuilder::table('users') ->where('status', '=', 'active') ->count();
echo "Active users: $activeUsers";มีอยู่แล้ว
หัวข้อที่มีชื่อว่า “มีอยู่แล้ว”ตรวจสอบว่าแบบสอบถามส่งกลับผลลัพธ์ใดๆ หรือไม่
public function exists(): boolผลตอบแทน: bool - เป็นจริงหากมีผลลัพธ์อยู่
ตัวอย่าง:
if (QueryBuilder::table('users')->where('email', '=', 'test@example.com')->exists()) { echo 'User already exists';}###รวมครับ
รับค่ารวม
public function aggregate(string $function, string $column): mixedตัวอย่าง:
$maxPrice = QueryBuilder::table('products') ->aggregate('MAX', 'price');
$avgAge = QueryBuilder::table('users') ->aggregate('AVG', 'age');
$totalSales = QueryBuilder::table('orders') ->aggregate('SUM', 'total');INSERT แบบสอบถาม
หัวข้อที่มีชื่อว่า “INSERT แบบสอบถาม”แทรกแถว
public function insert(array $values): boolตัวอย่าง:
QueryBuilder::table('users')->insert([ 'username' => 'john', 'email' => 'john@example.com', 'password' => password_hash('secret', PASSWORD_BCRYPT), 'created_at' => date('Y-m-d H:i:s')]);แทรกมากมาย
หัวข้อที่มีชื่อว่า “แทรกมากมาย”แทรกหลายแถว
public function insertMany(array $rows): boolตัวอย่าง:
QueryBuilder::table('log_entries')->insertMany([ ['action' => 'login', 'user_id' => 1, 'timestamp' => time()], ['action' => 'logout', 'user_id' => 2, 'timestamp' => time()], ['action' => 'update', 'user_id' => 3, 'timestamp' => time()]]);UPDATE แบบสอบถาม
หัวข้อที่มีชื่อว่า “UPDATE แบบสอบถาม”อัพเดตแถว
public function update(array $values): intผลตอบแทน: int - จำนวนแถวที่ได้รับผลกระทบ
ตัวอย่าง:
// Update single userQueryBuilder::table('users') ->where('id', '=', 123) ->update([ 'email' => 'newemail@example.com', 'updated_at' => date('Y-m-d H:i:s') ]);
// Update multiple rowsQueryBuilder::table('posts') ->where('status', '=', 'draft') ->where('created_at', '<', date('Y-m-d', strtotime('-30 days'))) ->update([ 'status' => 'archived' ]);เพิ่มขึ้น/ลดลง
หัวข้อที่มีชื่อว่า “เพิ่มขึ้น/ลดลง”เพิ่มหรือลดคอลัมน์
public function increment(string $column, int $amount = 1): intpublic function decrement(string $column, int $amount = 1): intตัวอย่าง:
// Increment view countQueryBuilder::table('posts') ->where('id', '=', 123) ->increment('views');
// Decrement stockQueryBuilder::table('products') ->where('id', '=', 456) ->decrement('stock', 5);DELETE แบบสอบถาม
หัวข้อที่มีชื่อว่า “DELETE แบบสอบถาม”ลบแถว
public function delete(): intผลตอบแทน: int - จำนวนแถวที่ถูกลบ
ตัวอย่าง:
// Delete single recordQueryBuilder::table('comments') ->where('id', '=', 789) ->delete();
// Delete multiple recordsQueryBuilder::table('log_entries') ->where('created_at', '<', date('Y-m-d', strtotime('-30 days'))) ->delete();ลบแถวทั้งหมดออกจากตาราง
public function truncate(): boolตัวอย่าง:
// Clear all sessionsQueryBuilder::table('sessions')->truncate();คุณสมบัติขั้นสูง
หัวข้อที่มีชื่อว่า “คุณสมบัติขั้นสูง”การแสดงออกแบบดิบ
หัวข้อที่มีชื่อว่า “การแสดงออกแบบดิบ”QueryBuilder::table('products') ->select('id', 'name', QueryBuilder::raw('price * quantity as total')) ->get();คำถามย่อย
หัวข้อที่มีชื่อว่า “คำถามย่อย”$recentPostIds = QueryBuilder::table('posts') ->select('id') ->where('created_at', '>', date('Y-m-d', strtotime('-7 days'))) ->toSql();
$comments = QueryBuilder::table('comments') ->select('*') ->whereIn('post_id', $recentPostIds) ->get();รับ SQL
หัวข้อที่มีชื่อว่า “รับ SQL”public function toSql(): stringตัวอย่าง:
$sql = QueryBuilder::table('users') ->select('id', 'username') ->where('status', '=', 'active') ->toSql();
echo $sql;// SELECT id, username FROM xoops_users WHERE status = ?ตัวอย่างที่สมบูรณ์
หัวข้อที่มีชื่อว่า “ตัวอย่างที่สมบูรณ์”เลือกแบบซับซ้อนพร้อมการรวม
หัวข้อที่มีชื่อว่า “เลือกแบบซับซ้อนพร้อมการรวม”<?php/** * Get posts with author and category info */
$posts = QueryBuilder::table('posts') ->select( 'posts.id', 'posts.title', 'posts.content', 'posts.created_at', 'users.username as author', 'categories.name as category' ) ->join('users', 'posts.user_id', '=', 'users.id') ->join('categories', 'posts.category_id', '=', 'categories.id') ->where('posts.published', '=', 1) ->orderBy('posts.created_at', 'DESC') ->limit(10) ->get();
foreach ($posts as $post) { echo '<article>'; echo '<h2>' . htmlspecialchars($post['title']) . '</h2>'; echo '<p class="meta">By ' . htmlspecialchars($post['author']) . ' in ' . htmlspecialchars($post['category']) . '</p>'; echo '<p>' . htmlspecialchars($post['content']) . '</p>'; echo '</article>';}การแบ่งหน้าด้วย QueryBuilder
หัวข้อที่มีชื่อว่า “การแบ่งหน้าด้วย QueryBuilder”<?php/** * Paginated results */
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;$perPage = 20;$offset = ($page - 1) * $perPage;
// Get total count$total = QueryBuilder::table('articles') ->where('status', '=', 'published') ->count();
// Get page results$articles = QueryBuilder::table('articles') ->select('*') ->where('status', '=', 'published') ->orderBy('created_at', 'DESC') ->limit($perPage) ->offset($offset) ->get();
// Calculate pagination$pages = ceil($total / $perPage);
// Display resultsforeach ($articles as $article) { echo '<div class="article">' . htmlspecialchars($article['title']) . '</div>';}
// Display pagination linksif ($pages > 1) { echo '<nav class="pagination">'; for ($i = 1; $i <= $pages; $i++) { if ($i == $page) { echo '<span class="current">' . $i . '</span>'; } else { echo '<a href="?page=' . $i . '">' . $i . '</a>'; } } echo '</nav>';}การวิเคราะห์ข้อมูลด้วยมวลรวม
หัวข้อที่มีชื่อว่า “การวิเคราะห์ข้อมูลด้วยมวลรวม”<?php/** * Sales analysis */
// Total sales by region$regionSales = QueryBuilder::table('orders') ->select('region', QueryBuilder::raw('SUM(total) as total_sales'), QueryBuilder::raw('COUNT(*) as order_count')) ->groupBy('region') ->orderBy('total_sales', 'DESC') ->get();
foreach ($regionSales as $region) { echo $region['region'] . ': $' . number_format($region['total_sales'], 2) . ' (' . $region['order_count'] . ' orders)' . "\n";}
// Average order value$avgOrderValue = QueryBuilder::table('orders') ->aggregate('AVG', 'total');
echo 'Average order value: $' . number_format($avgOrderValue, 2);แนวทางปฏิบัติที่ดีที่สุด
หัวข้อที่มีชื่อว่า “แนวทางปฏิบัติที่ดีที่สุด”- ใช้การสืบค้นแบบกำหนดพารามิเตอร์ - QueryBuilder จัดการการรวมพารามิเตอร์โดยอัตโนมัติ
- Chain Methods - ใช้ประโยชน์จากอินเทอร์เฟซที่คล่องแคล่วสำหรับโค้ดที่อ่านได้
- ทดสอบ SQL เอาต์พุต - ใช้
toSql()¤ เพื่อยืนยันคำค้นหาที่สร้างขึ้น - ใช้ดัชนี - ตรวจสอบให้แน่ใจว่าคอลัมน์ที่มีการสืบค้นบ่อยได้รับการจัดทำดัชนีแล้ว
- จำกัดผลลัพธ์ - ใช้
limit()สำหรับชุดข้อมูลขนาดใหญ่เสมอ - ใช้ Aggregates - ให้ฐานข้อมูลทำการนับ/สรุปแทน PHP
- Escape Output - หลีกเลี่ยงข้อมูลที่แสดงด้วย
htmlspecialchars()เสมอ - ดัชนีประสิทธิภาพ - ตรวจสอบการสืบค้นที่ช้าและปรับให้เหมาะสมตามนั้น
เอกสารที่เกี่ยวข้อง
หัวข้อที่มีชื่อว่า “เอกสารที่เกี่ยวข้อง”- XoopsDatabase - เลเยอร์ฐานข้อมูลและการเชื่อมต่อ
- เกณฑ์ - ระบบสืบค้นตามเกณฑ์เดิม
- ../Core/XoopsObject - การคงอยู่ของวัตถุข้อมูล
- ../Module/Module-System - การทำงานของฐานข้อมูลโมดูล
ดูเพิ่มเติมที่: ¤XOOPS ฐานข้อมูล API