Categories
java

Elastic job

分布式调度应用

elasticjob-lite-core 分布式调度应用核心代码

基于ZooKeeper 作为调度中心

Categories
mongodb

mongoDB

启动 mongodb

还原 mongorestore

linux下安装mongoDB

sudo apt install mongodb-server

执行本地连接

mongo

本地配置文件

/etc/mongodb.conf

重要配置项

bind_ip //绑定主机
port    //服务端口
auth    //是否需要账号密码登录

配置需要登录前需要先添加用户

在admin表下添加user

use admin;

db.createUser({user:"admin", pwd:"密码",roles:[{role:"userAdminAnyDatabase",db:"admin"},{role:"readWriteAnyDatabase",db:"admin"}]});

连接后先授权

use admin;
db.auth('robin','RobinLuo123');
Categories
java

身份证判断逻辑


// 定义判别用户身份证号的正则表达式(15位或者18位,最后一位可以为字母)
String regularExpression = "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" +
"(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)";
//假设18位身份证号码:41000119910101123X 410001 19910101 123X
//^开头
//[1-9] 第一位1-9中的一个 4
//\\d{5} 五位数字 10001(前六位省市县地区)
//(18|19|20) 19(现阶段可能取值范围18xx-20xx年)
//\\d{2} 91(年份)
//((0[1-9])|(10|11|12)) 01(月份)
//(([0-2][1-9])|10|20|30|31)01(日期)
//\\d{3} 三位数字 123(第十七位奇数代表男,偶数代表女)
//[0-9Xx] 0123456789Xx其中的一个 X(第十八位为校验值)
//$结尾

//假设15位身份证号码:410001910101123 410001 910101 123
//^开头
//[1-9] 第一位1-9中的一个 4
//\\d{5} 五位数字 10001(前六位省市县地区)
//\\d{2} 91(年份)
//((0[1-9])|(10|11|12)) 01(月份)
//(([0-2][1-9])|10|20|30|31)01(日期)
//\\d{3} 三位数字 123(第十五位奇数代表男,偶数代表女),15位身份证不含X
//$结尾


boolean matches = IDNumber.matches(regularExpression);

//判断第18位校验值
if (matches) {

if (IDNumber.length() == 18) {
try {
char[] charArray = IDNumber.toCharArray();
//前十七位加权因子
int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
//这是除以11后,可能产生的11位余数对应的验证码
String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"};
int sum = 0;
for (int i = 0; i < idCardWi.length; i++) {
int current = Integer.parseInt(String.valueOf(charArray[i]));
int count = current * idCardWi[i];
sum += count;
}
char idCardLast = charArray[17];
int idCardMod = sum % 11;
if (idCardY[idCardMod].toUpperCase().equals(String.valueOf(idCardLast).toUpperCase())) {
return true;
} else {
return false;
}

} catch (Exception e) {
logger.error("身份证校验异常,{}", e.getMessage());
return false;
}
}

}

return matches;
Categories
java

spring AOP

切面语法

execution

execution是一种使用频率比较高比较主要的一种切点指示符,用来匹配方法签名,方法签名使用全限定名,包括访问修饰符(public/private/protected)、返回类型,包名、类名、方法名、参数,其中返回类型,包名,类名,方法,参数是必须的,如下面代码片段所示:

@Pointcut("execution(public String org.baeldung.dao.FooDao.findById(Long))")
上面的代码片段里的表达式精确地匹配到FooDao类里的findById(Long)方法,但是这看起来不是很灵活。假设我们要匹配FooDao类的所有方法,这些方法可能会有不同的方法名,不同的返回值,不同的参数列表,为了达到这种效果,我们可以使用通配符。如下代码片段所示:

@Pointcut("execution(* org.baeldung.dao.FooDao.*(..))")
第一个通配符匹配所有返回值类型,第二个匹配这个类里的所有方法,()括号表示参数列表,括号里的用两个点号表示匹配任意个参数,包括0个

within

使用within切点批示符可以达到上面例子一样的效果,within用来限定连接点属于某个确定类型的类。如下面代码的效果与上面的例子是一样的:

@Pointcut("within(org.baeldung.dao.FooDao)")
我们也可以使用within指示符来匹配某个包下面所有类的方法(包括子包下面的所有类方法),如下代码所示:

@Pointcut("within(org.baeldung..*)")

this 和 target

this用来匹配的连接点所属的对象引用是某个特定类型的实例,target用来匹配的连接点所属目标对象必须是指定类型的实例;那么这两个有什么区别呢?原来AspectJ在实现代理时有两种方式:
1、如果当前对象引用的类型没有实现自接口时,spring aop使用生成一个基于CGLIB的代理类实现切面编程
2、如果当前对象引用实现了某个接口时,Spring aop使用JDK的动态代理机制来实现切面编程
this指示符就是用来匹配基于CGLIB的代理类,通俗的来讲就是,如果当前要代理的类对象没有实现某个接口的话,则使用this;target指示符用于基于JDK动态代理的代理类,通俗的来讲就是如果当前要代理的目标对象有实现了某个接口的话,则使用target.

比如在上面这段代码示例中,spring aop将使用jdk的动态代理来实现切面编程,在编写匹配这类型的目标对象的连接点表达式时要使用target指示符, 如下所示:
@Pointcut("target(org.baeldung.dao.BarDao)")

如果FooDao类没有实现任何接口,或者在spring aop配置属性:proxyTargetClass设为true时,Spring Aop会使用基于CGLIB的动态字节码技为目标对象生成一个子类将为代理类,这时应该使用this指示器
@Pointcut("this(org.baeldung.dao.FooDao)")

参数

参数指示符是一对括号所括的内容,用来匹配指定方法参数:

 
@Pointcut("execution(* *..find*(Long))")


这个切点匹配所有以find开头的方法,并且只一个Long类的参数。如果我们想要匹配一个有任意个参数,但是第一个参数必须是Long类的,我们这可使用下面这个切点表达式:

@Pointcut("execution(* *..find*(Long,..))")

@Target

@Pointcut("@target(org.springframework.stereotype.Repository)")

@args

@Pointcut("@args(org.baeldung.aop.annotations.Entity)")
public void methodsAcceptingEntities() {}

@within

这个指示器,指定匹配必须包括某个注解的的类里的所有连接点:

@Pointcut("@within(org.springframework.stereotype.Repository)")
上面的切点跟以下这个切点是等效的:

@Pointcut("within(@org.springframework.stereotype.Repository *)")

@annotation

这个指示器匹配那些有指定注解的连接点,比如,我们可以新建一个这样的注解@Loggable:

@Pointcut("@annotation(org.baeldung.aop.annotations.Loggable)")
public void loggableMethods() {}
我们可以使用@Loggable注解标记哪些方法执行需要输出日志:

@Before("loggableMethods()")
public void logMethod(JoinPoint jp) {
    String methodName = jp.getSignature().getName();
    logger.info("Executing method: " + methodName);
}

&&、||、!

可以使用&&、||、!、三种运算符来组合切点表达式,表示与或非的关系。

@target @within 区别
@target要求对象的运行时类型与被注解的类型是同一个类型
@within要求对象的运行时类型是被注解的类型的子类
Categories
nginx

nginx tcpip 代理

nginx stream 能提供基于tcpip的代理功能

stream {
        upstream redis {
                server 192.168.0.14:6379;
        }
        server {
                listen 6379;
                proxy_pass redis;

        }
}

定义stram模块 开始配置tcpip转发规则

定义的upstream redis 是一个只能内网访问的redis

server 模块表示对外的配置信息 上文就是把开通本机6379端口 代理redis服务器

Categories
mysql

mysql 表空间操作

mysql表的持久化的引擎有myisam 和 innodb 两种 会在指定的数据目录下生成myi、myd文件和idb文件作为表的数据文件

myi和myd是myisam的数据文件

idb是innodb的数据文件

但我们需要硬盘级别复制mysql数据时 可以再备份库先创建一抹异样的表结构,然后 alter table XXX discard tablesapce 断开数据文件关联 然后把从库的数据文件替换备份库的数据文件(文件名就是表名)然后执行挂载数据文件 alter table XXX import tablespace

注意windows下MySQL文件和表名都是小写的 然而linux表名是区分大小写的会导致生成的数据文件 大小写有差异 所以import tablespace 之前需要先改成小写(与创建的表名相同)。

上述说的数据文件就是表空间文件 discard tablespace import tablespace 就是表空间的断开与挂载

