วันพุธที่ 15 พฤษภาคม พ.ศ. 2556

Laravel::ELoquent ORM Part 1 การจัดการฐานข้อมูลทีทำให้ SQL ยาวโคตรสั้นไปเลยครับ


Eloquent ORM
คือ Orm ของ laravel ครับแต่ถูกออกแบบมาให้สั้นกว่าเข้าใจได้ง่ายกว่าครับ
อย่างข้างล่างใน framework อื่นเราสืบทอดมาจาก model ใน laravel เราสืบทอดจาก eloquent ครับ
1.  class User extends Eloquent {}


โครงสร้าง
·        ทุกตารางจะมี primary key คือ id ทุกตารางจะใช้ชื่อ Model ตรงๆเลย เพื่อความกระชับและเข้าใจง่าย ถ้าเราอยากใช้ชื่ออื่นเป็นชื่อตาราง หรือคอลัมอื่นเป็น primary key ก็แค่ประกาศครับ
1.  class User extends Eloquent {
2.   
3.       public static $table = 'my_users';
4.   
5.       public static $key = 'my_primary_key';
6.   
7.  }
Retrieving Models
อย่างที่บอกไว้บอกตอนท้ายบทก่อนว่าเราจะย่อให้สั้นอีก บทก่อนเราใช้ DB :: (‘User)-> บททนี้เราย่อให้ชื่อตารางแทนเลย
1.  $user = User::find(1);
2.   
3.  echo $user->email;
ข้างล่างคือ sql ที่ออกมาครับ
1.  SELECT * FROM "users" WHERE "id" = 1
ถ้าจะค้นแบบ ครับ
1.  $users = User::all();
2.   
3.  foreach ($users as $user)
4.  {
5.       echo $user->email;
6.  }
ฟังชันอะไรที่ใช้ในบทก่อน เราก็ใช้ได้ในบทนี้ครับ
1.  $user = User::where('email', '=', $email)->first();
2.   
3.  $user = User::where_email($email)->first();
4.   
5.  $users = User::where_in('id', array(1, 2, 3))->or_where('email', '=', $email)->get();
6.   
7.  $users = User::order_by('votes', 'desc')->take(10)->get();
Aggregates
เหมือนบทก่อนเลยครับแต่ย่อได้อีก
1.  $min = User::min('id');
2.  $max = User::max('id');
3.  $avg = User::avg('id');
4.  $sum = User::sum('id');
5.  $count = User::count();
1.  $count = User::where('id', '>', 10)->count();
 Inserting & Updating Models
การ insert ก็แค่สร้าง object ใหม่แล้วเรียกใช้แต่ละคอลัมในตารางนั้น แล้วก็เรียกฟังก์ชัน save ครับ
1.  $user = new User;
2.   
3.  $user->email = 'example@gmail.com';
4.  $user->password = 'secret';
5.   
6.  $user->save();
ใช้ create ในการสร้าง column ใหม่ครับ
$user = User::create(array('email' => 'example@gmail.com'));
จะแก้ไขก็ง่ายๆ ครับ หาข้อมูลแถวที่เราจะแก้ไขแล้วก็แทรกข้อมูลที่เราจะแก้ไขลงไปก็เสร็จแล้ว
1.  $user = User::find(1);
2.   
3.  $user->email = 'new_email@gmail.com';
4.  $user->password = 'new_secret';
5.   
6.  $user->save();
เราอยากจะบันทึกเวลาการสร้างหรือแก้ไขข้อมูลลงไปด้วย ง่ายๆเลยครับ ด้วยการใช้ฟังก์ชันข้างล่าง
class User extends Eloquent {
1.   
2.       public static $timestamps = true;
3.   
4.  }
เราต้องสร้างคอลัมน์ชื่อ created_at กับ updated_at ไว้ด้วยนะครับ laravel จะบันทึกข้อมูลเวลาลงในคอลัมทั้งสองโดยอัตโนมัติ

บางครั้งเราอยากจะแก้ไขคอลัม updated_at ในตอนที่เราไม่ได้แก้ไขข้อมูล อาจจะเป็นเรียกขึ้นมาดูเฉยก็ใช้ ฟังก์ชัน touch เลยครับ
1.  $comment = Comment::find(1);
2.  $comment->touch();
หรือจะใช้ฟังก์ชัน timestamp แทนก็ได้ครับ
1.  $comment = Comment::find(1);
2.  $comment->timestamp();
3.  //do something else here, but not modifying the $comment model data
4.  $comment->save();
Relationships(การเชื่อมตาราง)
การเชื่อมตารางของ laravel  มี รูปแบบ ครับ
has_one  =  แบบ ต่อ 1                                belongs_to แบบกลุ่มต่อ 1
has_many  = 
แบบ 1 ต่อ กลุ่ม              has_many_and_belongs_to = แบบกลุ่มต่อกลุ่ม
ต่อ 1
จากตัวอย่าง ผู้ใช้งานหนึ่งคนมีโทรศัพท์หนึ่งเครื่อง
1.  class User extends Eloquent {
2.   
3.       public function phone()
4.       {
5.            return $this->has_one('Phone');
6.       }
7.   
8.  }
เวลาจะใช้งานก็เป็นแบบนี้เลยครับ
$phone = User::find(1)->phone()->first();

