用户
 找回密码
 入住 CI 中国社区
搜索
查看: 8869|回复: 11
收起左侧

[数据库] 再发一个动态生成数据库模型,不用每个模型写CURD

[复制链接]
发表于 2013-5-21 11:07:24 | 显示全部楼层 |阅读模式
目的:
1、不重复编写基础的增删改查。
2、对仅需要基本增删改查的数据表,不创建文件,而是动态实例化。

基于几点考虑:
1、有很多数据表,需要很多数据模型的文件
2、需要重复编写CURD
3、有些数据表仅仅需要几本的CURD

大概的思路:
1、用MY_model 继承 CI_model
2、在MY_model 中编写常用的 curd 操作,并将“表名”作为类变量
3、用一个函数动态实例化数据模型的对象

PHP复制代码
 
/**
 * 动态生成CI的数据模型
 * 由于所有数据模型都会有基本的 insert/update/delete/get/gets操作,因此我们将他们动态生成
 * 对一个数据表的操作需求仅有 添加、更新、删除、获取单条、获取所有记录的SQL操作,才能使用本函数
 *
 * 必须有 my_model 继承 ci_model 且常用方法写在my_model中
 * @param string() $name        传入数据表名,返回该数据表的数据模型(如果表名不存在会报错)
 * @return object() $obj        返回该对象的实例
 */

function factModel($name){
        $nameModel = $name.'_model';
        $ci = &get_instance();
        if( !isset($ci->$nameModel) ){
                $ci->$nameModel = new MY_model();
                $ci->$nameModel->TABLE = $name;
        }
        return $ci->$nameModel;
}
 
复制代码


MY_MODEL.php 的代码,这里的数据库操作,是和我之前发的 支持读写分离的数据库类一起用的,自己可改成其他的用法

PHP复制代码
<?php/**
 * 提供表常用的insert、update、delete、get、gets 等几个方法,省的每个函数都要写,很烦人
 * 继承本类的模型,必须 public $TABLE = 表名, 否则 以上操作因为找不到表名而报错
 * 如果需要操作字表,建议:
 * function table_insert(){
 *   $id = $this->insert(主表插入)
 *       //编写字表插入的代码,更新和删除相同
 * }
 * @author Administrator
 */

class MY_model extends CI_Model {
        //put your code here
        public $TABLE = FALSE;
        function __construct() {
                parent::__construct();
        }
       
        //快速获取当前用户的uid
        function uid(){
                return $this->uid;
        }
       
        function insert($data){
                $sql = "INSERT INTO {$this->TABLE} {$this->db->st($data,'insert')}";
                $id = $this->db->runsql($sql);
                return $id;
        }
 
        function get($where){
                $rows = $this->gets( $where, '', 'limit 0,1');
                if( is_array($rows) && isset($rows[0]) ){
                        return $rows[0];
                }
                return NULL;
        }
       
        function gets($where, $order='', $limit=''){
               
                //如果传入的是数组,则使用and转换,否则请传入SQL片段
                $where = $this->db->st($where,'where');
               
                //如果没传入where的话,干脆就不用加条件了
                if( !empty($where) ){
                        $where = 'WHERE '.$where;
                }
                $sql = "SELECT * FROM {$this->TABLE} $where $order $limit";
                return $this->db->getData($sql);
        }
 
        function update($data, $where){
                $sql = "UPDATE {$this->TABLE} SET {$this->db->st($data,'update')} WHERE {$this->db->st($where,'where')}";
                return $this->db->runsql($sql);
        }
       
        function delete($where){
                $sql = "DELETE FROM {$this->TABLE} WHERE {$this->db->st($where,'where')}";
                return $this->db->runsql($sql);
        }      
}
 
?>
 
复制代码


 楼主| 发表于 2013-5-21 11:09:44 | 显示全部楼层
本帖最后由 baloyou 于 2013-5-21 13:47 编辑

动态使用方法:factModel('user')->get( array('uid'=>1) )
而factModel 函数我是放在 helper中全局加载的。
发表于 2013-5-25 11:11:40 | 显示全部楼层
不错的方法。mark
发表于 2013-5-30 10:59:23 | 显示全部楼层
非常不错,收藏。
发表于 2013-5-30 17:41:40 | 显示全部楼层
在MY_Controller加载公共Model不就行了,你这个弱爆了。
发表于 2013-6-14 10:39:34 | 显示全部楼层
奇怪大家怎麼那麼不喜歡CI的CURD,個人覺的不錯啊!
 楼主| 发表于 2013-7-2 15:00:16 | 显示全部楼层
longjianghu 发表于 2013-5-30 17:41
在MY_Controller加载公共Model不就行了,你这个弱爆了。

你确定只在控制器里操作数据库吗?

 楼主| 发表于 2013-7-2 15:03:07 | 显示全部楼层
Raphael 发表于 2013-6-14 10:39
奇怪大家怎麼那麼不喜歡CI的CURD,個人覺的不錯啊!

我当初是因为便于读写分离,才自己重新实现了一个DB,后来写小项目的时候图省心,就干脆把基本模型也省了
发表于 2013-7-2 17:05:13 | 显示全部楼层
記得已有文章教在CI 2.X的讀寫分離方法了,
找看看一定可以找到.
发表于 2013-7-3 09:38:55 | 显示全部楼层
Raphael 发表于 2013-7-2 17:05
記得已有文章教在CI 2.X的讀寫分離方法了,
找看看一定可以找到.

CI 可以连接多个数据库,从这里直接入手就行了。

本版积分规则