1、thinkphp5的数据库操作
连接数据库库的方式
a、配置文件定义:配置文件位于applicationdatabase.php, 访问:$db::table('user')->select();
b、方法配置
Db::connect([ // 数据库类型 'type' => 'mysql', // 数据库连接DSN配置 'dsn' => '', // 服务器地址 'hostname' => '127.0.0.1', // 数据库名 'database' => 'thinkphp', // 数据库用户名 'username' => 'root', // 数据库密码 'password' => '', // 数据库连接端口 'hostport' => '', // 数据库连接参数 'params' => [], // 数据库编码默认采用utf8 'charset' => 'utf8', // 数据库表前缀 'prefix' => 'think_', ]);
//访问
$data = $db->table('user')->select();
也可以使用字符串连接
Db::connect('mysql://root:1234@127.0.0.1:3306/thinkphp#utf8');
c、模型类定义
<?php namespace appindexmodel; use thinkModel; class User extends Model{ protected $connection = [ // 数据库类型 'type' => 'mysql', // 服务器地址 'hostname' => '127.0.0.1', // 数据库名 'database' => 'learn', // 用户名 'username' => 'root', // 密码 'password' => '******', // 端口 'hostport' => '3306', ]; }
//在控制器中进行使用
public function index(){ $user = new User(); $data = $user::all(); dump($data); }
使用数据库操作
普通查询和操作,可以使用Db这个对象,也可使用内置的方法db()->query(...) 方法
//返回的是查询的数据 $data = Db::query('select * from `user`'); $data = Db::query('select `name`, `phone` from `user` where `id` > :id', ['id' => 5]); //返回的是执行成功的记录数 $res = Db::execute('INSERT INTO `user` (`name`, `age`, `sex`, `phone`) VALUES ("yyy", 20, 0, 15756453562)'); $res = Db::execute('INSERT INTO `user` (`name`, `age`, `sex`, `phone`) VALUES (:name, :age, :sex, :phone)', ['name'=> 'fff', 'age'=> 30, 'sex'=> 1, 'phone'=> 15463547565]);
使用构造器进行查询操作
//table name 的使用 //通常没有设置前缀的时候可以用table $res = Db::table('user')->select(); //有设置前缀用name,但是没有设置前缀的情况下,也可用使用 $res = Db::name('user')->select();
$res = Db::table('user')->field(true)->where('id', 60)->value('name');
where的使用
//where的使用 $result = Db::table('user')->where(function ($query) { $query->where('id', 1)->whereor('id', 2); })->whereOr(function ($query) { $query->where('name', 'like', 'think')->whereOr('name', 'like', 'thinkphp'); })->select(); //多个where链式调用 $res = Db::table('user')->where('id', '>', 5)->where('name', 'abc')->select(); //也可以进行以下查询 $res = Db::table('user')->where(['id' => ['>', 5], 'age' => ['<', 28]])->select(); $res = Db::table('user')->where(['id'=> 1, 'name'=> 'abc'])->select(); $res = Db::table('user')->where('id=2 and name="小红"')->select(); $res = Db::table('user')->where('id=:id and name=:name')->bind(['id'=> 2, 'name'=> '小红'])->select(); Db::table('user') ->where('name','like','%thinkphp') ->where('status',1) ->find(); //可以写成以下的方法 Db::table('user') ->where('name&title','like','%thinkphp') ->find(); Db::table('user') ->where('name','like','%thinkphp') ->whereOr('title','like','%thinkphp') ->find(); //可以写成以下方法 Db::table('user') ->where('name|title','like','%thinkphp') ->find();
$res = User::whereBetween('id', [10, 50])->select(); $res = User::whereIn('id', [10, 50])->select();
TP运算符 | SQL运算符 | 例子 | 实际查询条件 |
---|---|---|---|
eq | = | $map['id'] = array('eq',100); | 等效于:$map['id'] = 100; |
neq | != | $map['id'] = array('neq',100); | id != 100 |
gt | > | $map['id'] = array('gt',100); | id > 100 |
egt | >= | $map['id'] = array('egt',100); | id >= 100 |
lt | < | $map['id'] = array('lt',100); | id < 100 |
elt | <= | $map['id'] = array('elt',100); | id <= 100 |
like | like | $map<'username'> = array('like','Admin%'); | username like 'Admin%' |
between | between and | $map['id'] = array('between','1,8'); | id BETWEEN 1 AND 8 |
not between | not between and | $map['id'] = array('not between','1,8'); | id NOT BETWEEN 1 AND 8 |
in | in | $map['id'] = array('in','1,5,8'); | id in(1,5,8) |
not in | not in | $map['id'] = array('not in','1,5,8'); | id not in(1,5,8) |
and(默认) | and | $map['id'] = array(array('gt',1),array('lt',10)); | (id > 1) AND (id < 10) |
or | or | $map['id'] = array(array('gt',3),array('lt',10), 'or'); | (id > 3) OR (id < 10) |
xor(异或) | xor | 两个输入中只有一个是true时,结果为true,否则为false,例子略。 | 1 xor 1 = 0 |
exp | 综合表达式 | $map['id'] = array('exp','in(1,3,8)'); | $map['id'] = array('in','1,3,8'); |
alias的使用
Db::table('think_user')->alias('a')->join('__DEPT__ b ','b.user_id= a.id')->select(); Db::table('think_user')->alias(['think_user'=>'user','think_dept'=>'dept'])->join('think_dept','dept.user_id= user.id')->select();
field的使用
//默认选择全部字段 $res = Db::table('user')->field(true)->select(); //相当于select * from user,不过建议使用上面的语法 $res = Db::table('user')->field('*')->select(); //选择除了id之外的所有字段 $res = Db::table('user')->field('id',true)->select(); //注意:这里只有一个参数 $res = Db::table('user')->field('name AS n, age AS a')->select(); $res = Db::table('user')->field(['name'=> 'n', 'age'=> 'a'])->select(); $res = Db::table('user')->field(['id', 'SUM(`age`)' => 's'])->select();
order的使用
//当如果有指定desc或者asc的时候按指定的排序,如果没有指定时默认按asc进行排序 $res = Db::table('user')->field(true)->order('age desc, sex')->select(); $res = Db::table('user')->field(true)->order(['age'=>'asc', 'sex'])->select(); //当你的order排序中使用了SQL函数的时候,请使用orderRaw方法替代order $res = Db::table('user')->field(true)->orderRaw('rand()')->select();
limit与page的使用
//表示只选取10条记录 $res = Db::table('user')->field(true)->order('age desc')->limit(10)->select(); //表示偏移3条记录后再选取4条记录 $res = Db::table('user')->field(true)->order('age desc')->limit(3,4)->select(); //使用page方法进行分页 以下表示在第三页的三条,那么相当于偏移了6条记录 $res = Db::table('user')->field(true)->order('age desc')->page(3, 3)->select(); //也可以使用混合,以下表示在第二页的四条数据,那么相当于偏移了4条记录 $res = Db::table('user')->field(true)->order('age desc')->limit(4)->page(2)->select();
group与having的使用
//group可以进行分组,支持多个字段分组 $res = Db::table('user')->field(true)->group('sex,name')->having('sex=1 and age>30')->select(); //having与where的区别在于前者可以从刷选后在名称里去读取,而where只能从原有的字段中读取 $res = Db::table('user')->field(['name'=>'n', 'age'=>'a', 'sex'=>'s'])->having('s=0')->select();
子查询与join以及distinct的使用
//获取子查询的sql语句 $sub = Db::table('user')->field(['SUM(`age`)'=> 's'])->buildSql(); $sub = Db::table('user')->field(['SUM(`age`)'=> 's'])->fetchSql(true)->select(); //推荐使用以下的子查询建立方法 $sub = Db::table('user')->field(['SUM(`age`)'=> 's', 'id'])->buildSql(); //利用join进行表与表的关联操作,type里的值可以是left, right, inner, full $res = Db::table('user')->alias('u')->join([$sub => 'm'], 'm.id = u.id', 'right')->select(); //查询唯一的字段如果有两个数据的是相同的,那么就展示一个 $res = Db::table('user')->distinct(true)->field('name' )->select();
聚合函数的使用
方法 | 说明 |
---|---|
count | 统计数量,参数是要统计的字段名(可选) |
max | 获取最大值,参数是要统计的字段名(必须) |
min | 获取最小值,参数是要统计的字段名(必须) |
avg | 获取平均值,参数是要统计的字段名(必须) |
sum | 获取总分,参数是要统计的字段名(必须) |
$res = Db::table('user')->count(); $res = Db::table('user')->sum('age'); $res = Db::table('user')->avg('age'); $res = Db::table('user')->max('age'); $res = Db::table('user')->min('age');
事务性操作
Db::transaction(function(){ Db::table('think_user')->find(1); Db::table('think_user')->delete(1); }); // 启动事务 Db::startTrans(); try{ Db::table('think_user')->find(1); Db::table('think_user')->delete(1); // 提交事务 Db::commit(); } catch (Exception $e) { // 回滚事务 Db::rollback(); }
添加数据的操作
$data = [ 'name' => '林华华', 'sex' => 1, 'age' => 28, 'phone' => 15746563538 ]; $list = [ [ 'name' => '项少龙', 'sex' => 0, 'age' => 28, 'phone' => 15746563539 ], [ 'name' => '何润东', 'sex' => 0, 'age' => 28, 'phone' => 15746563543 ] ]; try{ //添加一条记录 $res = Db::table('user')->insert($data); //如果成功,那么就返回成功的记录数 $res = Db::table('user')->insertGetId($data); //如果成功,那么就返回新增的id $res = Db::table('user')->insertAll($list); //是一个数据的二维数组,返回的是成功的条数 dump(Db::table('user')->getLastInsID()); //获取最后条数据的id dump($res); }catch(Exception $e) { dump($e->getCode()); } $sql = Db::getLastSql(); dump($sql);
更改数据操作
$res = Db::table('user')->where('id', 50)->update(['name'=> '陆毅']); $res = Db::table('user')->where('id', 60)->setField('name', '刘备'); $res = Db::table('user')->where('id', 60)->setField(['name' => '张飞', 'sex'=> 0]); $res = Db::table('user')->field(true)->select(); //需要用到函数的可以使用以下方法 Db::table('think_user') ->where('id', 1) ->update([ 'login_time' => Db::raw('now()'), 'login_times' => Db::raw('login_times+1'), ]);
删除数据操作
// 根据主键删除 Db::table('think_user')->delete(1); Db::table('think_user')->delete([1,2,3]); //常用删除方法 $res = Db::table('user')->where('name', '林华华')->delete();
注意:
Db::table('user'); //是可以用db('user')来替代的 //获取最后一条的执行数据 dump(Db::getLastSql());
2、使用model类进行数据库操作
<?php namespace appindexmodel; use thinkModel; class User extends Model { //如果表名和类名一致,那么可以不定义table这个关键字,如果不一样,那么按如下进行定义 protected $table = 'user'; //如果主键id是id的情况,那么可以不定义,如果不一致,那么要进行如下配置 protected $pk = 'id'; //通用配置在database.php里的 'resultset_type' => 'array', 但是多数据查询后的结果要进行循环后才能使用,如果使用collection,那么就可以调用toArray()方法 //注意:这里是不影响Db::table('user')->field(true)->select()的结果
protected $resultSetType = 'collection'; } ?>
model的初步调用
//静态调用,查询单条记录,get里面是主键id dump(User::get(50)->toArray()); //实例化类进行调用 dump((new User())::get(50)->toArray()); //调用内部的方法 dump(model('User')::get(50)->toArray()); //利用loader类进行自动加载 dump((Loader::model('User'))::get(50)->toArray());
model里的查询的方法
//查询主键id为3的数据 $res = User::get(3)->toArray();
$res = User::get(['id' => 1, 'name' => 'abc']) //查询主键id在【1,2,3,4】里面的数据 $res = User::all([1, 2, 3, 4])->toArray(); //动态查询语句 $res = User::getByAge(48)->toArray(); $res = User::getByName('刘德华')->toArray(); $res = User::getById(1)->toArray(); //获取指定字段的值 $res = User::where('id', 3)->value('name'); $res = User::where('id', 3)->column('name'); //可以调用Db里的方法进行查询 $res = User::field(true)->order(['age'=>'desc'])->select()->toArray(); //前提是User表中的$resultSetType = 'collection';
model里的新增方法
//方法一 $data = new User(); $data->data([ 'name' => 'bill', 'age' => 32, 'sex' => 0, 'phone' => 15474655463 ]); $res = $data->save(); //方法二 $data = new User(); $data->name = 'rick'; $data->age = 38; $data->sex = 0; $data->phone = 17483902938; $res = $data->save(); //方法三 $data = new User(); $res = $data->allowField(true)->save([ //如果需要指定字段,那么需要传入数组 'name' => 'jeere', 'age' => 20, 'sex' => 0, 'phone' => 10987463524 ]);
public static function getInfo() { $data = [ 'name' => '小雷', 'age' => 30, 'sex' => '男', 'phone' => 17465546374 ]; return self::create($data); }
添加多条数据
$user = new User; $list = [ ['id'=>1, 'name'=>'thinkphp', 'email'=>'thinkphp@qq.com'], ['id'=>2, 'name'=>'onethink', 'email'=>'onethink@qq.com'], ]; $user->saveAll($list, false);
使用静态方法添加
$user = User::create([ 'name' => 'thinkphp', 'email' => 'thinkphp@qq.com' ]); echo $user->name; echo $user->email; echo $user->id; // 获取自增ID
model里的更新方法,除了可以使用Db里的方法还可以使用以下方法
$user = new User; // save方法第二个参数为更新条件 $user->save([ 'name' => 'thinkphp', 'email' => 'thinkphp@qq.com' ],['id' => 1]);
model里的删除方法,除了可以使用Db里的delete方法还可以使用以下方法
$res = User::destroy(['name'=> 'are you ok???']); dump($res);
2、获取器的使用
//在表中定义获取器前面用get+字段名+Attr传入参数$val public function getSexAttr($val) { $arr = [0 => '男', 1 => '女']; return $arr[$val]; } //那么使用Model进行调用的时候会进行自动转换 $res = User::get(60); dump($res->toArray()); //但是如果没有调用model里面的方法,而是调用Db里的方法,那么就不能进行自动转换
如果需要调用model里的原始数据
$user = User::get(1); // 通过获取器获取字段 echo $user->status; // 获取原始字段数据 echo $user->getData('status'); // 获取全部原始数据 dump($user->getData());
3、修改器的使用(修改器的触发条件是save)
//在model类中定义方法,那么在调用model类的更新储存的时候就会进行修改 public function setSexAttr($val) { if($val == '男') { return 0; } return 1; }
调用,注意这里只能用save而不能用update这个方法
$user = new User(); $res = $user->save(['name' => 'fengge', 'sex' => '男'], ['id' => 60]); dump($res); dump(Db::getLastSql());
利用model中的方法进行表的连接操作
public static function getInfo() { $sub = self::field(['SUM(age)'=>'total', 'id'])->buildSql(); $res = self::alias('u')->field(['u.id', 'name', 'age', 'sex', 's.total'])->join([$sub => 's'], 's.id = u.id', 'inner')->select(); return $res->toArray(); }
4、自动完成
数据自动完成指在不需要手动赋值的情况下对字段的值进行处理后写入数据库。
系统支持auto
、insert
和update
三个属性,可以分别在写入、新增和更新的时候进行字段的自动完成机制,auto属性自动完成包含新增和更新操作,例如我们定义User
模型类如下:
namespace appindexmodel; use thinkModel; class User extends Model { protected $auto = []; protected $insert = ['ip','status' => 1]; protected $update = ['login_ip']; protected function setIpAttr() { return request()->ip(); } }
5、简要的语法
Db::table('data') ->where('id',1) ->inc('read') //自增 ->dec('score',3) //自减 ->exp('name','UPPER(name)') ->update();