0

私が直面している問題の 1 つは、select ステートメントは似ているが join/where ステートメントが異なるクエリが多数あることです。

以下は、CodeIgniter を介して作業しているコードの例です。私が通常行うことは、ランダムなキー/値の配列を受け入れる 1 つの関数 get() を作成することです。渡されるキー/値に応じて、適切なクエリが生成されて実行されます。さて、これは良い方法なのだろうか?ご覧のとおり、この関数はますます複雑になっています。最初は、get_all()、get_only_lessons() などの関数がたくさんありましたが、1 行または 2 行が異なる同じコード セットを繰り返さなければならないのはちょっと面倒です。

私の質問は、この問題に対処するための最良の方法は何ですか.

function get($param = NULL)
{
    /*
    SELECT  m.id AS id, CAST(m.order_number AS SIGNED) AS order_number, m.name AS name, m.permalink as permalink, 
        m.suplesson_id as suplesson_id, CAST(sm.order_number AS SIGNED) AS suplesson_order_number
    FROM    lessons m
    JOIN    courses c ON m.course_id = c.id
    LEFT JOIN lessons sm ON m.suplesson_id = sm.id
    WHERE   [various]
    */

    $select =   'm.id AS id, CAST(m.order_number AS SIGNED) AS order_number, m.name AS name, m.permalink as permalink, ';
    $select .= ' m.suplesson_id as suplesson_id';

    if (isset($param['id']) || isset($param['suplesson_order_number']) || isset($param['permalink']))   
        $select .= ', CAST(sm.order_number AS SIGNED) AS suplesson_order_number ';

    $this->db->select($select);
    $this->db->from($this->table_name.' m');
    $this->db->join($this->courses_table_name.' c', 'm.course_id = c.id');

    if (isset($param['id']) || isset($param['suplesson_order_number']) || isset($param['permalink']))
        $this->db->join($this->table_name.' sm', 'm.suplesson_id = sm.id', 'left');

    // where clauses
    if (isset($param['course_id'])) 
        $this->db->where(array('c.id' => $param['course_id']));
    if (isset($param['id'])) 
        $this->db->where(array('m.id' => $param['id']));
    if (isset($param['order_number'])) 
        $this->db->where(array('m.order_number' => $param['order_number']));
    if (isset($param['permalink'])) 
        $this->db->like('m.permalink', $param['permalink'], 'none');
    if (isset($param['suplesson_id'])) 
        $this->db->where(array('m.suplesson_id' => $param['suplesson_id']));
    if (isset($param['suplesson_order_number'])) 
        $this->db->where(array('sm.order_number' => $param['suplesson_order_number']));
    if (isset($param['NULL'])) 
        $this->db->where('m.'.$param['NULL'].' IS NULL');
    if (isset($param['NOT NULL'])) 
        $this->db->where('m.'.$param['NOT NULL'].' IS NOT NULL');

    $this->db->order_by('order_number');

    // filter based on num_rows/offset
    if (isset($param['id']) || isset($param['permalink']))  
        $this->db->limit(1);
    if (isset($param['num_rows']) && isset($param['offset'])) 
        $this->db->limit($param['num_rows'], $param['offset']);

    $query = $this->db->get();

    // return row if expecting 1 result 
    if (isset($param['id']) || isset($param['suplesson_order_number']) || isset($param['permalink']))   
        return ($query->num_rows() == 1) ? $query->row_array() : NULL;

    return ($query->num_rows() > 0) ? $query->result_array() : NULL;
}
4

1 に答える 1

0

DB クエリを実行する通常の方法は、モデル コードを構造化して複数の関数呼び出しを持ち、それぞれが 1 つの SQL ステートメントに関連するようにすることです。次に例を示します。

function get_user($userId)
{
    $this->db->get_where('user', array('userId' => $userId))
    //...
    //...        
}

function delete_user($userId)
{
    $this->db->delete('user',array('userId' => $userId))
}

ユーザーテーブルの読み取り/更新に必要なすべての関数を含む User_model というモデルクラスを作成する場合があるため、コントローラーで特定のモデル関数を呼び出します

$user = $this->User_model->get_user($userId)

どの SQL ステートメントを実行するかを決定するために、さまざまなパラメーターをチェックする 1 つの巨大なモデル関数を構築しようとしているようです。これは良い設計ではなく、Codeignitors MVC モデルにうまく適合しません。代わりに、テーブルごとに個別のモデルを作成し、各モデルで、実行する SQL 操作ごとに個別の関数を作成します。これらのモデルをコントローラーから呼び出して、テーブル内のデータを取得/更新/削除します。

于 2012-05-30T20:54:11.907 に答える