windwalker/datamapper

Windwalker DataMapper 包

安装次数: 3,921

依赖项: 2

建议者: 0

安全: 0

星标: 3

关注者: 4

分支: 1

类型:windwalker-package

3.5.23 2020-11-05 06:29 UTC

README

通过 Composer 安装

将此添加到您的 composer.json 文件中的 require 块。

{
    "require": {
        "windwalker/datamapper": "~3.0"
    }
}

入门指南

准备 Windwalker 数据库对象

use Windwalker\Database\DatabaseFactory;

// Make the database driver.
$db = DatabaseFactory::getDbo(
    'mysql',
	array(
		'driver'   => 'mysql',
		'host'     => 'localhost',
		'user'     => 'root',
		'password' => 'xxxx',
		'database' => 'mydb',
		'prefix'   => 'prefix_'
	)
);

DatabaseDriver 将在 Factory 中缓存,现在 DataMapper 将自动加载数据库驱动。

Database

创建 DataMapper

use Windwalker\DataMapper\DataMapper;

$fooMapper = new DataMapper('#__foo');

$fooSet = $fooMapper->find(array('id' => 1));

将 DB 注入 DataMapper

// $db is Windwalker DatabaseDriver
$mapper = new DataMapper('table', null, $db);

自定义主键

// If keep keys NULL, the default `id` will auto set.
$mapper = new DataMapper('table'); // Keys: array('id')

// Set custom key
$mapper = new DataMapper('table', 'table_id'); // Keys: array('table_id')

// Set multiple keys
$mapper = new DataMapper('table', array('table_id', 'uuid')); // Keys: array('table_id', 'uuid')

扩展它

您也可以创建一个类来操作特定的表

class FooMapper extends DataMapper
{
    protected static $table = '#__foo';

    protected static $keys = 'id';
}

$data = (new FooMapper)->findAll();

或者使用外观

use Windwalker\DataMapper\AbstractDatabaseMapperProxy;

abstract class FooMapper extends AbstractDatabaseMapperProxy
{
    protected $table = '#__foo';

    protected $keys = 'id'; // Keep NULL will use default `id`
}

$data = FooMapper::findOne(array('id' => 5, 'alias' => 'bar'));

查找记录

find() 方法将从表中检索行,并返回 DataSet 类。

find()

获取 id = 1 的记录

$fooSet = $fooMapper->find(array('id' => 1));

获取 published = 1,并按 date 排序

$fooSet = $fooMapper->find(array('published' => 1), 'date');

获取 published = 1,language = en-US,按 date DESC 排序,从 30 开始,限制 10

$fooSet = $fooMapper->find(array('published' => 1, 'language' => 'en-US'), 'date DESC', 30, 10);

使用数组,将会是 IN 条件

$fooSet = $fooMapper->find(array('id' => array(1,2,3))); // WHERE id IN (1,2,3)

findOne()

只返回一行。

$foo = $dooMapper->findOne(array('published' => 1), 'date');

findAll()

等于 find(array(), $order, $start, $limit)

使用自定义查询查找

$fooMapper = new DataMapper('#__foo');

$fooMapper->where('a = "b"') // Simple where
	->where('%n = $q', 'foo', 'bar') // Where format
	->where('flower = :sakura')->bind('sakura', 'Sakura') // Bind params
	->orWhere(array('c = d', 'e = f')) // AND (c=d OR e=f)
	->having('...')
	->limit(10, 20) // Limit, offset
	->order('created DESC') // Can be array or string
	->select(array('id', 'title', 'alias')) // Can be array or string
	->find();

可用的查询方法。

  • join($type = 'LEFT', $alias, $table, $condition = null, $prefix = null)
  • leftJoin($alias, $table, $condition = null, $prefix = null)
  • rightJoin($alias, $table, $condition = null, $prefix = null)
  • nnerJoin($alias, $table, $condition = null, $prefix = null)
  • outerJoin($alias, $table, $condition = null, $prefix = null)
  • call($columns)
  • group($columns)
  • order($columns)
  • limit($limit = null, $offset = null)
  • select($columns)
  • where($conditions, ...$args)
  • orWhere($conditions)
  • having($conditions, ...$args)
  • orHaving($conditions)
  • clear($clause = null)
  • bind($key = null, $value = null, $dataType = \PDO::PARAM_STR, $length = 0, $driverOptions = array())

Query Format

创建记录

使用 DataSet 包裹每个数据,然后将此对象发送到 create() 方法,这些数据将插入到表中。

create()

use Windwalker\Data\Data;
use Windwalker\Data\DataSet;

$data1 = new Data;
$data1->title = 'Foo';
$data1->auhor = 'Magneto';

$data2 = new Data(
    array(
        'title' => 'Bar',
        'author' => 'Wolverine'
    )
);

$dataset = new DataSet(array($data1, $data2));

$return = $fooMapper->create($dataset);

返回值将是整个数据集和添加的插入 ID。

Windwalker\Data\DataSet Object
(
    [storage:ArrayObject:private] => Array
        (
            [0] => Windwalker\Data\Data Object
                (
                    [title] => Foo
                    [auhor] => Magneto
                    [id] => 39
                )

            [1] => Windwalker\Data\Data Object
                (
                    [title] => Bar
                    [auhor] => Wolverine
                    [id] => 40
                )
        )
)

createOne()

只插入一行,不需要 DataSet。