Categories
ruby

gitlab

ubuntu下安装gitlab (必须是64位系统)

gitlab 是一个基于git的版本管理服务器 由ruby编写

然而gitlab的应用中有各种进程作为辅助功能 nginx redis posgresSQL 等一系列的辅助进程 为了避免和本级冲突应该设置其enabled为false 然后调用本机的第三方应用

apt install gitlab-ce 安装完成后 编写 /etc/gitlab/gitlab.rb (ruby文件) 进行配置,所有配置都应该在这里写 然后通过gitlab-ctl reconfigure 部署到具体应用上 不应在gitlab具体的应用配置上直接更改 如编写gitlab自带的nginx的nginx.conf redis 的 redis.conf 等

运行解析 首先进程跑起在puma中(旧版在unicorn)跑起http服务,然后由gitlab-workhorse 代理 将http服务转移到unix:socket中。然后通过我们自己的nginx 把请求转发到 这个socket中即可

邮件配置 :gitlab需要配置邮件发件账号 所以在smtp中配置自己的qq邮箱 qq邮箱需开启smtp功能 配配置授权码

gitlab命令 gitlab-ctl help/configure/restart/start/stop gitlab-rails console 进入控制台 可以调用ruby方法

Notify.test_email('1569964920@qq.com','robin gitlab','test').deliver_now
Categories
php

laravel http test 集成测试

http 测试 (在feature是集成测试 在unit是单元测试 想要跑起laravel的 要在feature里做测试)

例子

<?php

namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Tests\TestCase;

class ExampleTest extends TestCase
{
    /**
     * A basic test example.
     *
     * @return void
     */
    public function test_a_basic_request()
    {
        $response = $this->get('/');

        $response->assertStatus(200);
    }
}

mock 请求头

<?php

namespace Tests\Feature;

use Tests\TestCase;

class ExampleTest extends TestCase
{
    /**
     * A basic functional test example.
     *
     * @return void
     */
    public function test_interacting_with_headers()
    {
        $response = $this->withHeaders([
            'X-Header' => 'Value',
        ])->post('/user', ['name' => 'Sally']);

        $response->assertStatus(201);
    }
}

cookie

<?php

namespace Tests\Feature;

use Tests\TestCase;

class ExampleTest extends TestCase
{
    public function test_interacting_with_cookies()
    {
        $response = $this->withCookie('color', 'blue')->get('/');

        $response = $this->withCookies([
            'color' => 'blue',
            'name' => 'Taylor',
        ])->get('/');
    }
}

session

<?php

namespace Tests\Feature;

use Tests\TestCase;

class ExampleTest extends TestCase
{
    public function test_interacting_with_the_session()
    {
        $response = $this->withSession(['banned' => false])->get('/');
    }
}

身份mocking

<?php

namespace Tests\Feature;

use App\Models\User;
use Tests\TestCase;

class ExampleTest extends TestCase
{
    public function test_an_action_that_requires_authentication()
    {
        $user = User::factory()->create();

        $response = $this->actingAs($user)
                         ->withSession(['banned' => false])
                         ->get('/');
    }
}
$this->actingAs($user, 'api') //关键是这句

打印响应

<?php

namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Tests\TestCase;

class ExampleTest extends TestCase
{
    /**
     * A basic test example.
     *
     * @return void
     */
    public function testBasicTest()
    {
        $response = $this->get('/');

        $response->dumpHeaders();

        $response->dumpSession();

        $response->dump();
    }
}

json api 测试

?php

namespace Tests\Feature;

use Tests\TestCase;

class ExampleTest extends TestCase
{
    /**
     * A basic functional test example.
     *
     * @return void
     */
    public function test_making_an_api_request()
    {
        $response = $this->postJson('/api/user', ['name' => 'Sally']);

        $response
            ->assertStatus(201)
            ->assertJson([
                'created' => true,
            ]);
    }
}
$this->assertTrue($response['created']);

判断json结果完全一样

<?php

namespace Tests\Feature;

use Tests\TestCase;

class ExampleTest extends TestCase
{
    /**
     * A basic functional test example.
     *
     * @return void
     */
    public function test_asserting_an_exact_json_match()
    {
        $response = $this->json('POST', '/user', ['name' => 'Sally']);

        $response
            ->assertStatus(201)
            ->assertExactJson([
                'created' => true,
            ]);
    }
}

