จาก entry ที่ rails66
สนุกกับ Active Record: ค้น, ค้น, ค้น

มาดู version ของ Grails บ้างครับว่าเป็นอย่างไร เทียบกันแบบ 1 ต่อ 1 ไปเลย เพื่อความมันส์ ขออ้างอิงจาก entry ของคุณ cblue ที่ สนุกกับ ActiveRecord ภาคเกรลส์

class Writer {
	String firstname
	String lastname
}

สร้างข้อมูลกันก่อนครับ

import Writer
def writer1 = new Writer( firstname:"John", lastname:"Bestman")
writer1.save()
def writer2 = new Writer( firstname:"Mary", lastname:"Happy")
writer2.save()

มันไม่สวยเท่าไรที่สร้างนักเขียนแบบนี้ แหม… อายจังครับ [ต้องพูดแบบบุญชูนะครับ] แต่ยังหน้าด้านหน้าทนต่อไปครับ เอาไว้จะปรับปรุงครับ [ ขอติดค้างไว้ก่อนครับ ]

มาดูส่วนการค้นหากัน เทียบกันไปเลย

1. ดูนักเขียนทั้งหมด เอา 2 กระบวนท่าแรกมาโชว์ก่อนครับ
>>Writer.getAll()
>>Writer.list()

2. ดูนักเขียนคนแรก โอ้ว ต้องไปงัดกลยุทธมาหน่อย ใช้ offset กับ max ช่วยจ้า มันดูขัดหูขัดตาไปไหมครับ ????
>>Writer.list( max:1 )

ถ้ามี Writer.getFirst(); คงจะดีไม่น้อย หรือว่ามี แต่คงใช้กระบวนท่าเยอะ งั้นขอผ่านไปก่อนครับ [ 2 ครั้งแล้วนะครับ ]

3. เลือกคนที่มี id เป็น 2 อันนี้เข้าทางหน่อย
>>Writer.get(2)
หรือ
>>Writer.getAll( [ 2 ] )

คำถาม : แล้วแบบนี้มีไว้ทำไม ??
คำตอบ : มีไว้แบบนี้ครับ Writer.getAll( [ 1,4,6,5 ] ) ….ใส่ list ของ id มาได้เลย ซื้อไหมครับ อิอิอิ ???

4. หาชื่อนักเขียนที่ขึ้นต้นว่า John
:: ต้องการคนเดียว
>>Writer.findByFirstnameLike( “John%”)
:: ต้องการทุกๆ คน
>>Writer.findAllByFirstnameLike( “John%”)

อยากได้อะไรก็ใส่ตามชื่อ property ใน domain class เลยครับ
>>Writer.findAllByLastnameLike( “John%”)

และพวก operator มีให้ใช้เพียบครับ ลองพิจารณาดูครับ

* LessThan – less than the given value
* LessThanEquals – less than or equal a give value
* GreaterThan – greater than a given value
* GreaterThanEquals – greater than or equal a given value
* Like – Equivalent to a SQL like expression
* Ilike – Similar to a Like, except case insensitive
* NotEqual – Negates equality
* Between – Between two values (requires two arguments)
* IsNotNull – Not a null value (doesn’t require an argument)
* IsNull – Is a null value (doesn’t require an argument)

ใน Grails เขาเรียกว่า Power of Dynamic Finder ครับผม หรือเรียกว่า Magic หรือ เวทย์มนต์ ตาม Rails66 ดีครับ ???

โอ้วใน Rails66 เขาเพิ่มอีก domain ชื่อ Book ดังนั้นจัดให้
$grails create-domain-class Book

ได้หน้าตาประมาณนี้

class Book {
	String title
	Integer pages
	Date published_at
}

สร้างข้อมูลเลียนแบบ ให้เหมือนกันไปเลย สร้างแบบหน้าไม่อายอีกแล้วววววววว

def book1 = new Book( title:"Groovy on Grails", pages:450, published_at:new Date( ) )
book1.save()
def book2 = new Book( title:"Groovy Programming" , pages:320, published_at:new Date( ))
book2.save()
def book3 = new Book( title:"AJAX", pages:300, published_at:new Date( ))
book3.save()
def book4 = new Book( title:"Agorithm", pages:1000, published_at:new Date( ) )
book4.save()

ต่อมาทำการค้นหากันต่อครับ

1. ค้นหาหนังสือ ที่มีจำนวนหน้ามากกว่า 400 หน้า
>>Book.findAllByPagesGreaterThan( 400 )
หรือจะเอา >= 400 ก็ยังได้ครับ
>>Book.findAllByPagesGreaterThanEquals( 400 )

ดังนั้นเรื่อง parameter ที่ส่งเข้าไปใน Dynamic Finders methods นั้นไม่ต้องกังวลครับ อิอิอิ
ส่วนเรื่องวันที่ก็สามารถใช้ GreaterThan … Between และอื่นๆ ได้ตามอัธยาศัยครับ

