ThinkPHP5.0教程学习06:TP5 数据库与模型操作

学习教程来源于:
php中文网 ThinkPHP5 视频教程
ThinkPHP5.0完全开发手册

连接器与查询构造器

ThinkPHP5.0教程学习06:TP5 数据库与模型操作_第1张图片

TP5采用的是惰性连接,故而仅在查询时才会连接到数据库

TP5的数据库操作对底层进行优化设计,对各种操作进行高级封装。既可以直接使用连接器进行高效的原生查询,也可以使用封装好的查询构造器进行直观便捷的查询,为模型操作打下基础。

创建数据库连接(静态与动态方式)

静态连接:应用/模块中的数据库配置文件database.php
动态连接:入口类Db.php中的connect(参数:数组/字符串)方法

参数名 默认值 说明
type mysql 数据库类型
hostname 127.0.0.1 服务器地址
database 数据库名称
username 数据库用户名
passward 数据库密码
hostport 3306 数据库连接端口
charset utf8 数据库默认编码
prefix 数据库表的前缀
debug TRUE 数据库调试模式

①动态设置

public function demo()
{
    $config = [
        'type' => 'mysql',
        'hostname' => 'localhost',
        'username' => 'root',
        'password' => 'root',
        'database' =>'tp5',
    ];
    //1.获取数据库的链接实例/对象
    $link = Db::connect($config);
    //2.用连接实例调用查询类的查询方法
    $result = $link->table('staff')->select();
    //3.输出查询结果
    dump($result);
}

②动态配置连接字符串

mysql://root:1234@localhost:3306/thinkphp#usf8

数据库类型://用户名:密码@数据库地址:数据库端口/数据库名称#字符集

public function demo()
{
   
    //1.获取数据库的链接实例/对象 
    $config = 'mysql://root:root@localhost:3306/tp5#utf8';
    $link = Db::connect($config);
    //2.用连接实例调用查询类的查询方法
    $result = $link->table('staff')->select();
    //3.输出查询结果
    dump($result);
}

简化代码如下:

public function demo()
{
   
    $result = Db::table('staff')->select();
    dump($result);
}

!!!db()助手函数不支持惰性连接

数据库的原生查询实现原理:query和execute方法

Connection类:
①query(sql语句字符串,[参数绑定]):读操作—>select
②execute(sql语句字符串,[参数绑定]):写操作—>insert/update/delete

支持在原生查询的时候使用参数绑定,包括问号占位符或者命名占位符,参数绑定可以防止sql注入:

Db::query("select * from think_user where id=? AND status=?",[8,1]);
// 命名绑定
Db::execute("update think_user set name=:name where status=:status",['name'=>'thinkphp','status'=>1]);

Connection类实例通过入口类Db静态自动调用,不用显示写出

public function demo()
{
    //1.查询操作:查询工资大于4000远的员工信息用命名占位符进行参数绑定
    $sql = "select name,salary,dept from staff where salary > :salary";
    $result = Db::query($sql,['salary'=>4000]);//数组中的第一个元素和第一个问号对应
    dump($result);

    //2.更新操作:将Id=3的记录,salary增加1000
    $sql = "update staff set salary = salary+1000 where id=:id";
    $result = Db::execute($sql,['id'=>3]);
    dump($result);//返回受影响非记录条数

    //3.插入操作:默认添加到表的尾部的
    $sql = "insert into staff (name,sex,salary) values (:name,:sex,:salary)";
    $result = Db::execute($sql,['name'=>'郭襄','sex'=>0,'salary'=>3500]);
    dump($result);

    //4.删除操作:id=4的记录删除
    $sql = "delete from staff where id=:id";
    $result = Db::execute($sql,['id'=>4]);
    dump($result);

}
查询构造器(抽象访问层)

ThinkPHP5.0教程学习06:TP5 数据库与模型操作_第2张图片

ThinkPHP5.0教程学习06:TP5 数据库与模型操作_第3张图片

①链式操作的功能是快速生成查询条件
②链式操作中的所有的方法都来自于query查询类
③链式操作的返回值就是当前的查询对象

生成查询条件的三种方法:表达式/数组/闭包(推荐)

2个方法:
①where():AND条件
②whereOr():OR条件

三种格式:
①where(‘字段名’,‘表达式’,‘查询条件’)

public function index()
{
  dump(
    Db::table('staff')
    ->field(['name','salary'])
    ->where('id','>',2)
    ->select()
  );
}

②where([‘字段名’=>[‘表达式’,‘查询条件’],…])