判断json嵌套对象

<?php

namespace Tests\Feature;

use Tests\TestCase;

class ExampleTest extends TestCase
{
    /**
     * A basic functional test example.
     *
     * @return void
     */
    public function test_asserting_a_json_paths_value()
    {
        $response = $this->json('POST', '/user', ['name' => 'Sally']);

        $response
            ->assertStatus(201)
            ->assertJsonPath('team.owner.name', 'Darian');
    }
}

文件上传mocking

<?php

namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Tests\TestCase;

class ExampleTest extends TestCase
{
    public function test_avatars_can_be_uploaded()
    {
        Storage::fake('avatars');

        $file = UploadedFile::fake()->image('avatar.jpg');

        $response = $this->post('/avatar', [
            'avatar' => $file,
        ]);

        Storage::disk('avatars')->assertExists($file->hashName());
    }
}
//Storage::disk('avatars')->assertMissing('missing.jpg');
 //文件不存在

所有的response assert判断

assertCookie assertCookieExpired assertCookieNotExpired assertCookieMissing assertCreated assertDontSee assertDontSeeText assertExactJson assertForbidden assertHeader assertHeaderMissing assertJson assertJsonCount assertJsonFragment assertJsonMissing assertJsonMissingExact assertJsonMissingValidationErrors assertJsonPath assertJsonStructure assertJsonValidationErrors assertLocation assertNoContent assertNotFound assertOk assertPlainCookie assertRedirect assertSee assertSeeInOrder assertSeeText assertSeeTextInOrder assertSessionHas assertSessionHasInput assertSessionHasAll assertSessionHasErrors assertSessionHasErrorsIn assertSessionHasNoErrors assertSessionDoesntHaveErrors assertSessionMissing assertStatus assertSuccessful assertUnauthorized assertViewHas assertViewHasAll assertViewIs assertViewMissing

Categories
php

migration 使用

为了laravel 数据库迁移 migration使用

按照某个model构建 mirgration

php artisan make:migration create_flights_table --create=flights

按照现有的数据库 dump一下

php artisan schema:dump

// Dump the current database schema and prune all existing migrations...
php artisan schema:dump --prune

migration文件例子

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateFlightsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('flights', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('airline');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('flights');
    }
}

执行migration

php artisan migrate

scheme详解

建表

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

Schema::create('users', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('email');
    $table->timestamps();
});

检查

if (Schema::hasTable('users')) {
    // The "users" table exists...
}

if (Schema::hasColumn('users', 'email')) {
    // The "users" table exists and has an "email" column...
}

指定连接

Schema::connection('sqlite')->create('users', function (Blueprint $table) {
    $table->id();
});

指定表储存引擎

Schema::create('users', function (Blueprint $table) {
    $table->engine = 'InnoDB';

    // ...
});

指定字符集

Schema::create('users', function (Blueprint $table) {
    $table->charset = 'utf8mb4';
    $table->collation = 'utf8mb4_unicode_ci';

    // ...
});

更改字段(和创建字段一样)

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

Schema::table('users', function (Blueprint $table) {
    $table->integer('votes');
});

表改名

Schema::rename($from, $to);

删除表

Schema::drop('users');

Schema::dropIfExists('users');

所有的字段类型

bigIncrements bigInteger binary boolean char dateTimeTz dateTime date decimal double enumfloat foreignId geometryCollection geometry id increments integer ipAddress json jsonb lineString longText macAddress mediumIncrements mediumInteger mediumText morphs multiLineString multiPoint multiPolygon nullableMorphs nullableTimestamps nullableUuidMorphs point polygon rememberToken set smallIncrements smallInteger softDeletesTz softDeletes stringtext timeTz time timestampTz timestamp timestampsTz timestampstinyIncrements tinyInteger unsignedBigInteger unsignedDecimal unsignedInteger unsignedMediumInteger unsignedSmallInteger unsignedTinyInteger uuidMorphs uuid year

更改字段

Schema::table('users', function (Blueprint $table) {
    $table->string('name', 50)->change();
});

字段改名

Schema::table('users', function (Blueprint $table) {
    $table->renameColumn('from', 'to');
});

舍弃字段

