PHPackages                             xuey490/database - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. xuey490/database

ActiveLibrary[Database &amp; ORM](/categories/database)

xuey490/database
================

FssPHP Database operation library,Integrate ThinkPHP and Illuminate Database to achieve seamless switching between the two. (namespace Framework\\Database)

1.0.5(1mo ago)1101MITPHPPHP ^8.2

Since Dec 6Pushed 1mo agoCompare

[ Source](https://github.com/xuey490/database)[ Packagist](https://packagist.org/packages/xuey490/database)[ RSS](/packages/xuey490-database/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (6)Dependencies (12)Versions (7)Used By (1)

安装
--

[](#安装)

```
composer require xuey490/database

```

介绍： 利用工厂接口类整合Eloquent 和 ThinkORM 的Model和DB的操作，实现两者的无缝切换
-------------------------------------------------------

[](#介绍-利用工厂接口类整合eloquent-和-thinkorm-的model和db的操作实现两者的无缝切换)

- 接口定义 (DatabaseInterface)：明确契约。
- 主工厂 (DatabaseFactory)：负责分发，解耦具体实现。
- ThinkORM 实现：专注于 ThinkPHP ORM 的初始化。
- Eloquent 实现：专注于 Laravel ORM 的初始化。

初始化
---

[](#初始化)

现在你的调用方式更纯粹，不再依赖全局环境：

```

use Framework\Database\DatabaseFactory;
use Monolog\Logger; // 假设你使用 Monolog

public function index()
{
	// 1. 准备配置和日志
	$config = [
		'default' => 'mysql',
		'connections' => [
			'mysql' => [
				'type' => 'mysql',
				'hostname' => '127.0.0.1',
				// 数据库名
				'database'           =>  'oa',
				// 用户名
				'username'           =>  'root',
				// 密码
				'password'           =>  'root',
				// 端口
				'hostport'           =>  '3306',
				// 数据库表前缀
				'prefix'             =>  'oa_',
				'debug'    => true, // 控制是否记录日志
			]
		]
	];

	$logger = new Logger('db'); // 你的 PSR-3 Logger

	// 2. 配置文件处理器（关键：指定具体的日志文件路径）
	// 推荐路径：项目根目录下的 storage/logs 文件夹（需确保该文件夹有写入权限）
	$logFilePath = __DIR__ . '/../../storage/logs/db.log'; // 适配你的控制器路径
	// 第二个参数是日志级别（DEBUG 会记录所有级别日志，INFO 只记录 INFO 及以上）
	$handler = new StreamHandler($logFilePath, Logger::DEBUG);

	// 3. 将处理器添加到日志器
	$logger->pushHandler($handler);

	// 2. 实例化工厂 (无缝切换 'thinkORM' 或 'laravelORM')
	$dbFactory = new DatabaseFactory($config, 'laravelORM', $logger);	//原地初始化写法

	// 3. 使用
	// 方式 A: 类名
	$userModel = ($dbFactory)(App\Models\Config::class);

	// 方式 B: 表名 (Eloquent模式下返回 Builder, Think模式下返回 Query)
	$users = $dbFactory->make('config')->where('id', '>', 1)->get();
}

```

使用范例
----

[](#使用范例)

根据上面的使用示例，下面补充几个使用表名，模型类来操作数据库的例子，结合illuminate和thinkphp的特性，比如查询(limit，排序，条件查询，分组，统计等)，分页，删除，修改更新，事物回滚等

**核心提示**：虽然通过 `DatabaseFactory` 统一了“获取数据库操作对象”的入口（make），但**获取到的对象**（Query Builder 或 Model）依然是各自 ORM 的原生对象。

因此，**ThinkPHP ORM** 和 **Illuminate (Laravel) ORM** 在具体的方法调用上（如 `get()` vs `select()`, `orderBy()` vs `order()`）是有区别的。

以下是结合这两种 ORM 特性的详细对比使用示例。

---

### 0. 初始化准备

[](#0-初始化准备)

为了演示，假设我们已经通过工厂初始化了数据库。

```
use Framework\Database\DatabaseFactory;
// 假设已配置好 logger 和 config
// 切换驱动： 'laravelORM' (Laravel) 或 'think' (ThinkPHP)
$driverType = 'laravelORM';
$db = new DatabaseFactory($config, $driverType, $logger);
```

---

### 1. 查询构造器 (Table 模式)

[](#1-查询构造器-table-模式)

当你传入字符串（表名）时，工厂返回的是查询构造器。

#### 场景：复杂条件、排序、分页、限制数量

[](#场景复杂条件排序分页限制数量)

```
// 获取 user 表的操作对象
$query = $db->make('user');

// 通用逻辑：查找状态为1，年龄大于18，按ID倒序，取前10条
if ($driverType === 'laravelORM') {
    // === Illuminate (Laravel) 风格 ===
    $list = $query->where('status', 1)
                  ->where('age', '>', 18)
                  ->orderBy('id', 'desc') // Laravel 用 orderBy
                  ->limit(10)
                  ->get(); // Laravel 必须调用 get() 结束

    // 结果是 Illuminate\Support\Collection
    $list->each(function($item) {
        echo $item->username; // 对象方式访问 (配置 fetch mode 后) 或 数组方式
    });

} else {
    // === thinkORM 风格 ===
    $list = $query->where('status', 1)
                  ->where('age', '>', 18)
                  ->order('id', 'desc') // ThinkPHP 用 order
                  ->limit(10)
                  ->select(); // ThinkPHP 必须调用 select() 结束

    // 结果是 think\Collection
    $list->each(function($item) {
        echo $item['username']; // 默认是数组方式访问
    });
}
```

---

### 2. 模型模式 (Class 模式)

[](#2-模型模式-class-模式)

当你传入模型类名时，工厂返回模型实例。

假设定义了 User 模型：

- Laravel: `class User extends \Illuminate\Database\Eloquent\Model {}`
- Think: `class User extends \think\Model {}`

#### 场景：新增、修改、查询单条

[](#场景新增修改查询单条)

```
use App\Model\User;

// 工厂实例化模型 (等价于 new User)
$userModel = $db(User::class);

// === 插入数据 (Create) ===
// 两种 ORM 这里语法极其相似
$userModel->username = 'xuey863toy';
$userModel->email = 'xuey863toy@gmail.com';
$userModel->save();
// 或者使用 create 方法 (需注意 fillable/allowField 配置)
// User::create([...]);

// === 修改数据 (Update) ===
// 假设我们要更新刚插入的数据
// 注意：工厂返回的是空模型，我们需要先查询出来
if ($driverType === 'eloquent') {
    $user = $userModel->where('username', 'xuey863toy')->first();
    if ($user) {
        $user->email = 'new_email@gmail.com';
        $user->save();
    }
    // 批量更新
    $userModel->where('status', 0)->update(['status' => 1]);

} else {
    // thinkORM
    $user = $userModel->where('username', 'xuey863toy')->find();
    if ($user) {
        $user->email = 'new_email@gmail.com';
        $user->save();
    }
    // 批量更新
    $userModel->where('status', 0)->update(['status' => 1]);
}
```

---

### 3. 高级查询：分组与统计

[](#3-高级查询分组与统计)

语法上有细微差别：Laravel 使用 `groupBy`，ThinkPHP 使用 `group`。

```
$query = $db->make('orders');

if ($driverType === 'eloquent') {
    // 查询每个用户的订单总金额
    $result = $query->selectRaw('user_id, sum(amount) as total')
                    ->groupBy('user_id')
                    ->having('total', '>', 100)
                    ->get();

    // 统计总数
    $count = $db->make('users')->count();

} else {
    // ThinkORM
    $result = $query->field('user_id, sum(amount) as total')
                    ->group('user_id')
                    ->having('total', '>', 100)
                    ->select();

    // 统计总数
    $count = $db->make('users')->count();
}
```

---

### 4. 分页 (Pagination)

[](#4-分页-pagination)

这是最常用的功能，两者返回的分页对象不同，但调用方式类似。

```
$pageSize = 20;

if ($driverType === 'laravelORM') {
    // 返回 Illuminate\Pagination\LengthAwarePaginator
    $list = $db->make('user')->paginate($pageSize);

    // 获取数据
    $items = $list->items();
    // 获取总页数
    $lastPage = $list->lastPage();

} else {
    // 返回 think\Paginator
    $list = $db->make('user')->paginate($pageSize);

    // 获取数据 (ThinkPHP 分页对象可以直接当迭代器用)
    foreach ($list as $item) {
        // ...
    }
    // 获取总数
    $total = $list->total();
}
```

---

### 5. 删除操作 (Delete)

[](#5-删除操作-delete)

```
// 按条件删除
$db->make('user')->where('id', 1)->delete();

// 清空表 (慎用)
// Eloquent: truncate()
// Think: query('TRUNCATE TABLE user') 或 Db::execute
```

---

### 6. 事务处理 (Transactions)

[](#6-事务处理-transactions)

这是重构后最需要注意的地方。 由于工厂已经将 DB 库初始化为全局可用（Think 的 `Db::setConfig` 和 laravelORM 的 `Capsule::setAsGlobal`），我们建议**直接使用各自 ORM 的静态方法来管理事务**，因为事务通常是全局的，而不是绑定在某个模型实例上的。

```
// 引入必要的 Facade 或 Manager
use Illuminate\Database\Capsule\Manager as Capsule;
use think\facade\Db as ThinkDb;

try {
    if ($driverType === 'laravelORM') {
        // === Eloquent 事务 ===
        Capsule::beginTransaction();

        try {
            $db->make('user')->where('id', 1)->update(['money' => 0]);
            $db->make('log')->insert(['msg' => 'User 1 cleared']);

            Capsule::commit();
        } catch (\Throwable $e) {
            Capsule::rollBack();
            throw $e;
        }

        // 或者使用闭包方式 (推荐)
        Capsule::transaction(function () use ($db) {
            $db->make('user')->insert(['name' => 'A']);
            $db->make('user')->insert(['name' => 'B']);
        });

    } else {
        // === ThinkORM 事务 ===
        ThinkDb::startTrans();

        try {
            $db->make('user')->where('id', 1)->update(['money' => 0]);
            $db->make('log')->insert(['msg' => 'User 1 cleared']);

            ThinkDb::commit();
        } catch (\Throwable $e) {
            ThinkDb::rollback();
            throw $e;
        }

        // 或者使用闭包
        ThinkDb::transaction(function () use ($db) {
             $db->make('user')->insert(['name' => 'A']);
        });
    }
} catch (\Exception $e) {
    echo "事务回滚: " . $e->getMessage();
}
```

### 总结：如何屏蔽差异？

[](#总结如何屏蔽差异)

由于两个 ORM 语法（`get` vs `select`, `orderBy` vs `order`）差异客观存在，如果你想在业务代码中完全无感切换，通常有几种做法：

1. **Repository 模式（推荐）**：在 Factory 之上再封装一层 Repository，比如 `UserRepository->findAll()`，在 Repository 内部根据驱动类型去写 if-else。
2. **只使用交集语法**：但这很难，因为连最基础的查询结束符都不一样。
3. **拥抱特定 ORM**：工厂模式主要解决了**初始化**和**多项目复用**的问题。在实际业务中，如果你决定用 Eloquent，就统一按 Eloquent 写；工厂的作用是让你在新开项目想切回 ThinkORM 时，只需改配置和少量业务逻辑，而不需要重写底层连接代码。

###  Health Score

41

—

FairBetter than 89% of packages

Maintenance88

Actively maintained with recent releases

Popularity8

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity52

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~20 days

Recently: every ~26 days

Total

6

Last Release

58d ago

PHP version history (2 changes)1.0.0PHP &gt;=8.1

1.0.1PHP ^8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/830041f8bfd4d15e9a2693ed148d39ae3ca8ebb6a8a0eb8d1be7d97577f27fc0?d=identicon)[xuey490](/maintainers/xuey490)

---

Top Contributors

[![xuey490](https://avatars.githubusercontent.com/u/237189208?v=4)](https://github.com/xuey490 "xuey490 (13 commits)")

---

Tags

eloquent-ormfssphpilluminate-databasethinkorm

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/xuey490-database/health.svg)

```
[![Health](https://phpackages.com/badges/xuey490-database/health.svg)](https://phpackages.com/packages/xuey490-database)
```

###  Alternatives

[mongodb/laravel-mongodb

A MongoDB based Eloquent model and Query builder for Laravel

7.1k7.2M71](/packages/mongodb-laravel-mongodb)[owen-it/laravel-auditing

Audit changes of your Eloquent models in Laravel

3.4k33.0M95](/packages/owen-it-laravel-auditing)[dyrynda/laravel-cascade-soft-deletes

Cascading deletes for Eloquent models that implement soft deletes

1.2k3.1M5](/packages/dyrynda-laravel-cascade-soft-deletes)[tightenco/parental

A simple eloquent trait that allows relationships to be accessed through child models.

1.5k1.8M5](/packages/tightenco-parental)[watson/validating

Eloquent model validating trait.

9723.3M47](/packages/watson-validating)[cybercog/laravel-ban

Laravel Ban simplify blocking and banning Eloquent models.

1.1k651.8k11](/packages/cybercog-laravel-ban)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