public function index()
{
  dump(
    Db::table('staff')
    ->field(['name','salary'])
    ->where([
      'id'=>['>',2],
      'salary'=>['>',3000]
    ])
    ->select()
  );
}

③where(function($query){//链式查询语句;})

推荐方式:闭包的好处在于可以实现复杂的条件调用,且可以使用外部传入的变量

public function index()
    {
      dump(
        Db::table('staff')
        ->field(['name','salary'])
        ->where(function ($query){
            $query->where('id','>',1)
                  ->where('salary','>',4000);
        })
        ->select()
      );
    }
public function index()
    {
      $salary = 4000;
      // dump(
      //   Db::table('staff')
      //   ->field(['name','salary'])
      //   ->where(function ($query) use ($salary){
      //       $query->where('id','>',1)
      //             ->where('salary','>',$salary);
      //   })
      //   ->select()
      // );
      
      dump(
        Db::select(
          function ($query) use ($salary) {
            $query->table('staff')
            ->field(['name','salary'])
            ->where([
                'id'=>['>',2],
                'salary'=>['>',$salary]
            ]);
          })
        );
    }
select与find

参考:TP5 完全开发手册

查询一个数据使用find

// table方法必须指定完整的数据表名
Db::table('think_user')->where('id',1)->find();

find 方法查询结果不存在,返回 null

查询数据集使用select

Db::table('think_user')->where('status',1)->select();

select 方法查询结果不存在,返回空数组

数据库的新增与更新操作

1.新增
insert(['字段'=>'值']) 插入单条记录
insertAll(['二维数组']) 同时插入多条记录

2.更新
update(['字段'=>'值']) 根据条件更新一条或多条记录
setInc/setDec('字段','步长') 如果字段类型是数字型,且每次更新时有规律的,则可以使用这种方式

延迟更新

setInc/setDec支持延时更新,如果需要延时更新则传入第三个参数
下例中延时10秒,给score字段增加1

Db::table('think_user')->where('id', 1)->setInc('score', 1, 10);

setInc/setDec方法返回影响数据的条数

3.读取
find(主键) 单条读取,以一维数组的形式返回
select(主键) 返回多条满足条件的记录,可以以二维数组的方式返回

4.删除
delete(主键) 根据条件进行删除
delete(true) 无条件删除,清空数据表(危险操作)

delete删除方法不支持闭包

数据库的查询与删除操作:find/select/value/column/delete

1.value获取某个字段的值

public function index()
{
 //value('字段','默认值')
 $result = Db::table('staff')->where('id',1)->value('name');
 dump($result);
}

2.column输出一列数据

public function index()
{
 //value('字段','默认值')
 $result = Db::table('staff')->where('id','>',1)->column('name','id');//column的第一个参数为值,第二个参数为键名
 dump($result);
}

3.delete删除数据

public function index()
{
 //value('字段','默认值')
 $result = Db::table('staff')
 ->delete(7);
 return $result?'成功删除了'.$result.'条记录' : '删除失败';
}
模型的基本概念与基类Model介绍

模型是对实体的抽象描述,快速直观的展示出实体的特征。

TP5中的模型是指数据表(粗略理解)。

模型类中的属性与方法:
1.模型类中的属性和方法需要在基类Model中查看
2.Model.php类位于public/library/think/Model.php
3.该类是一个抽象类,不能被实例化,必须由子类继承并实现内部的全部抽象方法

模型的创建与使用:实例化与静态创建

模型与数据表的对应关系:
模型的属性与数据表的字段一一对应,数据表中的一行信息对应模型的一个实例。而模型的方法则定义了对当前数据表的一些操作。

①区别于联系

区别:
1.分工不同:Db类负责数据表的访问,模型专注于业务逻辑的处理
2.返回值不同:Db访问返回数组,模型操作返回对象

联系:
模型最终仍需调用Db类完成数据表的查询操作。
模型可以看做是一种更高级别的抽象,最终的底层仍然需要依靠Db类完成数据表的增删改查操作。

②创建模型

1.手工创建:
在应用或模块下创建模型目录model,并在该目录下创建与数据表同名的类文件:如User.php对应user.dbf表。(首字母大写)
2.命令创建:
在当前项目目录下,用命令:php think make:model 模块名/模型名,会自动创建指定位置和命名空间的空模型,并自动与数据表绑定;
3.模型创建完成后,会自动获取当前数据表名称$table,表中所有字段信息$field,主键$pk和数据库配置信息$connection.同时会自动继承基类Model中所有属性和方法,protected类型在本模型中使用,public类型还可以在控制器使用,静态方法大多直接用在控制器,进行CURD操作。

③控制器中调用模型

一、实例化调用:
1.用new生成模型对象
2.用模型对象处理相关业务

 where('id',3)->find();
     dump($result->getData('name'));
    }
}