Schema::table('users', function (Blueprint $table) {
    $table->dropColumn('votes');
});

Schema::table('users', function (Blueprint $table) {
    $table->dropColumn(['votes', 'avatar', 'location']);
});
CommandDescription
$table->dropMorphs('morphable');Drop the morphable_id and morphable_type columns.
$table->dropRememberToken();Drop the remember_token column.
$table->dropSoftDeletes();Drop the deleted_at column.
$table->dropSoftDeletesTz();Alias of dropSoftDeletes() method.
$table->dropTimestamps();Drop the created_at and updated_at columns.
$table->dropTimestampsTz();Alias of dropTimestamps() method.

索引约束

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

Schema::table('users', function (Blueprint $table) {
    $table->string('email')->unique();
});

$table->unique('email');

$table->index(['account_id', 'created_at']);

$table->unique('email', 'unique_email');
CommandDescription
$table->primary('id');Adds a primary key.
$table->primary(['id', 'parent_id']);Adds composite keys.
$table->unique('email');Adds a unique index.
$table->index('state');Adds an index.
$table->spatialIndex('location');Adds a spatial index (except SQLite).

更改索引

$table->renameIndex('from', 'to')

删除索引(约束)

CommandDescription
$table->dropPrimary('users_id_primary');Drop a primary key from the “users” table.
$table->dropUnique('users_email_unique');Drop a unique index from the “users” table.
$table->dropIndex('geo_state_index');Drop a basic index from the “geo” table.
$table->dropSpatialIndex('geo_location_spatialindex');Drop a spatial index from the “geo” table (except SQLite).

外键约束

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

Schema::table('posts', function (Blueprint $table) {
    $table->unsignedBigInteger('user_id');

    $table->foreign('user_id')->references('id')->on('users');
});

//自动推测
Schema::table('posts', function (Blueprint $table) {
    $table->foreignId('user_id')->constrained();
});

Schema::table('posts', function (Blueprint $table) {
    $table->foreignId('user_id')->constrained('users');
});

外键级联

$table->foreignId('user_id')
      ->constrained()
      ->onUpdate('cascade')
      ->onDelete('cascade');

删除外键

$table->dropForeign(['user_id']);
Categories
php

eloquent 使用

简介eloquent 为laravel中的orm模块

以下代码为orm对象生成命令

php artisan make:model Flight //创建Flight orm 对象
php artisan make:model Flight --migration | -m //生成migration数据库迁移文件
# Generate a model and a FlightFactory class...
php artisan make:model Flight --factory
php artisan make:model Flight -f

# Generate a model and a FlightSeeder class...
php artisan make:model Flight --seed
php artisan make:model Flight -s

# Generate a model and a FlightController class...
php artisan make:model Flight --controller
php artisan make:model Flight -c

# Generate a model and a migration, factory, seeder, and controller...
php artisan make:model Flight -mfsc

生成的基本对象:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Flight extends Model
{
    //optional
    protected $table = 'my_flights';//指定表名
    protected $primaryKey = 'flight_id'; //指定主键
    public $incrementing = false; //主键生成模式
    protected $keyType = 'string';
 //主键数据类型
    public $timestamps = false;
//是否有create 和 update 时间
    protected $dateFormat = 'U';
 //日期格式
    const CREATED_AT = 'creation_date';
 //创建时间字段名
    const UPDATED_AT = 'updated_date';//更新时间字段名
    protected $connection = 'sqlite';
 //指定该orm数据库连接
    protected $fillable = [] //数组 可批量创建的字段
    protected $guard = [] //数组 不可批量创建的字段

    protected $attributes = [
   //字段默认值
        'delayed' => false,
    ];


}

查询方法:

Flight::all

use App\Models\Flight;

foreach (Flight::all() as $flight) {
    echo $flight->name;
}

查询构造器

$flights = Flight::where('active', 1)
               ->orderBy('name')
               ->take(10)
               ->get();

聚合函数

$count = Flight::where('active', 1)->count();

$max = Flight::where('active', 1)->max('price');

对象collection reject方法剔除取消的航班 (闭包返回true)

$flights = Flight::where('destination', 'Paris')->get();

$flights = $flights->reject(function ($flight) {
    return $flight->cancelled;
});

orm游标

use App\Models\User;