ส่วนเรื่องของการเรียงลำดับนั้นไม่ได้ยากเย็นอะไรครับ เพียงทำตามนี้
โดยจะค้นหาหนังสือที่มีจำนวนหน้ามากกว่า 400 หน้า และเรียงด้วย title โดยเรียงแบบจากน้อย ไปมาก [a-z] ครับ
>>Book.findAllByPagesGreaterThan( 400, [ sort:"title", order:"asc" ] )
หรือจากมากไปน้อย [ z-a ]
>>Book.findAllByPagesGreaterThan( 400, [ sort:"title", order:"desc" ] )

มาดูการทำ paging ครับ
กำหนดให้
- แสดงหน้าละ 1 => max = 1
- หน้าที่ 1 หรือ page=1 => offset = ( max ) * ( page – 1 )
สามารถเขียนได้ดังนี้
>>Book.findAllByPagesGreaterThan( 400, [ max:1, offset:0,sort:"title", order:"desc" ] )

อ้อ… ทิ้งท้ายเหมือนกับ Rails66 หน่อยครับ การสุ่มแถวจาก Domain class ครับ
>>def offset = new Random().nextInt( Book.count() )
>>Book.list( max:1, offset:offset )

ตกหล่นตรงไหน บอกกล่าวได้เลยครับ ผมเพิ่งเริ่มศึกษาเหมือนกันครับ ….

ผมลองเปรียบเทียบเชิงภาษาครับว่าแตกต่างอย่างไร ซึ่งแน่นอนครับมีทั้งข้อดีและข้อเสียตามที่ผมอธิบายไปครับ ถ้านำข้อดีของทั้งสองภาษามารวมกัน ….. คิดดูครับจะเป็นอย่างไร
ถ้าไปดูข้อดีของภาษาอื่นอีก แล้วเอามาใช้ … จะดีไหมครับ …. พอจะตรงตามแนวคิด PAW 2.0 หรือเปล่าครับ
สามารถดูเพิ่มเติมได้ที่
Querying with GORM

Tags: , ,

14 Responses to “สนุกกับ Active Record ภาค Grails : ค้น, ค้น, ค้น”

  1. @up1
    เพิ่ม tag “newbie” ให้ด้วยนะครับพี่

    … แล้วก็ ; ครับ kill’em all !!!

  2. getFirst เราใช้ Writer.list( max:1 ) น่าจะพอได้ครับ

    ไม่น่ามีในเกรลส์ แบบนี้ต้อง patch ครับ

  3. ขอบคุณมากครับ

    ปล. ยังติดเขียนมี ; อยู่เลยครับ มันไปโดยอัตโนมัติครับ [ สงสัยจะอยู่ในสายเลือด 5555 ]

  4. Writer.list( max:1 )

    ผมว่ามันไม่ make sense เท่าไรครับ….

    เห็นด้วยอย่างยิ่ง ต้องมี patch ครับ …

  5. แล้ว first นี่เรียงตามอะไรครับ

  6. มี content ล้อกันตลอดเลยนะ

  7. ตาม idea แล้ว default น่าจะเรียงตาม id นะครับ ซึ่งผมคิดว่ามัน make sense

    แต่ถ้าสามารถใส่ว่า sort ด้วย column อะไรด้วยนี่แจ๋วไปเลย เช่น
    >>Writer.getFirst( sort:”column_name” )

    แต่ถ้าเรียงตาม id
    >>Writer.getFirst()

  8. ครับ ผมคิดว่าที่เขาไม่มีเพราะ method มันชวนสงสัยว่าจะเรียงตามอะไรกันแน่ และดูประโยชน์จากการใช้งานจริงดูเหมือนจะไม่มี ถ้าเป็นแบบมี parameter น่าจะมีประโยชน์ครับ แต่ก็อาจจะซ้ำซ้อนกับ method อื่น อย่างที่คุณ cblue เสนอ

  9. @admin
    > มี content ล้อกันตลอดเลยนะ

    นี่ไงที่ @sugree บอกไว้ใน blog http://sugree.com/node/246
    แลกหมัดกันด้วยโค้ดครับ

  10. ^^^^ งั้น grails66 ไปหาแลกหมัดที่อื่นอีกครับ เพื่อความมันส์ และจะได้เปิดมุมมองด้วยครับ

  11. @up1

    ที่ผม port python twitter client ของ @sugree เป็นต้นครับ
    คนเปิดอะไรมา เราจะเก็บหมดด้วย Groovy syntax ครับ

    ไม่เว้นแม้แต่ flex แต่อาจจะเหนื่อยหน่อย (กับ flex เราสู้ด้วยกริฟฟอนละกันพี่)

  12. ใน rails ปกติ find :first มักใส่กับ :o rder ตามที่ @up1 คาดไว้ครับ

Trackbacks/Pingbacks

  1. เร็วส์ หกสิบหก » Blog Archive » สนุกกับ Active Record: การเชื่อมโยง (1)
  2. สนุกกับ Active Record: การเชื่อมโยง (1) « Jittat

Leave a Reply