作者:江南白衣
前篇:〈在Spring+Hibernate框架下,用動(dòng)態(tài)語(yǔ)言寫業(yè)務(wù)類〉講述在Spring+Hibernate的架構(gòu)下,因?yàn)閯?dòng)態(tài)語(yǔ)言所帶來(lái)的利益,把一部分業(yè)務(wù)類改用Groovy編寫并編譯成Java Class文件。
而且,因?yàn)镚roovy的強(qiáng)大與簡(jiǎn)便,加上與Java親密無(wú)間的關(guān)系,一些框架類也可以逐漸考慮用Groovy編寫。
1.雖然多是星零的好處,但忽然間一整噸好處擺在面前還是很讓人感動(dòng)的。
除了動(dòng)態(tài)語(yǔ)言和閉包、MOP,Groovy其他的特性多是對(duì)J2SE中設(shè)計(jì)不合理的地方逐一進(jìn)行修正,集合、IO、字符串操作......雖然多是星零的好處,但忽然間以整噸好處擺在面前還是挺讓人感動(dòng)的。
同時(shí),Groovy完全兼容Java語(yǔ)法,但又提供糖糖選擇的方式感覺很貼心。(Groovy唯一不支持的java語(yǔ)法就是Inner Class的定義和函數(shù)定義里的"throws Exception" , 私生子的好處啊)
隱約覺得因?yàn)閯?dòng)態(tài)語(yǔ)言的無(wú)類型,還有閉包這樣帶著Lisp式FP的印記,加上MOP這樣的機(jī)制,可能會(huì)激發(fā)更大的變革發(fā)生。
1.動(dòng)態(tài)類型
動(dòng)態(tài)類型在Framework型項(xiàng)目中非常重要,多少設(shè)計(jì)模式嘔心瀝血,就是為了和這個(gè)類型搏斗。
而且,如果你是把代碼編譯成java Class,健壯性不會(huì)減低太多。
2.閉包
fp的基礎(chǔ),沒有閉包的C++用函數(shù)指針,java用匿名內(nèi)部類,都比他差遠(yuǎn)了。
詳看Matin Flower <閉包>文章的中文版 ,在一段文件操作的Script中試演了一下,果然使代碼簡(jiǎn)潔了好些。
3. MOP
Groovy的Team Leader-- Guillaume Laforge最喜歡的一樣特性,groovy 嵌入式XML語(yǔ)法的基礎(chǔ),對(duì)屬性和方法訪問的intercept 機(jī)制。詳看另一篇blog。
又比如,在MOP下,DAO那一堆findByName,findByTitle不用再逐一實(shí)現(xiàn)了,實(shí)現(xiàn)一個(gè)findBy即可攔截其他子虛烏有的findByXXX。
4. b.hql 可以多行,不用寫N多"和+ , 寫sql時(shí)特別方便。
c.簡(jiǎn)單集成了正則表達(dá)式
If ("name"==~ "na.*")
{println "match!"}
5. 集合與循環(huán)的語(yǔ)法
for (car in cars) { println car }
for ( e in map ) { x += e.value}
或者
car.each{print it}
集合也可以直接定義了,如
def myList = ["Rod", 3, Date()]
def myMap = ["Neeta":31, "Eric":34]
6.為JDK的基礎(chǔ)類擴(kuò)展了一系列Helper方法
//原來(lái)StringTokenizer類的功能被簡(jiǎn)單的集成到String類中了
names.tokenize(",").each{......}
其他基礎(chǔ)類的擴(kuò)展見Groovy-JDK
//自動(dòng)生成Getter和Setter重新使對(duì)象的屬性public,對(duì)java濫用getter,setter是一種修正。
class Customer
{
Integer id;
String name;
}
//簡(jiǎn)便的對(duì)象賦值
customer = new Customer(id:1, name:"calvin");
customer2 = new CUstomer(id:2);
8. Object內(nèi)建的反射語(yǔ)法
customer.getAt("name") //得到屬性name,
customer.invokeMethod("someFunction") //調(diào)用方法someFunction
從此不再需要Apache BeanUtils。
9.GPath--內(nèi)置的XML語(yǔ)法,和Fremarker類似。
傳說(shuō)中JDK7.0的功能 jdom和Dom4j可以安息了
book = new XmlSlurper().parseText("<book writer='calvin'><title>D</title></book>")
println book.title;
println book[@writer];
println book.children().size();
10.運(yùn)算符重載
//向數(shù)組添加對(duì)象
params << customer.getAt(it);
還有如C++的向String,InputStream添加對(duì)象.
還有集合類相加,如list1+list2
11.簡(jiǎn)化了IO操作
12.省略了每行末尾的分號(hào)
既然每行都要的,何必多此一舉呢?
另外return語(yǔ)句也可以省略,不過我還是習(xí)慣寫:)
2.Groovy版CustomerDAO的示例:
package com.itorgan.myappfuse.dao;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
public class CustomerDAOGroovy extends HibernateDaoSupport
{
public insert(customer)
{
getHibernateTemplate().save(customer)
}
public List getAllValid(sortColumn)
{
def hql = """from Customer customer
where customer.status='valid'
order by ${sortColumn}"""
def query = getSession().createQuery(hql)
return query.list()
}
public boolean isUnique(customer, uniqueColumnNames)
{
def params = []
def hql = "select count(*) from Customer customer where "
def first = true
uniqueColumnNames.tokenize(",").each
{
if (!first)
hql += " or "
else
first = false
hql+="customer.${it}=?"
params << customer.getAt(it)
}
def result = getHibernateTemplate().find(hql,params.toArray())
return ( result.get(0) == 0)
}
}
asm.jar包的沖突問題?
hibernate 需要asm.jar是1.53版本
groovy1.0 需要 asm-2.2.jar版本
兩者好像不能兼容?
把Hibernate所依賴的cglib 換成cglib-nodep-2.1_3.jar
則hibernate不再依賴的asm.jar