Kotchasan Framework Documentation

Kotchasan Framework Documentation

DB Class

TH 06 Feb 2026 07:29

DB Class

DB class คือ utility class สำหรับการทำงานฐานข้อมูลง่ายๆ ด้วยเมธอดสั้นๆ โดยใช้ QueryBuilder อยู่ภายใน

สารบัญ

ภาพรวม

DB class ถูกออกแบบให้ใช้งานง่าย เหมาะกับงาน CRUD ที่ไม่ซับซ้อน โดยมีความสามารถ:

  • เมธอดสั้นสำหรับงานพื้นฐาน
  • Transaction แบบเรียบง่าย
  • ยูทิลิตีสำหรับตรวจสอบตาราง
  • จัดการ error ได้เหมาะสม

การใช้งานพื้นฐาน

การสร้าง Instance

use Kotchasan\DB;
use Kotchasan\Database;

// สร้าง instance ใหม่
$db = DB::create();

// สร้าง instance ด้วย Database connection ที่กำหนด
$database = Database::create('custom_connection');
$db = DB::create($database);

// สร้างด้วย constructor
$db = new DB();

การทำงาน CRUD

INSERT - เพิ่มข้อมูล

// เพิ่มข้อมูลแถวเดียว
$userId = $db->insert('users', [
    'username' => 'john_doe',
    'email' => 'john@example.com',
    'password' => password_hash('secret', PASSWORD_DEFAULT),
    'created_at' => date('Y-m-d H:i:s')
]);

echo "User ID: {$userId}";

// เพิ่มข้อมูลโดยไม่ต้องใช้ ID
$result = $db->insert('logs', [
    'level' => 'info',
    'message' => 'User logged in',
    'timestamp' => time()
]);

if ($result) {
    echo "Log entry created successfully";
}

SELECT - ดึงข้อมูล

// ดึงข้อมูลทั้งหมดจากตาราง
$users = $db->select('users');

// ดึงข้อมูลตามเงื่อนไข
$activeUsers = $db->select('users', ['status' => 'active']);

// ดึงข้อมูลแบบมีเงื่อนไขซับซ้อน
$recentUsers = $db->select('users',
    [
        ['status', 'active'],
        ['created_at', '>=', '2024-01-01']
    ],
    ['orderBy' => ['created_at' => 'DESC'], 'limit' => 10]
);

// เลือกเฉพาะบางคอลัมน์
$userEmails = $db->select('users',
    ['status' => 'active'],
    [],
    ['email', 'username']
);

// ดึงข้อมูลแบบแบ่งหน้า
$page = 2;
$perPage = 2;
$users = $db->select('users',
    ['status' => 'active'],
    [
        'orderBy' => 'created_at',
        'limit' => $perPage,
        'offset' => ($page - 1) * $perPage
    ]
);

UPDATE - แก้ไขข้อมูล

use Kotchasan\Database\Sql;

// Update ตาม ID
$affectedRows = $db->update('users',
    ['id' => $userId],
    [
        'last_login' => date('Y-m-d H:i:s'),
        'login_count' => Sql::raw('login_count + 1') // ใช้ raw expression
    ]
);

echo "Updated {$affectedRows} rows";

// Update หลายแถว
$affectedRows = $db->update('posts',
    ['status' => 'draft', 'author_id' => $authorId],
    ['status' => 'published']
);

// Update ด้วยเงื่อนไขซับซ้อน
$affectedRows = $db->update('users',
    [['status', 'inactive'], ['last_login', '<', '2023-01-01']],
    ['status' => 'archived']
);

DELETE - ลบข้อมูล

// ลบตาม ID
$deletedRows = $db->delete('users', ['id' => $userId]);

// ลบตามเงื่อนไข
$deletedRows = $db->delete('logs', ['level' => 'debug']);

// ลบแบบมี LIMIT
$deletedRows = $db->delete('temp_files',
    [['created_at', '<', date('Y-m-d', strtotime('-7 days'))]],
    100 // ลบสูงสุด 100 แถว
);

echo "Deleted {$deletedRows} rows";

การค้นหาข้อมูล

// ดึงแถวแรกที่ตรงเงื่อนไข
$user = $db->first('users', ['email' => 'john@example.com']);

if ($user) {
    echo "Found user: {$user->username}";
} else {
    echo "User not found";
}

// ตรวจสอบว่ามีข้อมูลหรือไม่
$exists = $db->exists('users', ['email' => 'john@example.com']);

if ($exists) {
    echo "Email already exists";
}

// นับจำนวน
$totalUsers = $db->count('users');
$activeUsers = $db->count('users', ['status' => 'active']);

echo "Total users: {$totalUsers}, Active: {$activeUsers}";

