一、数据库的操作#
1、配置数据库
在applicable里的database.php文件里面进行配置
配置一个数据库和配置多个数据库,
但是不知道我的多个数据库配置会出问题,这个到学校再去进行检查
2、thinkphp5对数据库的基本使用
查
Db::query('select * from think_user where id=?',[8]);
Db::query('select * from think_user where id=:id',['id'=>8]);
###执行其它语句###
Db::execute(‘insert into think_user (id, name) values (?, ?)’,[8,‘thinkphp’]);
Db::execute(‘insert into think_user (id, name) values (:id, :name)’,[‘id’=>8,‘name’=>‘thinkphp’]);
使用多个数据库连接
Db::connect($config)->query('select * from think_user where id=:id',['id'=>8]);//$config是连接数据库的配置
使用构造器来进行查询
第一种:
Db::table('数据库全名')->where('id',2)->update(['name'=>"hello"]);//更新数据
Db::table('数据库全名')->where(条件)->select;//查
第二种:
Db::name('去掉前缀的数据库名,去配置文件中找数据库前缀')->insert(['id'=>18,'name'=>'thinkphp']);//建议使用这种方便管理数据库前缀
链式操作:
$list = Db::name(去掉前缀的数据库名)->where(条件)->field(查找的列)->limit(10)->select();
3、事务
事务是访问并可能更新数据库中各种数据项的一个程序执行单元,不可再分
、
手动控制事务
// 启动事务
Db::startTrans();
try{
Db::table('think_user')->find(1);
Db::table('think_user')->delete(1);
// 提交事务
Db::commit();
} catch (\Exception $e) {
// 回滚事务
Db::rollback();
}//注意在事务操作的时候,确保你的数据库连接是相同的
二、模型和关联
thinkphp5中的模型是重写Model的initialize
- 第一步,在application里面创立一个model文件夹
- 第二部,在model中创建跟数据库中表名相同名的php文件
- 第三步,文件中的内容如下
- namespace app\index\model;
- use think\Model;
- class 表名 extends Model
- {
- 内容可以为空
- }
在控制器中使用要实例化一个对象,在进行操作,如下所示
##新增##
单个
$user = new User;
$user->name = 'think';
$user->email = '12345678914@qq.com'
$user->save();
多个
$user = new User;//实例一个模型对象
$user->data([
'name'=>'thinkphp',
'email'=>'12345674@qq.com'
]);//利用data进行批量操作
$user->save();
如果是那种新增多个数据,记得要使用
$user->insUpdate(false)->save()
也可以使用
$list = [
['id'=>1, 'name'=>'thinkphp', 'email'=>'thinkphp@qq.com'],
['id'=>2, 'name'=>'onethink', 'email'=>'onethink@qq.com'],
];
$user->saveAll($list);
//在使用saveAll方法新增数据默认会自动识别数据是需要新增还是更新操作,
当数据中存在主键的时候会认为是更新操作,
如果你需要带主键数据批量新增,可以使用下面的方式:
$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::get(主键号);//先进性提取出数据
$user->name = 'thinkphp';
$user->email = 'thinkphp@qq.com';//进行相对性的修改
$user->save();//写入数据
方法二、直接更新
$user = new User;
// save方法第二个参数为更新条件
$user->save([
'name' => 'thinkphp',
'email' => 'thinkphp@qq.com'
],['id' => 1]);
上面两种方式更新数据,如果需要过滤非数据表字段的数据,可以使用:
$user = new User();
// 过滤post数组中的非数据表字段数据
$user->allowField(true)->save($_POST,['id' => 1]);
批量更新
$user = new User;
$list = [
['id'=>1, 'name'=>'thinkphp', 'email'=>'thinkphp@qq.com'],
['id'=>2, 'name'=>'onethink', 'email'=>'onethink@qq.com']
];
$user->saveAll($list);
也可以使用:
$user->isUpdate()->saveAll($list);
还可以直接利用数据库类更新数据
$user = new User;
$user->where('id', 1)->update(['name' => 'thinkphp']);
或者使用:
$user = new User;
$user->update(['id' => 1, 'name' => 'thinkphp']);
查询
利用模型查询数据除了之前写的那种,还有取出多个数据:
$list = User::all('多个主键');
$list = User::all([1,2,3]);//使用数组
$list = User::all(['status'=>1]);//使用数组
//使用闭包查询
$list = User::all(function($query){
$query->where('status',1)->limit(3)->order('id',asc)
});
删除
$user = Users::get(主键);
$user->delete();
//或者使用
Users::destroy(主键);
条件删除
使用数组进行条件删除
$user::destroy(['status'=>0]);
使用闭包删除
User::destroy(function($query){
$query->where('id','>',10);
});
还可以使用数据库类查询条件删除
User::where('id','>',10)->delete();
三、类型和自动完成
读取器
获取器定义在模型类里面,它的作用是在获取数据的字段值后自动进行处理
方法名的规则:get+数据库中的列名+Attr(参数)
例如:
protected function setSnameAttr($name){
return "王".$name;
}
在控制器中调用 echo $user->sname;
会显示 王+sname数据
修改器
获取器定义也在模型类里面,作用是可以在给数据库写入数据是自动处理数据
方法名的规则:set+数据库中的列名+Attr(参数)
例如:
public function setSnameAttr($name)
{
return '王'.$naem;
}
在控制器中调用 $user->sname='叉叉';
会自动处理成王叉叉输入到数据库里
类型转换
在数据模型中设置,
例如User表中有status,score,birthday,info几个字段
class User extends Model{
protexted $type = [
'status' => 'integer',
'score' => 'float',
'birthday=> 'datetime',
'info' => 'array,
];
}
- integer设置为integer(整型)后,该字段写入和输出的时候都会自动转换为整型。
- float该字段的值写入和输出的时候自动转换为浮点型。
- boolean该字段的值写入和输出的时候自动转换为布尔型。
- array如果设置为强制转换为array类型,系统会自动把数组编码为json格式字符串写入数据库,取出来的时候会自动解码。
- object该字段的值在写入的时候会自动编码为json字符串,输出的时候会自动转换为stdclass对象。
- serialize指定为序列化类型的话,数据会自动序列化写入,并且在读取的时候自动反序列化。
- json指定为json类型的话,数据会自动json_encode写入,并且在读取的时候自动json_decode处理。
- timestamp指定为时间戳字段类型的话,该字段的值在写入时候会自动使用strtotime生成对应的时间戳,输出的时候会自动转换为dateFormat属性定义的时间字符串格式,默认的格式为Y-m-d H:i:s,.
timestamp如果希望改变其他格式如下
class User extends Model
{
protected $type = [
'status' => 'integer',
'score' => 'float',
'birthday' => 'timestamp:Y/m/d',
];
}
四、查询范围
也是定义在数据模型里面的
查询命名格式scope+自己命名(参数)
例如:
namespace app\index\model;
use think\Model;
class User extends Model{
protected function scopethinkphp($query){
$query->where('name','thinkphp')->field('id','name');
}
}
在控制函数里面调用如下:
User::scope('thinkphp')->find();
或者直接在控制器里面写:
User::scope(function($query){
$query->where('age','>',20)->limit(10);
})->select();
五、输入和验证
验证器:在application\index(或者其它定义的)\validate里面创立一个更表名一样的文件
<?php
namespace app\index\validate;
use think\Validate;
class S extends Validate
{
//验证规则
protected $rule=[
['sex','regex:.{1,3}','性别错误'],//利用正则
['sno','checkSno:2012'],//自定义的验证
];
//自定义的验证
protected function checkSno($value,$rule){
$result = strstr($value,$rule);
if($result)
return true;
else return "学号错误,前面应为学号".$rule;
}
//验证构造器
public function add(){
$data = input('post.');
$result = Validate::is($data['sex'],'\d{1}');
if(true !== $result){
return $result;
echo '2';
}else{
echo '1';
}
$S = S;
$S->allowField(true)->save($data);
return $S->sname;
}
}
还可以使用这种
class User extends Validate
{
protected $rule = [
'name' => 'require|max:25',
'age' => 'number|between:1,120',
'email' => 'email',
];
protected $message = [
'name.require' => '名称必须',
'name.max' => '名称最多不能超过25个字符',
'age.number' => '年龄必须是数字',
'age.between' => '年龄只能在1-120之间',
'email' => '邮箱格式错误',
];
}
在控制器中使用
//验证规则和自定义验证
public function test(){
$s = new S;
$c=input('post.');
if($s->allowField(true)->validate(true)->save($c)){
echo "成功";
}else{
return $s->getError();
}
}
//input('post'.)他会自动获取表单中post传输的数据
//allowField(true)自动过滤掉数据表中没有的字段
//validate(true)自动进行验证
//save($c)如果验证成功,他会自动生成$c语句写入数据库
验证构造器
public function test2(){
$data = input('post.');
$result = $this->Validate($data,'S');
if($result!==true){
echo '2';
return $result;
}else{
echo '1';
}
$S =new S;
$S->allowField(true)->save($data);
return $S->sname;
}
六、关联
再本模块中定义好,并且指定和其它模块之间的关系,再到控制器里用使用调用属性的方法来调用两个模块之间的关系函数;并可以进行输出
一对一
HAS_ONE以及相对的BELONGS_TO
###第一步、定义关系###
在数据模型User中定义关系的方法
public function comm()
{
//用户HAS ONE档案关联
return $this->hasOne('Car','uid','user_id');
//Car为要关系的表名,‘uid’和‘user_id’是两个表之间联系的id号
}
在控制其中调用
$user = User::get('1');
echo $user->comm;//这个是user和car进行关联
新增数据
$User = new User;//实例化一个User对象
$user->name='小六';
if($user->save()){
$car->content = ‘这是一个test’;//给car赋值
$user->comm()->save($car);//调用user模块里的表关系函数连接起来
}
关联删除
$user = User::get(1);
if($user->delete()){
//删除关联数据
$user->comm->delete();
}
一对多
第一步、定义关系
HAS_MANY以及相对的BELONGS_TO
public function comm()
{
//用户HAS MANY档案关联
return $this->hasMany('Car','uid','user_id');
//Car为要关系的表名,‘uid’和‘user_id’是两个表之间联系的id号
}
新增数据
$user = User::get(1);//查询user中id=1的数据
$car = new Car;//实例化一个Car对象
$car->content = ‘这是一个test’;//给car赋值
$user->comm()->save($comment);//调用user模块里的表关系函数连接起来
关联查询
$user = User::get(1);
$com = $user->comm;//这个事先把user表中id=1的查询出来,在通过user->comm来进行联合查询
//还可以
User::get(1,'com');//这个事直两张表进行联合查询
过滤查询
$user = User::get(1);
$comment = $user->comm()->where('is_show',1)->select();//进行条件查询
//或者
$comm = $user->comm()->getByContent('这是一个测试');
//这个会直接去user表查询content="这是一个测试",然后进行联合查询
更新
$user = User::get(1);
$comm = $user->comm()->getByContent('这是一个测试');//先查找出来
$comm->content = '那个也事一个';//然后进行更新
//查询构造器的update方法进行更新
$user = user::get(1);
$user->comm()->where('content','这是一个测试')->update(['content'=>'那个也是']);
删除
删除部分关联数据
$user = user::get(1);
$comm = $user->comm()->getByContent('这是一个测试');
$comm->delete();//删除content=’这是一个测试‘的数据
删除所有关联数据
$user = user::geet(1);
$user->comm()->delete();//删除所有关联的数据
多对多
BELONGS_TO_MANY
public function comm()
{
//用户BELONGS_TO_MANY档案关联
//belongsToMany('关联模型','中间表名','外键名','当前外键名')
return $this->belongsToMany('Car','link','uid','user_id');
//Car为要关系的表名,‘uid’和‘user_id’是两个表之间联系的id号
}