技术开发 频道

用Groovy实现最简单的ORM

  【IT168 技术文档】小弟关注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
0
相关文章