二、静态调用:
1.通过静态查询直接将一个空模型转为数据模型
2.再调用相关方法完成增删改查操作

getData('sex'));
    }

    
}

三、不推荐使用助手函数model()和添加模型类后缀

④模型数据访问方式

1.控制器访问(外部)->用模型对象:$model

2.模型访问(内部)->用伪对象变量:$this

模型的CURD操作

Cread/Update/Read/Delete

1.模型向数据表中添加数据:save()/saveAll()/update()
方法 说明 调用方法 返回值
save($data=[]) 添加单条 实例化 影响记录数
saveAll($data=[]) 批量添加 实例化 模型对象数组
create($data=[]) 单条添加 静态 模型对象

①数据创建过程可以触发很多操作,非Db类操作可比
②静态调用的实质其实仍是实例化调用,只是将CURD方法进行静态封装
saveAll()方法实际上是通过多次执行insert语句完成,很少用到
④理论上讲,通过模型向表中添加数据,尽可能都采用静态方式

name = '韦小宝';
     $staff->sex = 1;
     $staff->salary = 9000;

     //3.执行数据添加操作
     $result = $staff->save();
	 return $result ? '成功添加了'.$result.'条记录' : '添加失败';
    }
}
'陈近南','salary'=>40000],
        ['name'=>'吴三桂','salary'=>60000],
        ['name'=>'陈圆圆','salary'=>8000],
     ];

     //3.执行数据添加操作
     $result = $staff->saveAll($data);
     dump($result);
    }
}

'林平之','sex'=>'1','salary'=>300
     ]);
     dump($result->getData());
    }

    
}

2.模型的更新操作:save()/saveAll()/update()
方法 说明 调用方法 返回值
save($data=[],$where=[]) 单条更新 实例化 影响记录数
saveAll($data=[].true) 批量更新 实例化 模型对象数组
update($data=[],$where=[],$field=[]) 单条更新 静态 模型对象

1.不允许无条件更新,必须设置更新条件
2.可以将更新条件,如主键写在更新数据中,方法可以自动识别
3.更新条件可以使用闭包,完成更复杂的业务逻辑

8,
        'name'=>'岳不群',
        'sex'=>1
     ];
     $staff->isUpdate(true)->save($data);
     dump($staff->getData());
    }   
}
'张无忌',
        'sex'=>1,
     ];
     $where = [
        'Id'=>13,
     ];
     $staff->save($data,$where);
     dump($staff->getData());
    }  
}
14,'name'=>'张无忌','sex'=>1],
        ['Id'=>15,'name'=>'赵敏','sex'=>0],
        ['Id'=>16,'name'=>'小昭','sex'=>1],
     ];
     $staff->isUpdate(true)->saveAll($data);
     dump($staff->getData());
    }
}
'韦一笑','sex'=>1,'salary'=>5600
     ];
     $where = ['id'=>24];
     $field = ['name','sex'];
     $result = Staff::update($data,$where,$field);
     dump($result->getData());
    }  
}
'韦一笑','sex'=>1,'salary'=>5600
     ];
     //更新条件使用闭包写法
     //闭包支持外部传入的变量
     $where = function ($query){
        $query->where('Id',25);
     };
     $field = ['name','sex'];
     $result = Staff::update($data,$where,$field);
     dump($result->getData());
    }  
}
3.模型的查询操作:find()/select()/get()/all()

ORM模型(对象关系映射)
ThinkPHP5.0教程学习06:TP5 数据库与模型操作_第4张图片

方法 调用方式 返回值
find($where)get($where) 实例化/静态 模型对象
select($where)all($where) 实例化/静态 模型对象数组