// ดึงค่าเดียว (scalar)
$total = $db->value('users', 'COUNT(*) as total', ['status' => 'active'], 0);

// ดึงค่าจากคอลัมน์เดียวเป็น array
$emails = $db->pluck('users', 'email', ['status' => 'active'], [
    'orderBy' => ['email' => 'ASC']
]);

เงื่อนไข Where

// แบบง่าย: [['field', 'value']]
$db->first('users', [['id', 1]]);

// หลายเงื่อนไข (AND)
$db->select('users', [
    ['status', 'active'],
    ['role', 'admin']
]);

// ใช้ operator
$db->select('orders', [
    ['total', '>', 1000],
    ['created_at', '>=', '2024-01-01']
]);

// ใช้ IN
$db->select('users', [['id', [1, 2, 3]]]);

// หากต้องการ OR หรือ nested group ให้ใช้ Database/QueryBuilder โดยตรง

การจัดการ Transaction

Transaction พื้นฐาน

use Kotchasan\DB;
use Kotchasan\Database\Sql;

// เริ่ม transaction
$db->beginTransaction();

try {
    // ทำหลาย operations
    $orderId = $db->insert('orders', [
        'user_id' => $userId,
        'total' => $total,
        'status' => 'pending'
    ]);

    $db->insert('order_items', [
        'order_id' => $orderId,
        'product_id' => $productId,
        'quantity' => $quantity,
        'price' => $price
    ]);

    $db->update('products',
        ['id' => $productId],
        ['stock' => Sql::raw('stock - '.(int) $quantity)]
    );

    // ยืนยัน transaction
    $db->commit();

    echo "Order created successfully";

} catch (Exception $e) {
    // ยกเลิก transaction
    $db->rollback();

    echo "Error creating order: " . $e->getMessage();
    throw $e;
}

การใช้งาน Transaction ขั้นสูง

use Kotchasan\DB;
use Kotchasan\Database\Sql;

class OrderService
{
    private $db;

    public function __construct()
    {
        $this->db = DB::create();
    }

    public function createOrder($userId, $items)
    {
        $this->db->beginTransaction();

        try {
            // สร้าง order
            $orderId = $this->db->insert('orders', [
                'user_id' => $userId,
                'status' => 'pending',
                'created_at' => date('Y-m-d H:i:s')
            ]);

            $total = 0;

            // เพิ่ม order items
            foreach ($items as $item) {
                // ตรวจสอบ stock
                $product = $this->db->first('products', ['id' => $item['product_id']]);

                if (!$product || $product->stock < $item['quantity']) {
                    throw new Exception("Insufficient stock for product {$item['product_id']}");
                }

                // เพิ่ม item
                $this->db->insert('order_items', [
                    'order_id' => $orderId,
                    'product_id' => $item['product_id'],
                    'quantity' => $item['quantity'],
                    'price' => $product->price
                ]);

                // ลด stock
                $this->db->update('products',
                    ['id' => $item['product_id']],
                    ['stock' => Sql::raw('stock - '.(int) $item['quantity'])]
                );

                $total += $product->price * $item['quantity'];
            }

            // อัปเดต total
            $this->db->update('orders',
                ['id' => $orderId],
                ['total' => $total]
            );

            $this->db->commit();

            return $orderId;

        } catch (Exception $e) {
            $this->db->rollback();
            throw $e;
        }
    }
}

ยูทิลิตีเพิ่มเติม

การจัดการตาราง

// ล้างข้อมูลทั้งตาราง (TRUNCATE)
$success = $db->emptyTable('cache');

if ($success) {
    echo "Cache table cleared";
}

// ล้างตารางพร้อม options
$success = $db->emptyTable('logs', [
    'reset_autoincrement' => true
]);

// ปรับปรุงประสิทธิภาพตาราง
$success = $db->optimizeTable('users');

if ($success) {
    echo "Table optimized";
}

ตรวจสอบโครงสร้าง

// ตรวจสอบว่ามี field หรือไม่
$hasEmailField = $db->fieldExists('users', 'email');

if (!$hasEmailField) {
    echo "Email field does not exist";
}

// ดึงชื่อตารางจริงพร้อม prefix
$realTableName = $db->getTableName('users');
echo "Real table name: {$realTableName}";

// ตรวจสอบการเชื่อมต่อฐานข้อมูล (ใช้ connection ปัจจุบัน)
$dbExists = $db->databaseExists('myapp_db');

if ($dbExists) {
    echo "Database connection is available";
}

ตัวช่วยตัวนับ

// เพิ่มค่า column ตัวเลข
$db->increment('users', ['id' => $userId], 'login_count');

