จาก 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
September 11th, 2008 at 3:12 pm
@up1
เพิ่ม tag “newbie” ให้ด้วยนะครับพี่
… แล้วก็ ; ครับ kill’em all !!!
September 11th, 2008 at 3:16 pm
getFirst เราใช้ Writer.list( max:1 ) น่าจะพอได้ครับ
ไม่น่ามีในเกรลส์ แบบนี้ต้อง patch ครับ
September 11th, 2008 at 3:17 pm
ขอบคุณมากครับ
ปล. ยังติดเขียนมี ; อยู่เลยครับ มันไปโดยอัตโนมัติครับ [ สงสัยจะอยู่ในสายเลือด 5555 ]
September 11th, 2008 at 3:19 pm
Writer.list( max:1 )
ผมว่ามันไม่ make sense เท่าไรครับ….
เห็นด้วยอย่างยิ่ง ต้องมี patch ครับ …
September 11th, 2008 at 3:23 pm
แล้ว first นี่เรียงตามอะไรครับ
September 11th, 2008 at 3:25 pm
มี content ล้อกันตลอดเลยนะ
September 11th, 2008 at 3:30 pm
ตาม idea แล้ว default น่าจะเรียงตาม id นะครับ ซึ่งผมคิดว่ามัน make sense
แต่ถ้าสามารถใส่ว่า sort ด้วย column อะไรด้วยนี่แจ๋วไปเลย เช่น
>>Writer.getFirst( sort:”column_name” )
แต่ถ้าเรียงตาม id
>>Writer.getFirst()
September 11th, 2008 at 3:33 pm
ครับ ผมคิดว่าที่เขาไม่มีเพราะ method มันชวนสงสัยว่าจะเรียงตามอะไรกันแน่ และดูประโยชน์จากการใช้งานจริงดูเหมือนจะไม่มี ถ้าเป็นแบบมี parameter น่าจะมีประโยชน์ครับ แต่ก็อาจจะซ้ำซ้อนกับ method อื่น อย่างที่คุณ cblue เสนอ
September 11th, 2008 at 3:57 pm
@admin
> มี content ล้อกันตลอดเลยนะ
นี่ไงที่ @sugree บอกไว้ใน blog http://sugree.com/node/246
แลกหมัดกันด้วยโค้ดครับ
September 11th, 2008 at 4:04 pm
^^^^ งั้น grails66 ไปหาแลกหมัดที่อื่นอีกครับ เพื่อความมันส์ และจะได้เปิดมุมมองด้วยครับ
September 12th, 2008 at 2:04 am
@up1
ที่ผม port python twitter client ของ @sugree เป็นต้นครับ
คนเปิดอะไรมา เราจะเก็บหมดด้วย Groovy syntax ครับ
ไม่เว้นแม้แต่ flex แต่อาจจะเหนื่อยหน่อย (กับ flex เราสู้ด้วยกริฟฟอนละกันพี่)
September 13th, 2008 at 8:40 am
ใน rails ปกติ find :first มักใส่กับ
rder ตามที่ @up1 คาดไว้ครับ