its-mieger/lara-db-ext

此包已被 废弃 并不再维护。作者建议使用 mehr-it/lara-db-ext 包代替。

laravel数据库和ORM功能的扩展,包括模型连接(SQL)、多列查询和数据库字段前缀

2.1.0 2020-02-26 07:47 UTC

README

自定义连接

selectPrefixed

有时您希望某些列名前加上给定的前缀。以下示例将所有返回的列名都加上 "user_" 前缀

DB:table('users')->selectPrefixed(['id', 'name'], 'user_')->get();

// => [['user_id' => 1, 'user_name' => 'John']]

当您在具有冲突列名的表上使用连接时,这非常有用

DB:table('users')
	->join('children', 'users.id', '=', 'children.user_id')
	->addSelectPrefixed('users.*', 'user_')
	->addSelectPrefixed('children.*', 'child_')
	->get();

// => [[ 'user_id' => 1, 'user_name' => 'John', 'child_id' => 12, 'child_name' => 'Maria']]

如果不加前缀,则 children 字段会静默地覆盖 users 字段。如您所见,它也适用于使用通配符列选择器。最好的是:它不会产生额外的查询来获取表结构。实际上,它完全不依赖于表列

它还可以与表达式一起使用

DB:table('users')->selectPrefixed(new Expression('count(*) as myCount'), 'user_')->get();

// => [['user_myCount' => 123]]

如果您省略前缀参数并传递一个关联数组作为第一个参数,则可以在一个调用中设置多个前缀

DB:table('users')
	->join('children', 'users.id', '=', 'children.user_id')
	->selectPrefixed([
		'user_'  => 'users.*',
		'child_' => ['id', 'name'],
	])
	->get();

whereNotNested

如果您想否定一个嵌套的 where 子句,新的 whereNotNested 函数就派上用场了

DB:table('users')
	->whereNotNested(function($query) {
		$query->where('name', 'John');
		$query->where('age', '>', 49);
	})
	->get();

这将产生以下查询

SELECT * FROM users WHERE NOT (first_name = 'John' AND age > 49) 

whereMultiIn

某些 SQL 语法允许使用 IN 操作符比较多个列。您可以使用 whereMultiIn 函数来实现这一点

DB:table('users')
	->whereMultiIn(['name', 'age'], [
		['John', 38],
		['Ida', 49],
	])
	->get();

这将产生以下查询

SELECT * FROM users WHERE (name, age) IN ( ('John', 38), ('Ida', 49) )

您甚至可以传递一个子选择而不是值数组

DB:table('users')
	->whereMultiIn(['name', 'age'], function ($query) {
		return $query->select(['parent_name', 'parent_age'])
			->from('children')
			->where('age', '<', 3);
	})
	->get();

whereMultiColumns

whereMultiColumns 接受要比较的多个列

DB:table('users')
	->whereMultiColumns(['name', 'age'], ['n', 'a'])
	->get();

这将产生以下查询

SELECT * FROM users WHERE (name = n AND age = a)

运算符应用于列的组合。这就是为什么只支持 =!=<> 的原因。

DB:table('users')
	->whereMultiColumns(['name', 'age'], '!=', ['n', 'a'])
	->get();

这将产生以下查询

SELECT * FROM users WHERE NOT (name = n AND age = a)

自动 where 检测

另一个改进是,where 函数现在可以使用数组作为值参数,因此它将自动转换为 whereIn。当然,这也适用于多列

DB:table('users')
	->where('name', ['John', 'Ida'])
	->get();
	
DB:table('users')
	->where(['name', 'age'], [
		['John', 38],
		['Ida', 49],
	])
	->get();

这也适用于 whereColumn 函数

DB:table('users')
	->whereColumn(['name', 'age'], ['n', 'a'])
	->get();

时区处理

数据库中的时区处理可能很复杂。Laravel将没有时区信息的日期传递给数据库。这种行为是正确的,因为数据通常存储没有任何时区信息。当读取日期时,Laravel (Eloquent) 使用默认的应用程序时区来解释日期。

但是,Laravel 不确保将 DateTime 参数传递给数据库时使用应用程序时区。因此,如果您将具有不同时区的日期传递给数据库,则在读取时将使用另一个时区。

为确保所有 DateTime 参数在发送到数据库之前都转换为应用程序时区,此包为数据库连接添加了 "adapt_timezone" 配置选项。如果设置为 true,则任何 DateTime 值在传递给数据库之前都将转换为应用程序时区。

AdaptsAttributeTimezone 特性实现了 Eloquent 模型属性的时区适配。

数据库会话时区

一些数据库,例如MySQL,在将日期转换为时间戳时会使用数据库会话时区(参见MySQL官方文档以获取详细信息)。对于MySQL来说,这仅影响将日期存储到TIMESTAMP列(而不是DATETIME列)以及NOW()和CURTIME()函数。因此,您应该始终将连接的“时区”参数配置为与应用程序时区相同的值!