xiaolingzi's blog

每天都在成长...

欢迎您:亲

PHP ORM框架LingORM介绍及使用文档

xiaolingzi 发表于 2017-03-15 15:55:51

LingORM是为php编写的ORM框架,支持插入修改删除等基本ORM功能,也支持一般复杂的查询(比如复杂条件下的联表查询)。除此,也支持原生sql查询以应对更加复杂的情况。


一、框架的引入

框架采用了命名空间和类自动加载,所以框架的引入也比较简单,如果项目中已有自动加载类文件,在自动加载类文件中引用框架的自动加载类即可,框架的自动加载类在AutoLoader目录下的AutoLoader.php文件。如果没有自动加载类的需要在入口执行文件的头部引入该文件即可。

GitHub地址:https://github.com/xiaolingzi/PHP-ORM-LingORM


二、数据库配置

数据库采用json格式进行配置,内容格式如下:

{
    "testdb1":{
        "host":"192.168.0.22",
        "user":"db_user",
        "password":"password",
        "database":"dbname1",
        "charset":"utf8",
        "driver":"pdo_mysql"
    },
    "testdb2":{
        "host":"192.168.0.22",
        "user":"db_user",
        "password":"password",
        "database":"dbname2",
        "charset":"utf8",
        "driver":"pdo_mysql"
    },
    "testdb3":{
        "driver":"pdo_mysql",
        "database":"dbname3",
        "charset":"utf8",
        "user":"db_user",
        "password":"password",
        "servers":[
        {
            "host":"192.168.0.110",
            "mode":"w",
            "w_weight":3
        },
        {
            "host":"192.168.0.111",
            "mode":"rw",
            "w_weight":1,
            "weight":1
        },
        {
            "host":"192.168.0.112",
            "mode":"r",
            "weight":3
        },
        {
            "host":"192.168.0.113",
            "user":"db_user",
            "password":"password",
            "database":"dbname113",
            "charset":"utf8",
            "mode":"r",
            "weight":2
        }]
    }
}

1. 单台数据库服务器

单台的配置如testdb1和testdb2那样

2. 集群

一读多写、多读多写的情况配置如testdb3那样,将host属性改为servers属性,servers里面配置每个数据库信息:

1)读写配置通过mode属性,r为只读,w为只写,rw为读写

2)数据库名称、用户密码、编码等配置可以继承父节点配置,也可以自定义

3)多台配置通过权重随机的算法来决定连接那台服务器,读权重属性为weight、写权重的属性为w_weight

3.配置文件路径

然后修改LingORM根目录的Config.php文件,设置配置文件的路径。文件内容如下:

<?php
namespace LingORM;
                               
class Config
{
    const DEFAULT_DATABASE_SERVER="testdb1";
                                   
    static public function getDatabaseConfigPath()
    {
        return dirname(dirname(ROOT_PATH)).'/config/'.ENVIRONMENT.'/database_config.json';
    }
}

(1) 修改DEFAULT_DATABASE_SERVER的值,设置默认使用的数据库连接

(2) 修改getDatabaseConfigPath方法返回实际数据库配置文件路径


三、实体类

1.实例及说明如下:

<?php
namespace Lib\Entity\Test;
                               
/**
 * @Table (name="test",database="love")
 */
class TestEntity
{
    /**
     * @Column (name="testId", type="int", isGenerated=1, primaryKey=1)
     */
    public $testId;
                                   
    /**
     * @Column (name="testName", type="string", length="50")
     */
    public $testName;
                                   
    /**
     * @Column (type="datetime")
     */
    public $testTime;
                                   
}

实体类包含了类和表、属性和表字段之间的映射关系,通过注释中的@Table和@Column参数来表示。

其中@Table的参数如下:

(1) name 表示该实体类对应的表名。可选,如没有该参数,则默认以类名作为表名。

(2) database 表示表所在数据库。可选,如没有该参数,则使用查询是提供的配置或者默认配置中的数据库作为该表的数据库。

@Column参数如下:

(1) name 表示该属性对应的表字段。可选,如没有该参数则默认以该属性名作为字段名。

(2) type 字段类型。可选,默认为string。参数值主要有int,string,float,double,datetime。

(3) isGenerated 字段值是否数据库自动生成。可选,默认为0。如果该值设置为1在插入的时候就不会使用该字段。

(4) primaryKey 是否主键。可选,默认为0.对实体进行删除更新时会使用这些字段作为条件。

(5) length 字段长度。可选,改参数只对string字段使用。

2.实体类的生成

运行Tools目录下的MysqlEntityGenerator.php文件可以将mysql的表生成对应的实体类,使用前需要将里面getConnection方法中的数据库连接改为实际的和将模板命名空间改为实际的。运行命令如下:

php {实际目录}/LingORM/Tools/MysqlEntityGenerator.php -d [database] -t [table] -f [diretory]

(1) -d 数据库名。必填。

(2) -t 表名。可选,如没有该参数则默认生成指定数据库中的所有表。

(3) -f 存储的目录。 可选,如果没有则存储在当前目录下的entity目录中。


四、基本功能

在介绍基本功能之前先简单说一下where条件和order条件的构建,因为接下来的功能会用到,大家在这里先有个概念,也不用太纠结于此。跟踪后面的示例一起看会更明白。

where条件构建:

$query = new Query("testdb1");
                                        
$testTable = $query->createTable($testTable = new TestEntity());
                                
$where = $query->createWhere();
$where->setOr(
        $testTable->testId->lt(2),$testTable->testId->gt(3)
);

通过createWhere方法构建一个where对象,where对象有setOr和setAnd两个方法对应于sql语句中的or和and,方法支持不定量参数,多个参数条件会用or或者and拼接起来,只传一个参数则没有拼接。如上面的示例其实就等于

testId<=2 or testId>3

复杂条件可以通过嵌套完成,如下:

$where->setOr(
        $testTable->testId->lt(2),
        $where->getAnd($testTable->testId->gt(3),$testTable->testTime->lt("2017-01-01 00:00:00"))
);

其中

(1)$query是ORM目录下Query.php文件中Query类的实例,他是所有功能的入口,该类的构造方法接收一个可选参数$key,就是上面数据库配置中的testdb1和testdb2,表示查询使用的数据库连接,如果该参数没有则采用Config文件DEFAULT_DATABASE_SERVER指定的默认连接。

(2)$testTable是要查询的表对象,通过createTable方法构建,一个必填参数是实体实例,第二个参数是查询改表时的别名,该参数可选,不填系统会自动生成一个别名。

(3)条件中属性的比较运算符有如下:

gt 大于。如例子中的$testTable->testId->gt(3)

ge 大于等于

lt 小于

le 小于等于

eq 等于

neq 不等于

like 模糊匹配

in 对应sql中的in

nin 对应sql中的not in

order条件构建:

$query = new Query("testdb1");
$testTable = $query->createTable($testTable = new TestEntity());
$order=$query->createOrder()
    ->orderBy($testTable->testId, "desc")
    ->orderBy($testTable->testName, "asc");

如上例,order by的条件构建就想到简单,通过createOrder创建order对象,并调用它的orderBy方法设置排序字段即可。

1.单条查询

$query = new Query("testdb1");
$testTable = $query->createTable($testTable = new TestEntity());
$where = $query->createWhere();
$where->setOr(
        $testTable->testId->lt(2),$testTable->testId->gt(3)
    );
$order=$query->createOrder()
    ->orderBy($testTable->testId, "desc")
    ->orderBy($testTable->testName, "asc");
                                
$result = $query->createQuery()->fetchOne($testTable, $where, $order);

其中fetchOne方法中的$order参数可选。

2.多条查询

$query = new Query("testdb1");
$testTable = $query->createTable($testTable = new TestEntity());
$where = $query->createWhere();
$where->setOr(
        $testTable->testId->lt(2),$testTable->testId->gt(3)
);
$order=$query->createOrder()
    ->orderBy($testTable->testId, "desc")
    ->orderBy($testTable->testName, "asc");
                                
$result = $query->createQuery()->fetchAll($testTable, $where, $order);

fetchAll方法中的$order参数也是可选。

3.单条插入

$entity = new TestEntity();
$entity->testName = "my name";
$entity->testTime = "2016-09-01";
                                
$query = new Query("testdb1");
$query->createQuery()->insert($entity);

4.批量插入

$entityArr = array();
for($i = 0; $i < 2; $i ++)
{
    $entity = new TestEntity();
    $entity->testName = "my name " . $i;
    $entity->testTime = "2016-09-01";
    array_push($entityArr, $entity);
}
                                
$query = new Query("testdb1");
$query->createQuery()->batchInsert($entityArr);

5.单条更新

$entity = $this->getEntity();
//$entity = new TestEntity();
//$entity->testId = 1;
$entity->testName = "my name first1";
$entity->testTime = "2016-09-01";
                                
$query = new Query("testdb1");
$result = $query->createQuery()->update($entity);

update函数有两个参数,第一个参数是要更新的实体,第二参数为可选参数,默认为false,设置为true可以在更新时忽略null的值,即null值不进行更新。

6.批量更新

$entityArr = array();
for($i = 4; $i < 6; $i ++)
{
    $entity = new TestEntity();
    $entity->testId = $i;
    $entity->testName = "my name " . $i;
    $entity->testTime = "2016-09-01";
    array_push($entityArr, $entity);
}
                                
$query = new Query("testdb1");
$query->createQuery()->batchUpdate($entityArr);