1.原则来说,查询都应该采用静态查询方法
2.尽可能采用get()all()方法代替find()selec()
3.牢记一条原则:一个模型对象实例应该唯一对应数据表的一条记录

 field(['name','salary'])
        -> where('id','=',3);
     };
     $result = $staff->find($where);
     //$result = $staff->get($where);
     dump($result->getData());
    }  
}
 field(['name','salary'])
        -> where('salary','>',10000);
     };
     $result = $staff->select($where);
     //$result = $staff->all($where);
     foreach ($result as $value) {
         dump($value->getData());
     }
    }  
}
 field(['name','salary'])
        -> where('salary','>',10000);
     };
     $result = $staff->all($where);
     foreach ($result as $key => $value) {
         // dump($value->getData());
         echo '记录编号:'.($key+1).' | 姓名:'.$value->name.' | 工资:'.$value->salary.'
'; } } }
field(['name','salary'])
        ->where('id','=',2);
     };
     // $result = Staff::find($where);
     $result = Staff::get($where);
     dump($result->getData());
    }  
}
field(['name','salary'])
        ->where('id','>',2);
     };
     // $result = Staff::select($where);
     $result = Staff::all($where);
     foreach ($result as $value) {
        dump($value->getData());
     }
    }  
}
4.模型的删除操作:delete()和destroy()
方法 调用方式 返回值
delete() 实例化 受影响的记录数量
destroy(条件/闭包) 静态 受影响记录数量

1.delete()不要传任何参数,他只删除当前模型对象对应的记录
2.destroy()中的删除条件,推荐采用闭包方式
3.推荐用软删除替代该方法,即用更新的方式来实现删除操作

where('id','>',12)
        ->where('sex','=',1)
        ->whereOr('salary','>',4000);
     };
     
     $value = Staff::destroy($where);
     dump($value);
    }  
}

5.模型读取器与修改器:getAttr()和setAttr()

①模型的读取器
触发条件:当用模型对象读取表中字段值的时候
应用场景:日期时间字段、集合或枚举数据、数字状态与文本转换、字段拼接
设置位置:在模型中设置,访问属性通常为protected,不允许外部直接访问
方法名称get属性名称Attr($name,$data=[])

get FieldName Attr($name,$data=[])
驼峰命名法,对应表中字段:field_name

模型的读取器工作原理图
ThinkPHP5.0教程学习06:TP5 数据库与模型操作_第5张图片

②模型的修改器
触发条件:当用模型对象向数据表中新增记录或更新字段值的时候
应用场景:日期时间字段、集合或枚举数据、数字状态与文本转换、字段拼接
设置位置:在模型中设置,访问属性通常为protected,不允许外部直接访问
方法名称set属性名称Attr($name,$data=[])

set FieldName Attr($name)
驼峰命名法,对应表中字段:field_name

模型的修改器工作原理图
ThinkPHP5.0教程学习06:TP5 数据库与模型操作_第6张图片


6.模型数据类型转换:$type属性设置技巧

字符串类型是默认的读取类型

 'array',		//以json格式写入,取出自动编码为array
	'age' 		 => 'integer',		//该字段写入和输出的时候都会字段转换为整型
	'salary'	 => 'float',		//该字段写入和输出的时候都会自动转换为浮点型
	'dept' 		 => 'serialize',	//自动序列化写入,读取的时候自动反序列化
	'home'		 => 'json',			//json_encode写入,读取时json_decode处理
	'hiredate'	 => 'timestamp',	//用strtotime转为时间戳写入,读出按$dateFormat格式输出
	'birthday'	 => 'datetime'		//读写都是按$dateFormat格式处理
];
?>
7.模型自动完成设置:$insert/$update/$auto属性配置技巧

一、自动时间戳
1.模型中开启:protected $autoEriteTimestamp=true
2.在表中手工创建二个字段:create_time,update_time
3.用户自行新增和更新操作时,会自动将新增与更新时间写入表中
4.默认以时间戳格式写入,可以配置为:datatime格式

二、自动完成
1.$insert=['字段'=>'值',...]; //新增时自动插入到表中的
2.$update=['字段'=>'值',...]; //更新时自动更新字段值
3.$auto=['字段'=>'值',...]; //新增或更新时自动填入或更新字段值
通常要与类型自动转换属性:$type=['字段'=>'类型',...]相配合

4500,
    	'hiredate'=>'2019-09-16',
    ];
    // 新增自动完成列表
    protected $insert = [
    	// 'sex'=>1,
    	'dept',	//部门名称,根据员工性别sex字段的值确定
    	'hiredate'=>'2019-09-16',
    ];
    // 更新自动完成列表
    protected $update = [
    	'dept'=>'测试部',
    ];
    protected $type = [
    	'hiredate'=>'timestamp',
    ];
    protected function setDeptAttr($dept,$data)
    {
    	if ($data['sex']) {
    		return $this->dept = '开发部';
    	}else{
    		return $this->dept = '客服部';
    	}
    }
}
?>

你可能感兴趣的:(PHP,ThinkPHP5.0)