Swoole微服务框架Swoft之ORM

原创
2017/09/19 20:36
阅读数 1.3W

Swoft

Swoft是基于swoole协程的高性能PHP微服务框架,Swoft宗旨是打造一款简单、快速、高效的框架。项目开源地址:https://github.com/swoft-cloud/swoft

ORM

ORM用于实现面向对象编程语言里不同类型系统的数据之间的转换,ORM有多种设计模式,swoft采用的是data mapper,业务和实体分开,但是也实现了类似ActiveRecord的操作方式,其实都是同一个实现的。

数据库操作分为两种基础(ActiveRecord)和高级的(data mapper),基础的用于快速开发和常见的查询操作,高级的用于事务和一些复杂的业务查询。

查询器语法

方法 功能
insert 指定插入表
update 指向更新的表
delete 删除语句
select 查询字段
selects 查询多个字段
from 指定删除和查询的表
innerJoin 内连接
leftJoin 左连接
rightJoin 右连接
where where条件语句
andWhere where and 条件语句
openWhere where 里面左括号
closeWhere where 里面右括号
orWhere where or 条件语句
whereIn where in语句
whereNotIn where not in 语句
whereBetween where between and 语句
whereNotBetween where not between and语句
having having语句
andHaving having and语句
orHaving having or语句
havingIn having in语句
havingNotIn having not in语句
havingBetween having between and语句
havingNotBetween havin not between and 语句
openHaving having括号开始语句
closeHaving having括号结束语句
groupBy group by语句
orderBy order by语句
limit limit语句
set 设置更新值
setParameter 设置参数
setParameters 设置多个参数
getSql 获取执行语句

 

实体定义

一个表和一个类是一一映射的,对类的操作相当于对表的操作,该类称为一个实体。实体定义规则如下:

  1. 必须使用@Entity注解标明这是一个实体
  2. 必须使用@Table命令指定映射的表名
  3. 必须使用@column指定表映射字段,没有定义的属性,不映射。
  4. 其中一个属性必须使用@Id注解标明主键
  5. 所有属性必须有getter和setter方法
  6. 属性默认值即是表字段默认值。
  7. 若需使用基础查询,必须基础Model类
/**
 * 用户实体
 *
 * @Entity()
 * @Table(name="user")
 * @uses      User
 * @version   2017年08月23日
 * @author    stelin <phpcrazy@126.com>
 * @copyright Copyright 2010-2016 Swoft software
 * @license   PHP Version 7.x {@link http://www.php.net/license/3_0.txt}
 */
class User extends Model
{
    /**
     * 主键ID
     *
     * @Id()
     * @Column(name="id", type=Types::INT)
     * @var int
     */
    private $id;

    /**
     * 名称
     *
     * @Column(name="name", type=Types::STRING, length=20)
     * @Required()
     * @var string
     */
    private $name;


    /**
     * 年龄
     *
     * @Column(name="age", type=Types::INT)
     * @var int
     */
    private $age = 0;

    /**
     * 性别
     *
     * @Column(name="sex", type="int")
     * @Enum(value={1,0})
     * @var int
     */
    private $sex = 0;


    /**
     * 描述
     *
     * @Column(name="description", type="string")
     * @var string
     */
    private $desc = "";


    //getter and setter methods
    // ...
}

注解解析

目前只实现了几个注解,若需其它验证注解比如邮、URI、手机等,可自行实现。

@Column

此注解用于定义类属性和表字段的关系,如果没有使用,默认属性的名称对应表字段名称,定义的字段类型对应数据库字段类型。注解有三个参数可以使用

  1. name定义映射的数据库字段名称
  2. type定义映射的数据库字段类型
  3. length定义字符串最大长度

@Enum

此注解是枚举类型注解,定义该字段只能是枚举数组里面的其中一个值,使用如上demo

@Id

数据表映射主键ID

@Required

属性字段必须传值

基础查询

swoft提供一套基础查询,类ActiveRecord方法,方便快捷的实现数据库操作,但是实体必须继承Model类,且不能使用事务,如需使用事务,请使用高级查询。基础查询提供延迟收包和非延迟收包两种方式,非延迟收包一般用于并发使用。

新增

$user = new User();
$user->setName("stelin");
$user->setSex(1);
$user->setDesc("this my desc");
$user->setAge(mt_rand(1, 100));

// 直接返回结果
//$result = $user->save();

// 延迟操作
$dataResult = $user->save(true);
$deferResult = $dataResult->getResult();

删除

实体删除

$user = new User();
$user->setAge(126);

// 直接返回结果
// $result = $user->delete();

// 延迟操作
$defer = $user->delete(true);
$result = $defer->getResult();

ID删除

// 直接返回结果
// $result = User::deleteById(284);