$users = User::cursor()->filter(function ($user) {
    return $user->id > 500;
});

子查询

use App\Models\Destination;
use App\Models\Flight;

return Destination::addSelect(['last_flight' => Flight::select('name')
    ->whereColumn('destination_id', 'destinations.id')
    ->orderByDesc('arrived_at')
    ->limit(1)
])->get();

查一条数据

use App\Models\Flight;

// Retrieve a model by its primary key...
$flight = Flight::find(1);

// Retrieve the first model matching the query constraints...
$flight = Flight::where('active', 1)->first();

// Alternative to retrieving the first model matching the query constraints...
$flight = Flight::firstWhere('active', 1);

查到一条或者(闭包)

model = Flight::where('legs', '>', 3)->firstOr(function () {
    // ...
});

查询报notFound fail方法

$flight = Flight::findOrFail(1);

$flight = Flight::where('legs', '>', 3)->firstOrFail();

静态创建

use App\Models\Flight;

// Retrieve flight by name or create it if it doesn't exist...
$flight = Flight::firstOrCreate([
    'name' => 'London to Paris'
]);

// Retrieve flight by name or create it with the name, delayed, and arrival_time attributes...
$flight = Flight::firstOrCreate(
    ['name' => 'London to Paris'],
    ['delayed' => 1, 'arrival_time' => '11:30']
);

// Retrieve flight by name or instantiate a new Flight instance...
$flight = Flight::firstOrNew([
    'name' => 'London to Paris'
]);

// Retrieve flight by name or instantiate with the name, delayed, and arrival_time attributes...
$flight = Flight::firstOrNew(
    ['name' => 'Tokyo to Sydney'],
    ['delayed' => 1, 'arrival_time' => '11:30']
);

对象创建

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Models\Flight;
use Illuminate\Http\Request;

class FlightController extends Controller
{
    /**
     * Store a new flight in the database.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        // Validate the request...

        $flight = new Flight;

        $flight->name = $request->name;

        $flight->save();
    }
}

对象更新

use App\Models\Flight;

$flight = Flight::find(1);

$flight->name = 'Paris to London';

$flight->save();

批量更新

Flight::where('active', 1)
      ->where('destination', 'San Diego')
      ->update(['delayed' => 1]);

对象填充数据

$flight->fill(['name' => 'Amsterdam to Frankfurt']);

按条件更新或创建

$flight = Flight::updateOrCreate(
    ['departure' => 'Oakland', 'destination' => 'San Diego'],//条件
    ['price' => 99, 'discounted' => 1] //数据
);
Flight::upsert([
    ['departure' => 'Oakland', 'destination' => 'San Diego', 'price' => 99],
    ['departure' => 'Chicago', 'destination' => 'New York', 'price' => 150]
], ['departure', 'destination'], ['price']);

删除

use App\Models\Flight;

$flight = Flight::find(1);

$flight->delete();
Flight::destroy(1);

Flight::destroy(1, 2, 3);

Flight::destroy([1, 2, 3]);

Flight::destroy(collect([1, 2, 3]));

查询删除

$deletedRows = Flight::where('active', 0)->delete();

逻辑删除

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Flight extends Model
{
    use SoftDeletes; //多一个deleted_at字段
}

迁移文件

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Facades\Schema;

Schema::table('flights', function (Blueprint $table) {
    $table->softDeletes();
});

Schema::table('flights', function (Blueprint $table) {
    $table->dropSoftDeletes();
});

检查是是否被软删除

if ($flight->trashed()) {
    //
}

还原逻辑删除的数据

$flight->restore();
Flight::withTrashed()
        ->where('airline_id', 1)
        ->restore();
$flight->history()->restore();

强制物理删除

$flight->forceDelete();

和软删除的数据一起查询

$flights = Flight::withTrashed()
                ->where('account_id', 1)
                ->get();

只查询软删除的数据

$flights = Flight::onlyTrashed()
                ->where('airline_id', 1)
                ->get();

对象复制replicate

use App\Models\Address;

$shipping = Address::create([
    'type' => 'shipping',
    'line_1' => '123 Example Street',
    'city' => 'Victorville',
    'state' => 'CA',
    'postcode' => '90001',
]);

$billing = $shipping->replicate()->fill([
    'type' => 'billing'
]);

$billing->save();