批量更新多数时候是从数据库读取列表在更新,这里随便模拟一下数据而已。update函数有两个参数,第一个参数是要更新的实体,第二参数为可选参数,默认为false,设置为true可以在更新时忽略null的值,即null值不进行更新

7.条件更新

$query = new Query("testdb1");
$testTable = $query->createTable($testTable = new TestEntity());
$where = $query->createWhere();
$where->or_(
        $testTable->testId->eq(3)
);
//更新字段
$setParamArr=array(
            $testTable->testName->eq("new name"),
            $testTable->testName->eq("2016-09-02")
        );
                                        
$result = $query->createQuery()->updateBy($table, $setParamArr, $where);

8.单条删除

$entity = new TestEntity();
$entity->testId = 5;
                               
$query = new Query("testdb1");
$query->createQuery()->delete($entity);

9.条件删除

$query = new Query("testdb1");
$testTable = $query->createTable($testTable = new TestEntity());
$where = $query->createWhere();
$where->setOr(
        $testTable->testId->eq(3)
);
$result = $query->createQuery()->deleteBy($testTable, $where);


五、复杂查询

1.单表查询

复杂查询通过Query中的createQueryBuilder创建的查询构造器进行,如下例:

$query = new Query("testdb1");
$testTable = $query->createTable($testTable = new TestEntity());
$where = $query->createWhere();
$where->setOr(
        $testTable->testId->lt(2),$testTable->testId->gt(3)
);
                                
$queryBuilder = $query->createQueryBuilder();
$queryBuilder->select($testTable->testId->count()->alias("num"),$testTable,$testTable->testTime)
    ->from($testTable)
    ->where($where)
    ->orderBy($testTable->testId, "desc");
$result = $queryBuilder->getResult();

这里需要注意的是,where的参数还是通过where构造器创建,而order by则直接调用orderBy方法,多个排序字段调用多次即可。

select的字段支持count、sum、distinct和alias,如:

$testTable->testId->count()->alias("num")

转为sql为

count(testId) as num

由如

$testTable->testId->distinct()

转为sql为

distinct testId

2.联表查询

看下面示例:

$query = new Query("testdb1");
                                
$testTable1=$query->createTable($testTable1 = new TestOldEntity());
$testTable2=$query->createTable($testTable2 = new TestNewEntity());
                                
$where = $query->createWhere();
$where->setAnd($testTable1->testIdId->gt(2), $testTable1->testIdId->lt(5)));
                                
$onWhere=$query->createWhere();
$onWhere->setAnd($testTable1->testId->eq($testTable1->testId));
                                
$queryBuilder = $query->createQueryBuilder();
$result = $queryBuilder->select($testTable1->testId,$testTable1->testName,$testTable2->testTime)
->from($memberTable)
->innerJoin($testTable2, $onWhere)
->where($where)
->getResult();

其中还有左联合、右联合分别是leftJoin和rightJoin。on条件也是通过where条件构造器构造。


3.指定结果类

默认调用getResult方法返回的是一个数组,如果想指定结果类,可以在该方法传入结果类的实例。如:

$result = $queryBuilder->getResult(new testEntity());

如此返回的结果将是TestEntity类对象,优先根据字段名和实体属性的映射关系将对应列的值赋予对应属性,没有的话会使用字段名作为对象的动态属性。

4.分页数据返回

将getResult改为getPageResult可以获取分页结果

$result = $queryBuilder->getPageResult($pageIndex, $pageSize, new testEntity());

返回结果为一个数组,包含以下值:

totalCount 总条数

totalPages 总页数

data 数据列表,如果不传结果类对象参数则每条数据均为数组,传则每条数据均为结果类对象。


五、原生sql查询

对于一些更复杂的查询,还可以通过原生sql语句进行查询,框架提供了两种类型的原型sql执行。

1.执行语句,返回影响数

$query = new Query("testdb1");
$sql="update test set testName='first name' where testId=:testId";
$paramArr=array("testId"=>1);
$result = $query->createSql()->excute($sql, $paramArr);

所有查询通过都必须是参数化查询

2.执行语句,返回查询结果

$query = new Query("testdb1");
$sql="select * from test where testId=:testId";
$paramArr=array("testId"=>1);
$pageSize=1;
$pageIndex=1;
$result = $query->createSql()->getPageResult($sql, $paramArr, $pageIndex, $pageSize, new TestEntity());
//$result = $query->createSql()->getResult($sql, $paramArr, new TestEntity());


以上就是所有说明,如有出错,请指正。


      

转载请注明出处:http://www.xxling.com/article/3107.aspx

  • 分类: PHP
  • 阅读: (2557)
  • 评论: (0)
拍砖 取消
请输入昵称
请输入邮箱
*
 选择评论类型
300字以内  请输入评论内容