介绍
tfmodel类对于常规的CRUD操作不直接通过tfdo类实现,而是通过tfdao类的派生类组实现,tfdao类的派生类包括tfdaoSingle、tfdaoOneToOne、tfdaoManyToMany三个。
tfdaoSingle类是单数据表操作类,支持insert、update、delete方法,支持常规条件查询的方法select、selectMany、selectAll,支持通过表主键/约束进行查询的方法selectByPrimary、selectByUnique、selectByIndex、selectManyByPrimary、selectManyByUnique、selectManyByIndex、selectAllByPrimary、selectAllByUnique、selectAllByIndex,支持通过SQL的WHERE条件进行查询的方法selectByWhere、selectManyByWhere、selectAllByWhere。系统会为当前数据源对应的数据库的所有数据表进行扫描,并且为每个数据表建立对应的tfdaoSingle类,所以我们可以直接通过这些类对数据表进行CRUD操作。
tfdaoOneToOne类是一对一关联数据表操作类,支持insert、update、delete方法,支持常规条件查询的方法select,支持通过表主键/约束进行查询的方法selectByPrimary、selectByUnique、selectByIndex。使用tfdaoOneToOne类之前需要先在tfmodel类里注册并设置关联关系,使用tfdaoOneToOne类可以大幅降低一对一的多表关联CRUD操作的复杂度。
tfdaoManyToMany类是多对多关联数据表操作类,支持bind、unbind方法,支持getADataAll、getBDataAll方法。使用tfdaoManyToMany类之前需要先在tfmodel类里注册并设置关联关系,使用tfdaoManyToMany类可以大幅降低多对多的多表关联CRUD操作的复杂度。
TFPHP官方网址:https://tongfu.net/soft/63.html
TFPHP官方Github网址:https://github.com/tongfunet/tfphp
建立数据表
设置一个简单的用户管理系统,包括用户基本信息表、用户详细信息表、用户角色表、用户关注关联表。
用户基本信息表,包括用户名密码等等基本信息。
CREATE TABLE user ( uId int not null auto_increment, uName varchar(50) not null comment '登录用户名,全局唯一', uPass char(32) not null comment '登录密码,md5哈希加密', uRoleId int not null comment '关联role.rId,是用户角色', createDT timestamp not null, lastLoginDT timestamp null comment '最后登录时间', primary key(uId), UNIQUE uName(uName) );
用户详细信息表,包括用户姓名、性别、所属地区等等详细信息。
CREATE TABLE user_detail ( uId int not null comment '关联user.uId', uRealName varchar(50) null comment '用户姓名', uGender tinyint(1) null comment '用户性别,0-未设置,1-男,2-女', uDescript text null comment '用户自我介绍', primary key(uId) );
用户角色表,系统用户角色,每个用户必须从属一个角色。
CREATE TABLE role ( rId int not null auto_increment, rName varchar(50) not null comment '角色名称,全局唯一', rDescript varchar(100) null comment '角色描述', createDT timestamp not null, primary key(rId), UNIQUE rName(rName) );
用户关注关联表,这是一个中间表,用来记录用户之间互相关注的关系。
CREATE TABLE subscribe_user ( uId int not null comment '关联user.id,是用户自己的ID', subscribeUId int not null comment '关联user.id,是用户关注的其他用户ID', primary key(uId, subscribeUId) );
注册DAO对象
四张基本表不用手动注册,系统自动生成了。首先我们先注册一个fullUser一对一的tfdaoOneToOne对象,将用户基本信息表和用户详细信息表关联起来一起操作。
$this->setO2O("fullUser", ["user", "user_detail"], [
["mapping"=>["uId"=>"uId"]] // 即:user.uId==user_detail.uId
]);然后我们还要注册一个userSubscribe多对多的tfdaoManyToMany对象,将用户相互关注通过它来实现。
$this->setM2M("userSubscribe", ["user", "subscribe_user", "user"], [
["mapping"=>["uId"=>"uId"]], // 即:user.uId==subscribe_user.uId
["mapping"=>["subscribeUId"=>"uId"]] // 即:subscribe_user.subscribeUId==user.uId
]);功能实现
tfdaoSingle示例
添加三个系统角色“普通用户”,“系统用户”,“管理员”。
使用constraintSelect通过rName约束检查角色名称是否重复,不存在同名角色的时候就写入。
$tRole = $this->getSG("role");
if(!$tRole->selectByUnique(["普通用户"], "rName")){
$tRole->insert(["rName"=>"普通用户", "rDescript"=>"普通用户", "createDT"=>date("Y-m-d H:i:s")]);
}
if(!$tRole->selectByUnique(["系统用户"], "rName")){
$tRole->insert(["rName"=>"系统用户", "rDescript"=>"系统用户", "createDT"=>date("Y-m-d H:i:s")]);
}
if(!$tRole->selectByUnique(["管理员"], "rName")){
$tRole->insert(["rName"=>"管理员", "rDescript"=>"管理员", "createDT"=>date("Y-m-d H:i:s")]);
}再添加一个角色用来学习update方法和delete方法的使用技巧。
$tRole = $this->getSG("role");
if(!$tRole->selectByUnique(["测试角色"], "rName")){
$tRole->insert(["rName"=>"测试角色", "rDescript"=>"测试角色", "createDT"=>date("Y-m-d H:i:s")]);
$newRoleId = $tRole->getLastInsertAutoIncrementValue(); // 获得自增列新值
if($newRoleId){
$tRole->update(["rDescript"=>"改一下测试角色的描述"], ["rId"=>$newRoleId]); // 条件更新
$tRole->deleteByPrimary([$newRoleId]); // 主键删除
}
}tfdaoOneToOne示例
注册用户“福哥”,密码“123456”,姓名“同福”,性别“男”,描述“福哥是个程序员”。
还是先检查用户名重复,然后通过insert相继向user表、user_detail表写入数据,
$tFullUser = $this->getO2O("fullUser");
$tRole = $this->getSG("role");
$roleData = $tRole->selectByUnique(["管理员"], "rName");
if($roleData && !$tFullUser->selectByUnique(["福哥"], "uName")){
$tFullUser->insert([
"uName"=>"福哥",
"uPass"=>md5("123456"),
"uRoleId"=>$roleData["rId"],
"createDT"=>date("Y-m-d H:i:s"),
"uRealName"=>"同福",
"uGender"=>1,
"uDescript"=>"福哥是个程序员"
]);
}再注册一个用户“鬼谷子叔叔”。
$roleData = $tRole->selectByUnique(["普通用户"], "rName");
if($roleData && !$tFullUser->selectByUnique(["鬼谷子叔叔"], "uName")){
$tFullUser->insert([
"uName"=>"鬼谷子叔叔",
"uPass"=>md5("abcdef"),
"uRoleId"=>$roleData["rId"],
"createDT"=>date("Y-m-d H:i:s"),
"uRealName"=>"鬼谷子叔叔",
"uGender"=>2,
"uDescript"=>"鬼谷子叔叔也是程序员"
]);
}再注册一个用户用来学习update方法和delete方法的使用技巧。
$roleData = $tRole->selectByUnique(["普通用户"], "rName");
if($roleData && !$tFullUser->selectByUnique(["测试用户"], "uName")){
$tFullUser->insert([
"uName"=>"测试用户",
"uPass"=>md5("test"),
"uRoleId"=>$roleData["rId"],
"createDT"=>date("Y-m-d H:i:s"),
"uRealName"=>"测试用户",
"uGender"=>2,
"uDescript"=>"测试用户"
]);
$newUserId = $tFullUser->getLastInsertAutoIncrementValue(); // 获得自增列新值
if($newUserId){
$tFullUser->updateByUnique([$newUserId ], ["uDescript"=>"改一下测试角色的描述"]); // 约束更新
$tFullUser->deleteByIndex(["测试用户"]); // 索引删除。注意:这里删除的是每张关联数据表的关联记录
}
}tfdaoManyToMany示例
用“鬼谷子叔叔”关注“福哥”。
$tUser = $this->getSG("user");
$tUserSubscribe = $this->getM2M("userSubscribe");
$userGGZ = $tUser->selectByUnique(["uName"=>"鬼谷子叔叔"], "uName");
$userFG = $tUser->selectByUnique(["uName"=>"福哥"], "uName");
if($userGGZ && $userFG){
$tUserSubscribe->bind([$userGGZ], [$userFG]);
}可以通过unbind方法进行取消关注。
$tUserSubscribe = $this->getM2M("userSubscribe");
if($userGGZ && $userFG){
$tUserSubscribe->unbind([["uId"=>$userGGZId]], [["uId"=>$userFGId]]);
}还可以用replace方法进行彻底地替换更新,与bind方法的区别是replace方法会清除当前绑定操作设置的关联之外的所有关联数据。比如:一篇博客打了5个标签,使用bind方法打第6个标签结果一共有6个标签,使用replace打第6个标签结果就只有1个标签,其他的被清除了。