drwkqwa82140 2018-10-12 03:44 采纳率: 0%
浏览 1025

在使用laravel插入数据之前检查数据库并避免重复

我试图在插入数据之前检查数据库以避免重复。 我将URL存储在数组中,然后将这些URL插入表的“链接”列中。 所以首先我要检查该列,是否设置相同的URL? 如果不是,则使用此代码插入数据。 这是我完整的数据库插入代码:
foreach ($outlineUrls  as $outlineUrl) {
    $html = file_get_contents($outlineUrl);
    $DOMParser = new \DOMDocument();
    $DOMParser->loadHTML($html);


    $changeForMyDB = [
                            'remote_id' => '',
                            'region' => '関西',
                            'link' => json_encode($outlineUrl),
                            'name' => '',
                            'price' => '',
                            'extend' => '',
                            'address' => '',
                            'hows_old' => '',
                            'rooms' => '',
                            'old' => '',
                            'entery' => '',
                            'balcon_m2' => '',
                            'company_name' => '',
                            'script_from' => ''
                        ];

            $allPTags = $DOMParser->getElementsByTagName('p');
            foreach($allPTags as $ptag){
                if($ptag->getAttribute('class') == 'c-name'){
                        $changeForMyDB['name'] = trim($ptag->nodeValue);
                }
            }

            $changeForMyDB['address'] = trim($DOMParser->getElementsByTagName('dd')[0]->nodeValue);

            $allTables = $DOMParser->getElementsByTagName('table');
            foreach($allTables as $table){
                foreach($table->getElementsByTagName('tr') as $tr){
                    $property = trim($tr->getElementsByTagName('th')[0]->nodeValue);
                    $value = trim($tr->getElementsByTagName('td')[0]->nodeValue);

                    switch ($property) {
                        case '物件名':
                            $changeForMyDB['name'] = $value;
                            break;
                        case '販売価格':
                            $changeForMyDB['price'] = $value;
                            break;
                        case '専有面積':
                            $changeForMyDB['extend'] = $value;
                            break;
                        case '所在地':
                            $changeForMyDB['address'] = $value;
                            break;
                        case '総戸数':
                            $changeForMyDB['hows_old'] = $value;
                            break;
                        case '間取り':
                            $changeForMyDB['rooms'] = $value;
                            break;
                        case '竣工時期':
                            $changeForMyDB['old'] = $value;
                            break;
                        case '管理会社':
                            $changeForMyDB['company_name'] = $value;
                            break;
                        case '入居時期':
                            $changeForMyDB['entery'] = $value;
                            break;
                        case '入居時期':
                            $changeForMyDB['entery'] = $value;
                            break;
                        case 'バルコニー面積':
                            $changeForMyDB['balcon_m2'] = $value;
                            break;
                        default:
                            # code...
                            break;
                    }
                }
            }

if(Estates::where('link','=',$outlineUrl)->count() > 0)
{

   $this->error('There is link.');

} else {

        Estates::insertGetId($changeForMyDB);

        $this->line('Data saved.');

       }

但问题就在这里。它没有检查就插入了数据! 你知道是什么问题吗?谢谢你的帮助。

  • 写回答

1条回答 默认 最新

  • duangan4406 2018-10-12 04:30
    关注

    You can use the updateOrCreate() method to achieve the goal of only inserting if the record does not exist:

    $estate = Estates::updateOrCreate(['link' =>  $outlineUrl], $changeForMyDB);
    

    This will check if there is an Estate::where('link', '=', $outlineUrl). If none is found, it will create a new Estate´ and add all data from$changeForMyDBto it. If one exists, it will fetch it from the database, add all data from$changeForMyDB`. Then it will persist the changes. Read more about that here: https://laravel.com/docs/5.7/eloquent#other-creation-methods


    To avoid issues with concurrent requests, you should also wrap your update within a database transaction. This ensures that the database has the same state when you checked for uniqueness as when you store your data.

    DB::transaction(function () {
        $estate = Estates::updateOrCreate(['link' =>  $outlineUrl], $changeForMyDB);
    });
    

    If you don't want to update existing entries, use something like this:

    DB::transaction(function () {
        if (Estates::where('link','=',$outlineUrl)->count() === 0) {
            $estate = Estates::create($changeForMyDB);
        }
    });
    

    Beware that Estates::create($data) and Estates::insert($data) are not the same. The create($data) function will create a model, fill it with the $data and return the persisted model. It will also fire all Eloquent events that are relevant for the create method. The insert($data) method on the other hand will not create an Eloquent model and will therefore also not fire any Eloquent events. It will directly insert the data into the database. This is more lightweight and faster, but you should keep that in mind.


    If you want to check if the record already existed and report some kind of error, you can check with this:

    if (!$estate->wasRecentlyCreated()) {
        // report error here
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥15 thinkphp6配合social login单点登录问题
  • ¥15 HFSS 中的 H 场图与 MATLAB 中绘制的 B1 场 部分对应不上
  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch