PhpBoot 入門(二) 面向對象的方式編寫 SQL

PhpBoot 是一款爲快速開發 RESTful API 而設計的PHP框架(加星請點這裏>>>PbpBoot Github<<<)。php

PhpBootDB 對PDO進行了封裝,使開發者能夠更方便的編寫正確和安全的 SQL。下面將繼續上一篇: 快速開發 RESTful 接口的示例,介紹PhpBoot\DB的使用。html

配置

能夠經過依賴注入的方式,對數據庫進行配置。mysql

  1. 在須要數據庫的類中加入依賴注入代碼:git

    use PhpBoot\DB\DB;
    use PhpBoot\DI\Traits\EnableDIAnnotations;
    
    class Books
    {
        use EnableDIAnnotations; //啓用經過@inject標記注入依賴
    
        /**
         * @inject
         * @var DB
         */
        private $db;
        
        public function getBooks()...
    }

    框架在實例化Books後,根據@inject註釋, 自動給屬性$db賦值,其邏輯等價於:github

    $books->db = $app->get(DB::class);
  2. 修改數據庫配置sql

    在 config.php 中加入如下配置(數據庫地址等需根據實際狀況修改):數據庫

    'DB.connection'=> 'mysql:dbname=phpboot-example;host=127.0.0.1',
    'DB.username'=> 'root',
    'DB.password'=> 'root',
    'DB.options' => [],

編寫 SQL

下面將經過實現 createBook、deleteBook、updateBook、findBooks 方法,演示insert、delete、update、select 的使用。安全

INSERT

public function createBook(Book $book)
{
    $newId = $this->db->insertInto('books')
        ->values([
            'name'=>$book->name,
            'brief'=>$book->brief,
            ...
        ])
        ->exec()
        ->lastInsertId(); 
    return $newId;
}

DELETE

public function deleteBook($id)
{
    $this->db->deleteFrom('books')
        ->where(['id'=>$id])
        ->exec();
}

UPDATE

public function updateBook(Book $book)
{
    $this->db->update('books')
        ->set([
            'name'=>$book->name,
            'brief'=>$book->brief,
            ...
        ])
        ->where(['id'=>$book->id])
        ->exec(); 
}

SELECT

public function findBooks($name, $offsit, $limit)
{
    $books = $this->db->select('*')
        ->from('books')
        ->where('name LIKE ?', "%$name%")
        ->orderBy('id')
        ->limit($offsit, $limit)->get();
        
    return $books;
}

高級用法

上述示例展現了PhpBoot\DB的基礎用法,PhpBoot\DB同時也支持更復雜的SQL。app

複雜 WHERE

相似 SQL WHERE a=1 OR (b=2 and c=3), 能夠如下代碼實現:框架

->where(['a'=>1])
->orWhere(function(ScopedQuery $query){
    $query->where(['b'=>2, 'c'=>3])
})

上面例子中,ScopedQuery 中還能再嵌套 ScopedQuery

JOIN

$db->select('books.*', DB::raw('authors.name as author'))
    ->from('books')
    ->where(['books.id'=>1])
    ->leftJoin('authors')->on('books.authorId = authors.id')
    ->get()

WHERE ... IN ...

使用PDO時,WHERE IN的預處理方式很不方便,須要爲IN的元素預留數量相等的?, 好比:

$pdo->prepare(
    'SELECT * FROM table WHERE a IN (?,?,?)'
)->execute([1,2,3])

而使用PhpBoot\DB能夠解決這個問題:

$db->select()->from('table')->where('a IN (?)', [1,2,3]);

使用 SQL 函數

默認狀況下,框架會對輸入作轉換, 如會在表名和列名外加上 `` ,會把變量做爲綁定處理,好比下面的語句

$db->select('count(*) AS count')
    ->from('table')
    ->where(['time'=>['>'=>'now()']]);

等價 的 SQL:

SELECT `count(*) AS count` FROM `table` where `time` > 'now()'

若是但願框架不作轉換,須要使用DB::raw(),好比:

$db->select(DB::raw('count(*) AS count'))
    ->from('table')
    ->where(['time'=>['>'=>DB::raw('now()')]]);

與下面 SQL 等價

SELECT count(*) AS count FROM `table` where `time` > now()

子查詢

下面代碼演示子查詢用法:

$parent = $db->select()->from('table1')->where('a=1');
$child = $db->select()->from($parent);

與下面 SQL 等價

SELECT * FROM (SELECT * FROM `table1` WHERE a=1)

事務

$db->transaction(
    function(DB $db){
        $db->update('table1')->...
        $db->update('table1')->...
    }
)

事務容許嵌套,但只有最外層的事務起做用,內部嵌套的事務與最外層事務將被當作同一個事務。

使用多個數據庫

PhpBoot 爲DB 類定義了默認的構造方式,形式以下:

DB::class => \DI\factory([DB::class, 'connect'])
    ->parameter('dsn', \DI\get('DB.connection'))
    ->parameter('username', \DI\get('DB.username'))
    ->parameter('password', \DI\get('DB.password'))
    ->parameter('options', \DI\get('DB.options')),

因此若是你的業務只使用鏈接一個數據庫,只須要對DB.connection, DB.username ,DB.password, DB.options進行配置便可。但有的時候可能須要對在應用中鏈接不一樣的數據庫,這時能夠經過依賴注入配置多個庫,如:

  1. 先配置另外一個數據庫鏈接

    'another_db' => \DI\factory([DB::class, 'connect'])
        ->parameter('dsn', 'mysql:dbname=phpboot-example;host=127.0.0.1')
        ->parameter('username', 'root')
        ->parameter('password', 'root')
        ->parameter('options', [])
  2. 在須要的地方注入此鏈接

    use PhpBoot\DB;
    
    class Books
    {
        /**
         * @inject another_db
         * @var DB
         */
        private $db2;
    }

    幫助和文檔

    • 在線文檔

    • QQ 交流羣:185193529

    • 本人郵箱 caoyangmin@gmail.com

相關文章
相關標籤/搜索