// ลดค่า column ตัวเลข
$db->decrement('products', ['id' => $productId], 'stock', 2);

การตรวจสอบการทำงาน

// Query ล่าสุดที่รัน
$lastQuery = $db->lastQuery();

// ข้อความ error ล่าสุด
$lastError = $db->lastError();

การใช้ Raw SQL

// รัน raw SQL
$result = $db->raw("SELECT COUNT(*) as total FROM users WHERE created_at > ?", [
    '2024-01-01'
]);

if ($result) {
    $row = $result->fetch();
    echo "Total users: {$row['total']}";
}

// SQL ที่ซับซ้อน
$result = $db->raw("
    SELECT
        u.username,
        COUNT(p.id) as post_count,
        MAX(p.created_at) as last_post
    FROM users u
    LEFT JOIN posts p ON u.id = p.author_id
    WHERE u.status = ?
    GROUP BY u.id
    HAVING post_count > ?
    ORDER BY post_count DESC
", ['active', 5]);

if ($result) {
    $users = $result->fetchAll();
    foreach ($users as $user) {
        echo "{$user['username']}: {$user['post_count']} posts\n";
    }
}

เมธอดทั้งหมด

Static Methods

Method Description Parameters
create($database = null) สร้าง DB instance Database instance (optional)

Instance Methods

Method Description Parameters Return Value
insert($table, $data) เพิ่มข้อมูลลงตาราง table, data array int|null (ID)
update($table, $where, $data) แก้ไขข้อมูลในตาราง table, where, data int (affected rows)
delete($table, $where, $limit, $operator) ลบข้อมูลจากตาราง table, where, limit, operator int (affected rows)
select($table, $where, $options, $columns) ดึงข้อมูลจากตาราง table, where, options, columns array
first($table, $where, $columns, $cache, $cacheTtl) ดึงแถวแรก table, where, columns, cache, cacheTtl object|null
exists($table, $where, $cache, $cacheTtl) ตรวจสอบว่ามีข้อมูลหรือไม่ table, where, cache, cacheTtl bool
count($table, $where, $cache, $cacheTtl) นับจำนวนข้อมูล table, where, cache, cacheTtl int
value($table, $column, $where, $default, $cache, $cacheTtl) ดึงค่าเดียว table, column, where, default, cache, cacheTtl mixed
pluck($table, $column, $where, $options) ดึงค่าจากคอลัมน์เดียวเป็น array table, column, where, options array
nextId($table, $where, $column, $cache, $cacheTtl) หา ID ถัดไป table, where, column, cache, cacheTtl int
increment($table, $where, $column, $amount) เพิ่มค่า column ตัวเลข table, where, column, amount int
decrement($table, $where, $column, $amount) ลดค่า column ตัวเลข table, where, column, amount int
emptyTable($table, $options) ล้างข้อมูลในตาราง table, options bool
optimizeTable($table) ปรับปรุงประสิทธิภาพตาราง table name bool
fieldExists($table, $field) ตรวจสอบว่ามี field หรือไม่ table, field name bool
getTableName($table) ดึงชื่อตารางจริง logical table name string
getPrefix() ดึง table prefix - string
databaseExists($databaseName) ตรวจสอบการเชื่อมต่อฐานข้อมูล database name bool
raw($sql, $bindings) รัน raw SQL SQL string, bindings ResultInterface|null
beginTransaction() เริ่ม transaction - bool
commit() ยืนยัน transaction - bool
rollback() ยกเลิก transaction - bool
lastQuery() ดึง query ล่าสุด - string|null
lastError() ดึง error ล่าสุด - string|null
getDatabase() ดึง Database instance - Database

ตัวอย่างการใช้งาน

ระบบผู้ใช้งานแบบง่าย

use Kotchasan\\DB;

class SimpleUserManager
{
    private $db;

    public function __construct()
    {
        $this->db = DB::create();
    }

    public function register($username, $email, $password)
    {
        // ตรวจสอบว่า email มีอยู่แล้วหรือไม่
        if ($this->db->exists('users', ['email' => $email])) {
            throw new Exception('Email already exists');
        }

        // สร้างผู้ใช้ใหม่
        $userId = $this->db->insert('users', [
            'username' => $username,
            'email' => $email,
            'password' => password_hash($password, PASSWORD_DEFAULT),
            'status' => 'active',
            'created_at' => date('Y-m-d H:i:s')
        ]);

        return $userId;
    }

    public function login($email, $password)
    {
        $user = $this->db->first('users', [
            'email' => $email,
            'status' => 'active'
        ]);

        if ($user && password_verify($password, $user->password)) {
            // อัปเดทเวลาเข้าใช้งานล่าสุด
            $this->db->update('users',
                ['id' => $user->id],
                ['last_login' => date('Y-m-d H:i:s')]
            );

            return $user;
        }

        return null;
    }

    public function getUserStats()
    {
        return [
            'total' => $this->db->count('users'),
            'active' => $this->db->count('users', ['status' => 'active']),
            'inactive' => $this->db->count('users', ['status' => 'inactive'])
        ];
    }
}

ระบบแคชอย่างง่าย

use Kotchasan\DB;

class SimpleCache
{
    private DB $db;

    public function __construct()
    {
        $this->db = DB::create();

        // Create cache table if not exists
        $this->createCacheTable();
    }

    public function set(string $key, $value, int $ttl = 3600): ?int
    {
        $data = [
            'cache_key' => $key,
            'cache_value' => serialize($value),
            'expires_at' => date('Y-m-d H:i:s', time() + $ttl),
            'created_at' => date('Y-m-d H:i:s')
        ];

        // Delete old data if exists
        $this->db->delete('cache', ['cache_key' => $key], 0);

        // Insert new data
        return $this->db->insert('cache', $data);
    }

    public function get(string $key)
    {
        $item = $this->db->first('cache', [
            ['cache_key', $key],
            ['expires_at', '>', date('Y-m-d H:i:s')]
        ]);

        return $item ? unserialize($item->cache_value) : null;
    }

    public function delete(string $key): bool
    {
        return $this->db->delete('cache', ['cache_key' => $key]) > 0;
    }

    public function clear(): bool
    {
        return $this->db->emptyTable('cache');
    }

    public function cleanup(int $days = 3): int
    {
        // Delete expired data
        $cutoff = date('Y-m-d H:i:s', strtotime("-{$days} days"));
        return $this->db->delete('cache', [['expires_at', '<', $cutoff]], 0);
    }

    private function createCacheTable(): void
    {
        // Check if table exists
        if (!$this->db->fieldExists('cache', 'cache_key')) {
            // Create table with raw SQL
            $this->db->raw("
                CREATE TABLE IF NOT EXISTS `{$this->db->getTableName('cache')}` (
                    `id` int(11) NOT NULL AUTO_INCREMENT,
                    `cache_key` varchar(255) NOT NULL,
                    `cache_value` longtext NOT NULL,
                    `expires_at` datetime NOT NULL,
                    `created_at` datetime NOT NULL,
                    PRIMARY KEY (`id`),
                    UNIQUE KEY `cache_key` (`cache_key`),
                    KEY `expires_at` (`expires_at`)
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
            ");
        }
    }
}

ระบบบันทึก Log อย่างง่าย

use Kotchasan\DB;

class SimpleLogger
{
    private DB $db;

    public function __construct()
    {
        $this->db = DB::create();
    }

    public function log($level, $message, $context = [])
    {
        return $this->db->insert('logs', [
            'level' => $level,
            'message' => $message,
            'context' => json_encode($context),
            'created_at' => date('Y-m-d H:i:s'),
            'ip_address' => $_SERVER['REMOTE_ADDR'] ?? null,
            'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? null
        ]);
    }

    public function info($message, $context = [])
    {
        return $this->log('info', $message, $context);
    }

    public function warning($message, $context = [])
    {
        return $this->log('warning', $message, $context);
    }

    public function error($message, $context = [])
    {
        return $this->log('error', $message, $context);
    }

    public function getLogs(?string $level = null, int $limit = 10): array
    {
        $where = [];
        if ($level !== null) {
            $where = ['level' => $level];
        }

        return $this->db->select('logs', $where, [
            'orderBy' => ['created_at' => 'DESC'],
            'limit' => $limit
        ]);
    }

    public function cleanupOld(int $days = 3): int
    {
        $cutoff = date('Y-m-d H:i:s', strtotime("-{$days} days"));

        return $this->db->delete('logs', [['created_at', '<', $cutoff]], 0);
    }
}

ข้อควรทราบ

  1. ใช้งานง่าย: เหมาะกับงานที่ไม่ซับซ้อน
  2. ประสิทธิภาพ: งาน query ซับซ้อนควรใช้ Database class
  3. การจัดการ Error: หลายเมธอดคืนค่า null/false เมื่อเกิด error
  4. Transactions: ควรใช้ try-catch ทุกครั้ง
  5. ความปลอดภัย: ใช้ parameter binding และหลีกเลี่ยง raw SQL เมื่อไม่จำเป็น

คลาสที่เกี่ยวข้อง

  • Database - คลาสหลักสำหรับจัดการฐานข้อมูล
  • QueryBuilder - ตัวสร้างคำสั่ง SQL แบบขั้นสูง
  • Connection - การจัดการการเชื่อมต่อฐานข้อมูล