First they ignore you
then they ridicule you
then they fight you
then you win
    -- Mahatma Gandhi
Chinese => English     英文 => 中文             
随笔-219  评论-1047  文章-0  trackbacks-0

潜水那么久,也该写点东西跟各位朋友分享一下了:-)
小弟关注Groovy已有数月(您可以到Groovy官方网站 http://groovy.codehaus.org 下载),发现其极具魅力,故在我参加的学校'创新试验项目'中,就用它来实现最简易的ORM,做的非常简单,主要原因是没有时间,因为小弟学业繁重,所以抽出一个下午的时间来实现一个简易版的ORM,数据库用的是MySQL。现在简单说明一下所示代码,将User类的一个实例通过save方法保存到数据库中,然后再根据给定条件通过findBy方法从数据库中取出实例,最后删除一个特定实例。由于深知通过XML文件进行配置的痛苦,所以在设计时没有用到任何XML文件。此程序让程序员只需关注自己要处理的对象,而不用关心数据库方面的东西,简化开发过程。最后我想说明的是,由于时间问题,所以编码方面只注重算法的体现,没有考虑其他方面。下面给出的代码仅供演示及参考(源码已经上传,点击下载):

  1   package  edu.ecust.orm
  2
  3  import  groovy.sql.Sql
  4  import  groovy.text.Template
  5  import  groovy.text.SimpleTemplateEngine
  6
  7   public class User   {
  8      private   int  id
  9      private   String name
 10      private   int  age
 11
 12       public  User()   {}
 13
 14       public  User( int  id)   {
 15          this .id  =  id
 16     }

 17
 18       public  User( int  id, String name,  int  age)   {
 19          this.id  =  id
 20          this.name  =  name
 21          this.age  =  age
 22     }

 23
 24       public   int  getId()   {
 25          return  id
 26     }

 27
 28       public   void  setId( int  id)   {
 29          this.id  =  id
 30     }

 31
 32       public  String getName()   {
 33          return  name
 34     }

 35
 36       public   void  setName(String name)   {
 37          this.name  =  name
 38     }

 39
 40       public   int  getAge()   {
 41          return  age
 42     }

 43
 44       public   void  setAge( int  age)   {
 45          this.age  =  age
 46     }

 47
 48
 49
 50       public  String toString()   {
 51          return  name  +  "(#"   + id + ""  + age + ")"
 52     }

 53 }

 54
 55 typemap  =  [ "int" : "INTEGER" ,  "java.lang.Integer" : "INTEGER" ,  "long" : "BIGINT" ,  "java.lang.Long" : "BIGINT" ,  "short" : "SMALLINT" ,  "java.lang.Short" : "SMALLINT" ,  "byte" : "TINYINT" ,  "java.lang.Byte" : "TINYINT" ,  "float" : "FLOAT" ,  "java.lang.Float" : "FLOAT" ,  "double" : "DOUBLE" ,  "java.lang.Double" : "DOUBLE" ,  "java.math.BigDecimal" : "NUMERIC" ,  "char" : "CHAR(1)" ,  "java.lang.Character" : "CHAR(1)" ,  "java.lang.String" : "VARCHAR(50)" ,  "boolean" : "BIT" ,  "java.lang.Boolean" : "BIT" ]
 56
 57  def capitalize(str)   {
 58     def c  =  str.charAt( 0 )
 59      int  asci  =  ( int )c
 60       if  (asci  >   96   &&  asci  <   123 )   {
 61          return  (( char )(asci  -   32 )).toString()  +  str.substring( 1 )
 62     }

 63 }

 64
 65 def user  =   new  User( 1 ,  "Daniel" ,  21 )
 66
 67  def connect()   {
 68      return  Sql.newInstance(
 69          "jdbc:mysql://localhost:3306/orm" ,  "root" ,
 70      "1106" ,  "com.mysql.jdbc.Driver" )
 71 }

 72
 73  def pointToLine(str)   {
 74      return  str.replaceAll( "\\p{Punct}" ,  "_" )
 75 }

 76
 77  def getFields(u)   {
 78     def clazz  =  u.getClass()
 79     def fields  =  clazz.getDeclaredFields()
 80     def fieldunit  =  [:]
 81       for  (f in fields)   {
 82         def fstr  =  f.toString()
 83           if  (fstr.startsWith( "private" ))   {
 84             def fieldname  =  fstr.substring(fstr.lastIndexOf( "." )  +   1 )
 85             def methodname  =   "get"   +  capitalize(fieldname)
 86              fieldunit.put(fieldname, clazz.getMethod(methodname).invoke(u))
 87         }

 88     }

 89
 90      return  fieldunit
 91 }

 92
 93  tablename = "";
 94  def save(u)   {
 95     def clazz  =  u.getClass()
 96     def classname  =  clazz.getName()
 97     def classunit  =  [:]
 98     fieldunit  =  getFields(u)
 99     classunit.put(classname, fieldunit)
100     def keySet  =  classunit.keySet()
101     def it  =  keySet.iterator()
102     def fields
103       while  (it.hasNext())   {
104         tablename  =  it.next()
105         fields  =  classunit.get(tablename)
106     }

107     tablename  =  pointToLine(tablename)
108     def fkeySet  =  fields.keySet()
109     def fit  =  fkeySet.iterator()
110       def creationstmt  =   ""
111
112       def order  =  [:]
113       def num  =   0
114     while  (fit.hasNext())   {
115       def fieldname  =  fit.next()
116       def fieldvalue  =  fields.get(fieldname)
117         if  ( "id"   ==  fieldname)   {
118           creationstmt  +=   "id INTEGER PRIMARY KEY not null,"
119        }
   else    {
120           creationstmt  +=  fieldname  +   " "   +  typemap.get(fieldvalue.getClass().getName())  +   ","
121       }

122       order.put(num++ , fieldname)
123   }

124   creationstmt  =  creationstmt.substring( 0 , creationstmt.length()  -   1 )
125   def valuestr  =   "("
126   def vkeySet  =  order.keySet()
127   def vit  =  vkeySet.iterator()
128   params  =   "("
129     while  (vit.hasNext())   {
130       def elem  =  vit.next()
131       def v  =  order.get(elem)
132       valuestr  +=   "'\${"   +  v  +   "}',"
133       params  +=   "`"   +  v  +   "`,"
134   }

135   valuestr  =  valuestr.substring( 0 , valuestr.length()  -   1 )
136   params  =  params.substring( 0 , params.length()  -   1 )
137   valuestr  +=   ")"
138   params  +=   ")"
139   def insertstmt  =   "INSERT INTO `"   +  tablename  +   "`"   +  params  +   " VALUES"
140   insertstmt  +=  valuestr
141   def engine  =   new  SimpleTemplateEngine()
142   def template  =  engine.createTemplate(insertstmt).make(fields)
143   insertstmt  =  template.toString()
144   def createstmt  =   """
145          CREATE TABLE IF NOT EXISTS `"""  + tablename +  """`
146         (
147              """  + creationstmt +  """
148         );
149      """
150       try    {
151                 def sql  =  connect()
152                 sql.execute(createstmt)
153                 sql.execute(insertstmt)
154
155              }
   catch  (Exception e)   {
156                 int id = u.getId()
157                 id++
158                 u.setId(id)
159                 save(u)
160                 //println e.getMessage()
161             }

162
163      return  u.getId()
164 }

165
166 def delete(u) {
167    try {
168        def id = u.getId()
169        def sql  =  connect()
170        def result = sql.execute("DELETE FROM `" + tablename + "` WHERE id=" + id);
171        println "delete operation completed!"
172    }
 catch (Exception e) {
173        println e.getMessage()
174    }

175 }

176
177  def findBy(classname, condition)   {
178     def sql  =  connect()
179     objs  =  []
180     sql.eachRow( "select * from "   +  pointToLine(classname)  +   " where "   +  condition)   {
181     obj  =  Class.forName(classname).newInstance()
182
183     def clazz  =  obj.getClass()
184     def fields  =  clazz.getDeclaredFields()
185     def methods  =  clazz.getDeclaredMethods()
186     for  (f in fields)   {
187             def fstr  =  f.toString()
188               if  (fstr.startsWith( "private" ))   {
189                 def fieldname  =  fstr.substring(fstr.lastIndexOf( "." )  +   1 )
190                 def setmethodname  =   "set"   +  capitalize(fieldname)
191                 def setmethod
192                   for  (m in methods)   {
193                     def methodname  =  m.toString()
194                       if  (methodname.contains(setmethodname))   {
195                         setmethod  =  m
196                     }

197                 }

198                 def fieldvalue  =  it.getProperty(fieldname)
199                 setmethod.invoke(obj, fieldvalue)
200             }

201         }

202
203         objs.add(obj)
204   }

205
206      return  objs
207 }

208
209 println "Id of the saved object is " + save(user)
210 println "Found " + findBy( "edu.ecust.orm.User" ,  "id = '11'" )
211 userToDelete = new User(12"Daniel"21)
212 delete(userToDelete)
213
posted on 2006-08-29 14:13 山风小子 阅读(2906) 评论(2)  编辑  收藏 所属分类: Groovy & Grails