จากข้างบนถ้าจะเขียนเป็น Sql ธรรมดาก็จะเป็นแบบนี้ครับ
1.  SELECT * FROM "users" WHERE "id" = 1
2.   
3.  SELECT * FROM "phones" WHERE "user_id" = 1
ปกติ Eloquent จะตรวจว่าคอลัมไหนเป็นคีย์เชื่อมจาก ชื่อคอลัมน์_id” ถ้าคีย์เชื่อมของเราไม่เป็นรูปแบบตามนั้นก็สามารถเปลียนโดยเพิ่ม พารามิเตอร์ตัวที่สองไปเหมือนตัวอย่างข้างล่างครับ 
1.  return $this->has_one('Phone', 'my_foreign_key');
เหมือนกับ framework ตัวอื่นนะครับการดึงข้อมูลก็จะเป็นแบบลูกโซ่ ที่จะไปดึงตัวที่ตารางนั้นไปเชิ่อมมาด้วย
1.  $phone = User::find(1)->phone;
ถ้าเราเอาคีย์เชิ่อมไปวางไว้ที่ตารางไหน ตารางที่เอาไปวางไว้นั้นก็ต้องวาง belongs_to ไว้ เพื่อบอกว่า phone สังกัดอยู่กับ user
1.  class Phone extends Eloquent {
2.   
3.       public function user()
4.       {
5.            return $this->belongs_to('User');
6.       }
7.   
8.  }
เมื่อเชื่อมกันแล้วจะค้นหาข้อมูลที่เกี่ยวข้องกันก็ง่ายหละครับ
1.  echo Phone::find(1)->user()->first()->email;
2.   
3.  echo Phone::find(1)->user->email;


1-ต่อ-กลุ่ม
ยกตัวอย่าง บทความมีหลายความคิดเห็น  กรณีนี้เราก็ต้องใช้ has_many หละครับ:
1.  class Post extends Eloquent {
2.   
3.       public function comments()
4.       {
5.            return $this->has_many('Comment');
6.       }
7.   
8.  }
เวลาเราจะค้นก็เหมือนข้างล่างเลยครับ
1.  $comments = Post::find(1)->comments()->get();
2.   
3.  $comments = Post::find(1)->comments;
ตัวอย่างแรกจะเป็นการค้น posts ต่อมาเป็นการค้น comments
1.  SELECT * FROM "posts" WHERE "id" = 1
2.   
3.  SELECT * FROM "comments" WHERE "post_id" = 1
เราย่อคำสั่ง sql ยาวให้เข้าใจง่ายภายในบรรทัดเดียวได้เลย:
1.  echo Post::find(1)->comments()->order_by('votes', 'desc')->take(10)->get();
กลุ่ม-ต่อ-กลุ่ม
ความสัมพันธ์แบบกลุ่มต่อกลุ่ม มักจะมีความยุ่งยากมาก หลาย framework ก็ยังจัดการได้ไม่ค่อยดี. For example, ยกตัวอย่าง ผู้ใช้งานมีได้หลายสิทธิ์,แต่ละสิทธ์ก็มีได้ในผู้ใช้หลายคน.ตารางสามอันนี้ทำให้เกิดความงงขึ้นได้บ่อยเลยครับ ตารางผู้ใช้งานตารางสิทธิ์ตารางบอกว่าใครทำอะไรได้บ้างโครงสร้างจะเป็นแบบตัวอย่าง
users:
1.  id    - INTEGER
2.  email - VARCHAR
roles:
1.  id   - INTEGER
2.  name - VARCHAR
role_user:
1.  id      - INTEGER
2.  user_id - INTEGER
3.  role_id - INTEGER
ใน laravel จะใช้ has_many_and_belongs_to สั้นๆ เลยครับ
class User extends Eloquent {
1.   
2.       public function roles()
3.       {
4.            return $this->has_many_and_belongs_to('Role');
5.       }
6.   
7.  }
เวลาจะค้นก็แบบนี้เลยครับง่ายมาก ข้างล่างเราจะค้นว่า  user  นี้ มี  role  อะไรบ้าง
$roles = User::find(1)->roles()->get();
เวลาจะค้นว่ามีผู้ใช้กี่คนที่มีสิทธิ์นี้ก็ตามข้างล่างเลยครับ
1.  $roles = User::find(1)->roles;

ถ้าคีย์ที่ใช้เชื่อมไม่เหมือนกับที่ laravel เราก็แค่ส่งพารามิเตอร์ไปบอกด้วย
1.  class User extends Eloquent {
2.   
3.       public function roles()
4.       {
5.            return $this->has_many_and_belongs_to('Role', 'user_roles');
6.       }
7.   
8.  }
โดยค่าเริ่มต้น ตารางที่ใช้เชื่อมจะส่งแค่ค่า id
1.  class User extends Eloquent {
2.   
3.       public function roles()
4.       {
5.            return $this->has_many_and_belongs_to('Role', 'user_roles')->with('column');
6.       }
7.   
8.  }
เ   ว่างๆจะมาต่อ Part 2 นะครับ



ไม่มีความคิดเห็น:

แสดงความคิดเห็น