說明:建立表的時候需要進行判斷,如果表存在,則不需要建立。這個程式碼會被多次使用並可以重複使用,選擇寫成trait,實現分表後的增刪改查操作和分表前一樣,但預設是對當前月份進行增刪改查。
trait:
<?php
namespace App\Models\Traits;
use Carbon\Carbon;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
trait SplitTableTrait
{
/**
* 是否分表,預設false,即不分表
* @var bool
*/
protected $isSplitTable = true;
/**
* 最終生成表
* @var
*/
protected $endTable;
/**
* 字尾引數
* @var null
*/
protected $suffix = null;
/**
* 初始化
* @param array $attributes
* @param $suffix
* @return void
*/
public function init(array $attributes = [], $suffix = null)
{
$this->endTable = $this->table;
// isSplitTable引數為true時進行分表,否則不分表
if ($this->isSplitTable) {
// 初始化字尾,未傳則預設年月分表
$this->suffix = $suffix ?: Carbon::now()->format('Ym');
}
//初始化分表表名並建立
$this->setSuffix($suffix);
}
/**
* 設定表字尾, 如果設定分表字尾,可在service層呼叫生成自定義字尾表名,
* 但每次操作表之前都需要呼叫該方法以保證資料表的準確性
* @param $suffix
* @return void
*/
public function setSuffix($suffix = null)
{
// isSplitTable引數為true時進行分表,否則不分表
if ($this->isSplitTable) {
//初始化字尾,未傳則預設年月分表
$this->suffix = $suffix ?: Carbon::now()->format('Ym');
}
if ($this->suffix !== null) {
// 最終表替換模型中宣告的表作為分表使用的表
$this->table = $this->endTable.'_'.$this->suffix;
}
// 呼叫時,建立分表,格式為 table_{$suffix}
// 未傳自定義字尾情況下,,預設按年月分表格式為:orders_202205
// 無論使用時是否自定義分表名,都會建立預設的分表,除非關閉該呼叫
$this->createTable();
}
/**
* 提供一個靜態方法設定表字尾
* @param $suffix
* @return mixed
*/
public static function suffix($suffix = null)
{
$instance = new static;
$instance->setSuffix($suffix);
return $instance->newQuery();
}
/**
* 建立新的"table_{$suffix}"的模型例項並返回
* @param array $attributes
* @return object $model
*/
public function newInstance($attributes = [], $exists = false): object
{
$model = parent::newInstance($attributes, $exists);
$model->setSuffix($this->suffix);
return $model;
}
/**
* 建立分表,沒有則建立,有則不處理
* @return void
*/
protected function createTable()
{
$connectName = $this->getConnectionName();
// 初始化分表,,按年月分表格式為:orders_202205
if (!Schema::connection($connectName)->hasTable($this->table)) {
Schema::connection($connectName)->create($this->table, function (Blueprint $table) {
$table->id();
$table->dateTime('pay_at')->comment('交易時間');
$table->string('appid')->comment('公眾賬號ID');
$table->string('mch_id')->comment('商戶號');
$table->string('sub_mch_id')->nullable()->comment('特約商戶號');
$table->string('device_info')->nullable()->comment('裝置號');
$table->string('transaction_id')->comment('微信訂單號');
$table->string('out_trade_no')->comment('商戶訂單號');
$table->string('openid')->comment('使用者標識');
$table->string('trade_type')->comment('交易型別');
$table->string('pay_status')->comment('交易狀態');
$table->string('bank_type')->comment('付款銀行');
$table->string('fee_type')->comment('貨幣種類');
$table->decimal('settlement_total_fee', 10, 2)->comment('應結訂單金額');
$table->decimal('coupon_fee', 10, 2)->comment('代金券金額');
$table->string('refund_id')->comment('微信退款單號');
$table->string('out_refund_no')->comment('商戶退款單號');
$table->decimal('refund_fee', 10, 2)->comment('退款金額');
$table->decimal('coupon_refund_fee', 10, 2)->comment('充值券退款金額');
$table->string('refund_type')->nullable()->comment('退款型別');
$table->string('refund_status')->nullable()->comment('退款狀態');
$table->string('body')->comment('商品名稱');
$table->string('attach', 1000)->nullable()->comment('商戶資料包');
$table->decimal('service_charge', 10, 2)->comment('手續費');
$table->string('rate')->comment('費率');
$table->decimal('total_fee', 10, 2)->comment('訂單金額');
$table->decimal('apply_refund_fee', 10, 2)->comment('申請退款金額');
$table->string('rate_remark')->nullable()->comment('費率備註');
$table->timestamps();
});
}
}
}
模型使用trait:(任何模型都可使用這個trait進行按月分表)
<?php
namespace App\Models;
use App\Models\Traits\SplitTableTrait;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class WechatBill extends Model
{
use HasFactory;
use SplitTableTrait;
protected $table = 'wechat_bill';
protected $guarded = [];
public function __construct(array $attributes = [], $suffix = null)
{
// 初始化分表處理
$this->init($attributes, $suffix);
parent::__construct($attributes);
}
}
效果:
分表查詢示例
$wechatBill = new WechatBill();
$wechatBill->setSuffix(202303);
return $wechatBill->newQuery()->get();
分表寫入
return (new WechatBill([], 202303))->newInstance()->create([]);
本作品採用《CC 協議》,轉載必須註明作者和本文連結