// 延迟操作
$deferResult = User::deleteById(287, true);
$result = $deferResult->getResult();

IDS删除

// 直接返回结果
// $result = User::deleteByIds([291, 292]);

// 延迟操作
$deferResult = User::deleteByIds([288, 289], true);
$result = $deferResult->getResult();

更新

$query = User::findById(285);

/* @var User $user */
$user = $query->getResult(User::class);
$user->setName("upateNameUser2");
$user->setSex(0);

// 直接返回结果
$result = $user->update();

// 延迟操作
//$result = $user->update(true);
//$result = $result->getResult();

查询

实体查询

$user = new User();
$user->setSex(1);
$user->setAge(93);
$query = $user->find();

// 直接返回数组结果
// $result = $query->getResult();

// 直接返回User实体对象结果
/* @var User $userResult */
// $userResult = $query->getResult(User::class);

// 延迟操作处理
$defer = $query->getDefer();
// $result = $defer->getResult();

$result = $defer->getResult(User::class);

// sql语句
$ql = $query->getSql();
var_dump($result);

ID查询

$query = User::findById(236);

// 直接返回数组结果
$result = $query->getResult();

// 直接返回User实体对象结果
/* @var User $userObject */
$userObject = $query->getResult(User::class);

$query = User::findById(238);

// 延迟操作处理
//$deferResult = $query->getDefer()->getResult();

/* @var User $deferResult */
$deferResult = $query->getDefer()->getResult(User::class);

IDS查询

$query = User::findByIds([416, 417]);
$sql = $query->getSql();

// 延迟操作处理
// $defer = $query->getDefer();
// $result = $defer->getResult(User::class);

// 直接返回数组结果
$result = $query->getResult();

查询器

// $query = User::query()->select('*')->andWhere('sex', 1)->orderBy('id',QueryBuilder::ORDER_BY_DESC)->limit(3);
//$query = User::query()->selects(['id', 'sex' => 'sex2'])->andWhere('sex', 1)->orderBy('id',QueryBuilder::ORDER_BY_DESC)->limit(3);
$query = User::query()->selects(['id', 'sex' => 'sex2'])->leftJoin(Count::class, 'count.uid=user.id')->andWhere('id', 416)
    ->orderBy('user.id', QueryBuilder::ORDER_BY_DESC)->limit(2);

// 延迟操作处理    
// $result = $query->getResult();

// 直接返回数组结果
$defer = $query->getDefer();
$result = $defer->getResult();

并发查询

// getDefer方法延迟收包结果
$query1 = User::query()->selects(['id', 'sex' => 'sex2'])->leftJoin(Count::class, 'count.uid=user.id')->andWhere('id', 419)
    ->orderBy('user.id', QueryBuilder::ORDER_BY_DESC)->limit(2)->getDefer();

// getDefer方法延迟收包结果
$query2 = User::query()->select("*")->leftJoin(Count::class, 'count.uid=user.id')->andWhere('id', 420)
    ->orderBy('user.id', QueryBuilder::ORDER_BY_DESC)->limit(2)->getDefer();

// 同时接受数据
$result1 = $query1->getResult();
$result2 = $query2->getResult();

 

高级查询

高级查询可以事务事务和执行原生SQL语句,同一个实体管理器使用同一个数据库连接。使用基本上基础的查询差不多。

EntityManager::create()创建一个实体管理,默认是从节点,不存在从节点,使用主节点

实体管理器使用完,一定要关闭,否则无法释放连接

新增

$user = new User();
$user->setName("stelin");
$user->setSex(1);
$user->setDesc("this my desc");
$user->setAge(mt_rand(1, 100));

$em = EntityManager::create(true);
//        $result = $em->save($user);
$defer = $em->save($user, true);
$result = $defer->getResult();
$em->close();

删除

实体删除

$user = new User();
$user->setId(418);

$em = EntityManager::create(true);
//        $result = $em->delete($user);
$result = $em->delete($user, true);
$em->close();

ID删除

$em = EntityManager::create(true);
//        $result = $em->deleteById(Count::class, 396);
$result = $em->deleteById(Count::class, 406, true);
$em->close();

IDS删除

$em = EntityManager::create(true);
//        $result = $em->deleteByIds(Count::class, [409, 410]);
$result = $em->deleteByIds(Count::class, [411, 412], true);
$em->close();

更新

// 更是操作略有不同
$em = EntityManager::create();
$query = $em->createQuery()->update(User::class)->set('name', 'new name')->set('age', 12)->where('id', 12);
$result = $query->getResult();
$em->close();

查询

实体查询

$user = new User();
$user->setSex(1);
$em = EntityManager::create();
$query = $em->find($user);
//        $result = $query->getResult();
//        $result = $query->getResult(User::class);
//        $result = $query->getDefer()->getResult();
$result = $query->getDefer()->getResult(User::class);
$sql = $query->getSql();
$em->close();

