潜水那么久,也该写点东西跟各位朋友分享一下了:-)
小弟关注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
山风小子 阅读(3106)
评论(2) 编辑 收藏 所属分类:
Groovy & Grails