$data = new Data;
$data->title = 'Foo';
$data->auhor = 'Magneto';

$fooMapper->createOne($data);

更新记录

更新方法帮助我们更新表中的行。

update()

use Windwalker\Data\Data;
use Windwalker\Data\DataSet;

$data1 = new Data;
$data1->id = 1;
$data1->title = 'Foo';

$data2 = new Data(
    array(
        'id' => 2,
        'title' => 'Bar'
    )
);

$dataset = new DataSet(array($data1, $data2));

$fooMapper->update($dataset);

updateOne()

只更新一行。

$data = new Data;
$data->id = 1;
$data->title = 'Foo';

$fooMapper->updateOne($data);

updateAll()

UpdateAll 与 update 方法不同,我们只发送一个数据对象,但使用条件作为 where 来更新匹配这些条件的每一行。我们不需要主键来 updateAll()。

$data = new Data;
$data->published = 0;

$fooMapper->updateAll($data, array('author' => 'Mystique'));

删除

根据条件删除行。

delete()

$boolean = $fooMapper->delete(array('author' => 'Jean Grey'));

连接表

使用 newRelation() 创建一个 DataMapper 并连接其他表。

use Windwalker\DataMapper\DataMapper;

$items = DataMapper::newRelation('flower', '#__flower')
	->leftJoin('author', '#__users', 'flower.user_id = author.id')
	->innerJoin('category', '#__categories', array('category.lft >= flower.lft', 'category.rgt <= flower.rgt'))
	->where('flower.id = 1')
	->order('created DESC')
	->group('category.id')
	->find();

连接查询将是

SELECT `flower`.`id`,
	`flower`.`catid`,
	`flower`.`title`,
	`flower`.`user_id`,
	`flower`.`meaning`,
	`flower`.`ordering`,
	`flower`.`state`,
	`flower`.`params`,
	`author`.`id` AS `author_id`,
	`author`.`name` AS `author_name`,
	`author`.`pass` AS `author_pass`,
	`category`.`id` AS `category_id`,
	`category`.`title` AS `category_title`,
	`category`.`ordering` AS `category_ordering`,
	`category`.`params` AS `category_params`
FROM #__foo AS foo
    LEFT JOIN #__users AS author ON foo.user_id = author.id
    INNER JOIN #__categories AS category ON category.lft >= foo.lft AND category.rgt <= foo.rgt
WHERE
    flower.id = 1
ORDER BY flower.created DESC
GROUP BY category.id

如果未提供,将自动添加别名。

$fooMapper->find(array(
    'foo.id' => 3 // This is correct condition
    'state' => 1 // This field may cause column conflict, DataMapper will auto covert it to `foo.state` => 1
));

重置所有表和查询

$fooMapper->reset();

使用 OR 条件

$fooMapper->addTable(
    'category',
    '#__categories',
    'category.lft >= foo.lft OR category.rgt <= foo.rgt',
    'LEFT'
);

分组

$fooMapper->group('category.id');

比较对象

使用比较对象可以帮助我们设置一些难以使用数组定义的 where 条件。

$fooSet = $fooMapper->find(
    array(
        new GteCompare('id', 5),
        new NeqCompare('name', 'bar')
        new LtCompare('published', 1),
        new NinCompare('catid', array(1,2,3,4,5))
    )
);

这将生成如下 where 条件

WHERE `id` >= '5'
    AND `name` !== 'bar'
    AND `published` < '1'
    AND `catid` NOT IN (1,2,3,4,5)

可用的比较

自定义比较

echo (string) new Compare('title', '%flower%', 'LIKE');

将是

`title` LIKE `%flower%`

见:https://github.com/ventoviro/windwalker-compare

使用数据和数据集

见:https://github.com/ventoviro/windwalker-data

钩子

"windwalker/event": "~3.0" 添加到 composer.json

然后我们能够在每次操作后使用钩子。

class FooListener
{
    public function onAfterCreate(Event $event)
    {
        $result = $event['result'];

        // Do something
    }
}

$mapper = new DataMapper('table');

// Add object as listener
$mapper->getDispatcher()->addListener(new FooListener);

// Use listen() to add a callback as listener
$mapper->getDispatcher()->listen('onAfterUpdate', function () { ... });

$mapper->create($dataset);

扩展 DataMapper

class SakuraMapper extends DataMapper
{
    protected $table = 'saluras';

    public function onAfterFind(Event $event)
    {
        $result = $event['result'];

        // Find some relations
    }
}

$mapper = new DataMapper('table');
$mapper->find(array('id' => 5));

可用的事件

  • onBeforeFind
  • onAfterFind
  • onBeforeFindAll
  • onAfterFindAll
  • onBeforeFindOne
  • onAfterFindOne
  • onBeforeFindColumn
  • onAfterFindColumn
  • onBeforeCreate
  • onAfterCreate
  • onBeforeCreateOne
  • onAfterCreateOne
  • onBeforeUpdate
  • onAfterUpdate
  • onBeforeUpdateOne
  • onAfterUpdateOne
  • onBeforeUpdateBatch
  • onAfterUpdateBatch
  • onBeforeSave
  • onAfterSave
  • onBeforeSaveOne
  • onAfterSaveOne
  • onBeforeFlush
  • onAfterFlush
  • onBeforeDelete
  • onAfterDelete

关于事件的更多信息:Windwalker Event