ID查询

$em = EntityManager::create();
$query = $em->findById(User::class, 396);
//        $result = $query->getResult();
//        $result = $query->getResult(User::class);
$result = $query->getDefer()->getResult();
$sql = $query->getSql();
$em->close();

IDS查询

$query = User::findByIds([416, 417]);

$sql = $query->getSql();

//        $defer = $query->getDefer();
//        $result = $defer->getResult(User::class);

$result = $query->getResult();

查询器

// 查询器查询
$em = EntityManager::create();
$query = $em->createQuery();
$query->select("*")->from(User::class, 'u')->leftJoin(Count::class, ['u.id=c.uid'], 'c')->whereIn('u.id', [419, 420, 421])
    ->orderBy('u.id', QueryBuilder::ORDER_BY_DESC)->limit(2);
//        $result = $query->getResult();
$result = $query->getDefer()->getResult();
$sql = $query->getSql();
$em->close();


// sql查询
$params = [
    ['uid', 419],
    ['uid2', 420],
    ['uid3', 421, Types::INT],
];
$em = EntityManager::create();

// ':'方式传递参数
$querySql = "SELECT * FROM user AS u LEFT JOIN count AS c ON u.id=c.uid WHERE u.id IN (:uid, :uid1, :uid3) ORDER BY u.id DESC LIMIT 2";
$query = $em->createQuery($querySql);

// 单个设置参数
// $query->setParameter('uid', 419);
// $query->setParameter('uid2', 420);
// $query->setParameter('uid3', 421);

// 数组方式指定参数
$query->setParameters($params);

// '?'方式传递参数
// $querySql = "SELECT * FROM user AS u LEFT JOIN count AS c ON u.id=c.uid WHERE u.id IN (?1, ?2, ?3) ORDER BY u.id DESC LIMIT 2";
// $query = $em->createQuery($querySql);
// $query->setParameter(1, 419);
// $query->setParameter(2, 420);
// $query->setParameter(3, 421);

$result = $query->getResult();
$sql = $query->getSql();
$em->close();

事务

$user = new User();
$user->setName("stelin");
$user->setSex(1);
$user->setDesc("this my desc");
$user->setAge(mt_rand(1, 100));

$count = new Count();
$count->setFans(mt_rand(1, 1000));
$count->setFollows(mt_rand(1, 1000));

$em = EntityManager::create();
$em->beginTransaction();
$uid = $em->save($user);
$count->setUid($uid);

$result = $em->save($count);
if ($result === false) {
    $em->rollback();
} else {
    $em->commit();
}
$em->close();

 

展开阅读全文
打赏
3
10 收藏
分享
加载中
stelin博主

引用来自“Stelin”的评论

@红薯 之前就放到码云的 https://gitee.com/mirrors/swoft

引用来自“红薯”的评论

这个不是你自己创建的,你创建个新的,我们来修改地址:)

引用来自“Stelin”的评论

@红薯 已经建好了,地址 https://gitee.com/stelin/swoft

引用来自“红薯”的评论

搞定已推荐 ,请看 https://gitee.com/explore/recommend
谢谢支持。后续会努力完善,做得更好。
2017/09/20 09:56
回复
举报

引用来自“Stelin”的评论

@红薯 之前就放到码云的 https://gitee.com/mirrors/swoft

引用来自“红薯”的评论

这个不是你自己创建的,你创建个新的,我们来修改地址:)

引用来自“Stelin”的评论

@红薯 已经建好了,地址 https://gitee.com/stelin/swoft
搞定已推荐 ,请看 https://gitee.com/explore/recommend
2017/09/20 09:55
回复
举报
stelin博主

引用来自“Stelin”的评论

@红薯 之前就放到码云的 https://gitee.com/mirrors/swoft

引用来自“红薯”的评论

这个不是你自己创建的,你创建个新的,我们来修改地址:)
@红薯 已经建好了,地址 https://gitee.com/stelin/swoft
2017/09/20 09:40
回复
举报

引用来自“Stelin”的评论

@红薯 之前就放到码云的 https://gitee.com/mirrors/swoft
这个不是你自己创建的,你创建个新的,我们来修改地址:)
2017/09/20 09:25
回复
举报
stelin博主
@红薯 之前就放到码云的 https://gitee.com/mirrors/swoft
2017/09/20 09:11
回复
举报
代码托管到码云 gitee.com 呗,我们推荐一下。另外邀请参加本周六成都源创会
https://www.oschina.net/event/2264168
2017/09/20 08:21
回复
举报
更多评论
打赏
6 评论
10 收藏
3
分享
返回顶部
顶部