写这个
				OR Mapping
				层的初衷是因为一个朋友租了个虚拟主机,并试图开发一个小系统来扩展自己公司的业务,但因为虚拟主机的限制,不能使用他熟悉的
				Hibernate
				,他有不想写繁琐的
				JDBC
				,于是要我帮忙写一个简单的
				OR Mapping
				层。根据他的具体要求,我将这个小引擎的目标定为:
		
		
				
						1.  
				
				在
				JDBC API
				上建立简单的包装。
		
		
				
						2.  
				
				优化代码,使资源占用(
				CPU, RAM
				)尽量少
		
		
				
						3.  
				
				不支持事务处理
		
		
				
						4.  
				
				不支持分布式应用
		
		
				
						5.  
				
				只支持
				MySQL
				和
				ProgressSQL
				两种数据库
		
		
				
						6.  
				
				不需要配置文件
		
		
				
						7.  
				
				尽量少的第三方包依赖
		
		
				
						8.  
				
				实体间关系只处理一对一和一对多两种情况,并且只提供延迟加载方式
		
		
				
						9.  
				
				内置
				Connection Pool
		
		
				
						 
				
		
		
				经过三天的努力,基本的功能已经实现,再经过测试后,准备三月中旬交给朋友用。整个引擎只需要一个
				jar
				文件,
				100k
				左右(不需要其它第三方包,当然,数据库的
				JDBC
				驱动还是需要的
				^O^
				),使用起来也比较简单。对于简单的实体来说,只需要通过注释指定相对应的表和字段就可以了。下面用一个简单的
				Book
				对象来说明:
		
		
				
						 
				
		
		
				首先需要定义一个简单实体对象,并加入注释(支持
				Java 5
				以上环境)
		
		
				
						 
				
		
		
				@DBTable
				(name=
				"Books"
				)
				
						
						
				
		
		
				
						public
				
				
				
				
						class
				
				 Book {
				
						
						
				
		
		
				
						 
				
		
		
				
						    
				
				@DBColumn
				(name=
				"id"
				,type=
				"String"
				,isKey=
				
						true
				
				)
				
						
						
				
		
		
				
						    
				
				
						private
				
				 String 
				id
				;
				
						
						
				
		
		
				
						    
				
				
						
						
				
		
		
				
						    
				
				@DBColumn
				(name=
				"name"
				,type=
				"String"
				)
				
						
						
				
		
		
				
						    
				
				
						private
				
				 String 
				name
				;
				
						
						
				
		
		
				
						    
				
				
						
						
				
		
		
				
						    
				
				@DBColumn
				(name=
				"isdn"
				,type=
				"String"
				)
				
						
						
				
		
		
				
						    
				
				
						private
				
				 String 
				isdn
				;
				
						
						
				
		
		
				
						    
				
				
						
						
				
		
		
				
						    
				
				@DBColumn
				(name=
				"price"
				, type=
				"float"
				)
				
						
						
				
		
		
				
						    
				
				
						private
				
				
				
				
						float
				
				
				
				price
				;
				
						
						
				
		
		
				
						 
				
		
		
				
						    
				
				
						public
				
				 String getId() {
				
						
						
				
		
		
				
						       
				
				
						return
				
				
				
				id
				;
				
						
						
				
		
		
				
						    }
				
						
						
				
		
		
				
						 
				
		
		
				
						    
				
				
						public
				
				
				
				
						void
				
				 setId(String id) {
				
						
						
				
		
		
				
						       
				
				
						this
				
				.
				id
				 = id;
				
						
						
				
		
		
				
						    }
		
		
				
						    ......
				(其它的
				get, set
				方法省略)
				
						
						
				
		
		
				
						 
				
		
		
				
						 
				
		
		
				然后再调用引擎的相关新增,修改,删除方法就来完成数据维护工作,
		
		
				
						1.  
				
				新增
		
		
				
						 
				
		
		
				
						       DALEngine engine = 
				
						new
				
				 DALEngine();
				
						
						
				
		
		
				
						       Book b = 
				
						new
				
				 Book();
				
						
						
				
		
		
				
						       b.setId(
				"123456789"
				);
				
						
						
				
		
		
				
						       b.setName(
				"Think in Java 3 Edition"
				);
				
						
						
				
		
		
				
						       b.setIsdn(
				"123-4567-89"
				);
				
						
						
				
		
		
				
						       b.setPrice(60.5f);
				
						
						
				
		
		
				
						       
				
				
						try
				
				 {
				
						
						
				
		
		
				
						           engine.create(b);
				
						
						
				
		
		
				
						       } 
				
						catch
				
				(DALException e) {
				
						
						
				
		
		
				
						    
						       log.error(e);
				
						
						
				
		
		
				
						       }
				
						
						
				
		
		
				
						    }
		
		
				
						 
				
		
		
				
						2.  
				
				基于主键的修改
		
		
				
						 
				
		
		
				
						       
				
				
						try
				
				 {
				
						
						
				
		
		
				
						           engine.update(b);
				
						
						
				
		
		
				
						       } 
				
						catch
				
				(DALException e) {
				
						
						
				
		
		
				
						           log.error(e);
				
						
						
				
		
		
				
						       }
				
						
						
				
		
		
				
						 
				
		
		
				
						3.  
				
				基于条件的修改(忽略主键,按条件进行批量更改)
		
		
				
						 
				
		
		
				
						       HashMap params = 
				
						new
				
				 HashMap();
				
						
						
				
		
		
				
						       params.put(
				"price"
				, 20f);
				
						
						
				
		
		
				
						       
				
				
						try
				
				 {
				
						
						
				
		
		
				
						           engine.update(b, params, 
				"WHERE price > ?"
				);
				
						
						
				
		
		
				
						    
						    } 
				
						catch
				
				(DALException e) {
				
						
						
				
		
		
				
						           log.error(e);
				
						
						
				
		
		
				
						       }
				
						
						
				
		
		
				
						 
				
		
		
				
						4.  
				
				基于主键的删除
		
		
				
						 
				
		
		
				
						       
				
				
						try
				
				 {
				
						
						
				
		
		
				
						           engine.delete(b);
				
						
						
				
		
		
				
						       } 
				
						catch
				
				(DALException e) {
				
						
						
				
		
		
				
						           log.error(e);
				
						
						
				
		
		
				
						       }
				
						
						
				
		
		
				
						 
				
		
		
				
						5.  
				
				基于条件的删除(忽略主键,按条件进行批量删除)
		
		
				
						 
				
		
		
				
						       HashMap params = 
				
						new
				
				 HashMap();
				
						
						
				
		
		
				
						       params.put(
				"price"
				, 20f);
				
						
						
				
		
		
				
						       
				
				
						try
				
				 {
				
						
						
				
		
		
				
						           engine.delete(b.getClass(), params, 
				"WHERE price > ?"
				);
				
						
						
				
		
		
				
						       } 
				
						catch
				
				(DALException e) {
				
						
						
				
		
		
				
						           log.error(e);
				
						
						
				
		
		
				
						       }
				
						
						
				
		
		
				
						 
				
		
		
				
						 
				
		
		
				
						6.  
				
				基于主键的查询
		
		
				
						 
				
		
		
				
						       Book b = 
				
						null
				
				;
				
						
						
				
		
		
				
						       HashMap pks = 
				
						new
				
				 HashMap();
				
						
						
				
		
		
				
						       pks.put(
				"id"
				, 
				"123456789"
				);
				
						
						
				
		
		
				
						       
				
				
						try
				
				 {
				
						
						
				
		
		
				
						           b = engine.get(Book.
				
						class
				
				, pks);
				
						
						
				
		
		
				
						       } 
				
						catch
				
				(DALException e) {
				
						
						
				
		
		
				
						           log.error(e);
				
						
						
				
		
		
				
						       }
		
		
				
						 
				
		
		
				
						7.  
				
				基于指定条件的查询
		
		
				
						 
				
		
		
				
						       Collection<Book> books = 
				
						null
				
				;
				
						
						
				
		
		
				
						       HashMap params = 
				
						new
				
				 HashMap();
				
						
						
				
		
		
				
						       params.put(
				"price"
				, 20f);
				
						
						
				
		
		
				
						       
				
				
						try
				
				 {
				
						
						
				
		
		
				
						           
						books = engine.get(Book.
				
						class
				
				, params, 
				"WHERE price > ?"
				);
				
						
						
				
		
		
				
						       } 
				
						catch
				
				(DALException e) {
				
						
						
				
		
		
				
						           log.error(e);
				
						
						
				
		
		
				
						       }
		
		
				
						 
				
		
		
				处理一对一或一对多的实体关系,需要用到
				One2One
				或
				One2Many
				注释,比如处理
				Order
				和
				OrderDetail
				,需要这样定义实体
		
		
				
						 
				
		
		
				@DBTable
				(name=
				"Orders"
				)
				
						
						
				
		
		
				
						public
				
				
				
				
						class
				
				 Order {
				
						
						
				
		
		
				
						 
				
		
		
				
						    
				
				@DBColumn
				(name=
				"id"
				,type=
				"String"
				,isKey=
				
						true
				
				)
				
						
						
				
		
		
				
						    
				
				
						private
				
				 String 
				id
				;
				
						
						
				
		
		
				
						    
				
				
						
						
				
		
		
				
						    
				
				@
				One2Many(type=
				"test.OrderDetail"
				 column=
				"orderId"
				 cause=
				"id"
				)
				
						
						
				
		
		
				
						    
				
				
						private
				
				 Collection 
				details
				;
				
						
						
				
		
		
				
						    
				
				
						
						
				
		
		
				
						    ......(
				其它属性
				)
				
						
						
				
		
		
				
						 
				
		
		
				
						    
				
				
						pub
				
				
						lic
				
				 Collection getDetails() {
				
						
						
				
		
		
				
						       
				
				
						r
				
				
						eturn
				
				
				
				details
				;
				
						
						
				
		
		
				
						    }
				
						
						
				
		
		
				
						 
				
		
		
				
						    
				
				
						public
				
				
				
				
						void
				
				 setDetails(Collection details) {
				
						
						
				
		
		
				
						       
				
				
						this
				
				.
				details
				 = details;
				
						
						
				
		
		
				
						    }
				
						
						
				
		
		
				
						 
				
		
		
				
						    
				
				
						public
				
				 String getId() {
				
						
						
				
		
		
				
						       
				
				
						return
				
				
				
				id
				;
				
						
						
				
		
		
				
						    }
				
						
						
				
		
		
				
						 
				
		
		
				
						    
				
				
						public
				
				
				
				
						void
				
				 setId(
				
						String
				
				 id) {
				
						
						
				
		
		
				
						       
				
				
						this
				
				.
				id
				 = id;
				
						
						
				
		
		
				
						    }
				
						
						
				
		
		
				
						    
				
				
						
						
				
		
		
				
						    ......
				(其它的
				get, set
				方法省略)
				
						   
				
				
						
						
				
		
		
				}
				
						
						
				
		
		
				
						 
				
		
		
				@DBTable
				(name=
				"OrderDetails"
				)
				
						
						
				
		
		
				
						public
				
				
				
				
						class
				
				 OrderDetail {
				
						
						
				
		
		
				
						 
				
		
		
				
						    
				
				@DBColumn
				(name=
				"id"
				,type=
				"String"
				,isKey=
				
						true
				
				)
				
						
						
				
		
		
				
						    
				
				
						private
				
				 String 
				id
				;
				
						
						
				
		
		
				
						    
				
				
						
						
				
		
		
				
						    
				
				@
				Many2One(name=
				"orderId"
				,type=
				"test.Order"
				)
				
						
						
				
		
		
				
						    
				
				
						private
				
				 Order 
				order
				;
				
						
						
				
		
		
				
						 
				
		
		
				
						    ......(
				其它属性
				)
				
						
						
				
		
		
				
						 
				
		
		
				
						    
				
				
						public
				
				 String getId() {
				
						
						
				
		
		
				
						    
						    
				
				
						return
				
				
				
				id
				;
				
						
						
				
		
		
				
						    }
				
						
						
				
		
		
				
						 
				
		
		
				
						    
				
				
						public
				
				
				
				
						void
				
				 setId(String id) {
				
						
						
				
		
		
				
						       
				
				
						this
				
				.
				id
				 = id;
				
						
						
				
		
		
				
						    }
				
						
						
				
		
		
				
						 
				
		
		
				
						    
				
				
						public
				
				 Order getOrder() {
				
						
						
				
		
		
				
						       
				
				
						return
				
				
				
				order
				;
				
						
						
				
		
		
				
						    }
				
						
						
				
		
		
				
						 
				
		
		
				
						    
				
				
						public
				
				
				
				
						void
				
				 setOrder(Order order) {
				
						
						
				
		
		
				
						       
				
				
						this
				
				.
				order
				 = order;
				
						
						
				
		
		
				
						    }
				
						
						
				
		
		
				
						    
				
				
						
						
				
		
		
				
						    ......
				(其它的
				get, set
				方法省略)
				
						   
				
				
						
						
				
		
		
				
						    
				
				
						
						
				
		
		
				}
		
		
				
						 
				
		
		
				除了以上的根据实体对象来进行操作的方法外,也提供不依赖于实体的简单的
				JDBC
				包装方法,这时需要用
				DataSet
				对象来接受查询结果,用
				HashMap
				来传递参数。例如执行一个查询:
		
		
				
						 
				
		
		
				
						    DataSet dataSet = 
				
						null
				
				;
				
						
						
				
		
		
				
						    HashMap params = 
				
						new
				
				 HashMap();
				
						
						
				
		
		
				
						    params.put(
				"O.Operator"
				, 
				"Tom"
				);
				
						
						
				
		
		
				
						    
				
				
						try
				
				 {
				
						
						
				
		
		
				
						       dataSet = engine.select(
				"SELECT O.ID, O.Operator, O.DeliveryDate, "
				 +
				
						
						
				
		
		
				
						              
				
				"D.ProductId FROM Orders O, OrderDetails D "
				 +
				
						
						
				
		
		
				
						              
				
				"WHERE O.id = D.orderId and O.Operator = ?"
				, params);
				
						
						
				
		
		
				
						    } 
				
						catch
				
				(DALException e) {
				
						
						
				
		
		
				
						       log.error(e);
				
						
						
				
		
		
				
						    }
		
		
				
						 
				
		
		
				同样,可以用
				DALEngine
				的
				insert, update, delete
				方法直接执行
				SQL
				语句。
		
		
				
						 
				
		
		
				接下来,我主要是要完成进一步的功能测试和性能测试。但上班后时间可能不是太充裕,我希望能在三月中旬完成,我会在这里继续记录我的测试情况。
		
	posted on 2007-02-25 08:20 
Jini 阅读(1545) 
评论(13)  编辑  收藏  所属分类: 
数据库相关