上次说到Bean的定义,这次来说说怎么解析。
SQL有几种,Insert,Update,Remove。
Insert解析起来比较简单,如果你定义的主键为null的话,你就可以认为需要解析Insert语句了。至于主键怎么判断为null,很遗憾,我也不能给出完全的答案。 我是使用OID作为唯一关键字的,如果你使用了复合主键,那么没办法,你需要显示声明Insert方法了。
解析Insert语句无非就是注意一下AutoIncrement字段怎么生成,Version怎么生成,Timestamp怎么生成。
autoincrement在Oracle下面是先执行一句select ?.nextval from dual, 拿到这个值设置到Bean里面,然后作为一般字段解析就OK了. version字段么,新建是1, timestamp只要用服务器时间就行.
Update需要注意的问题是你需要知道主键字段是哪几个,因为Where语句是使用主键的值来定位的. 剩下的就是Version和timestamp字段. version++, timestamp使用当前的服务器时间. 如果有version或者timestamp的话也需要加入到where语句中. 如果executeUpdate返回0,那么很遗憾,要么数据已经被删除,要么是版本号或者时间戳不对.这个时候看你的需求,正常的话应该再发一句where子句中只有主键的语句,如果有结果,那么是版本号或者时间戳已经被更改,也就是说当前的数据过期了. 没有结果就是数据已经被删除.
Remove最简单, 使用主键作为条件删就是了. 如果有Version或者Timestamp,那么处理方式和Update一样. 需要注意的是Oracle用Delete from,而SQL Server用Delete * from, 这个时候SQLBuilder的不同实现就有用了.
至于SELECT,这个比较复杂, 这里先说知道主键的查询, 条件查询以后专门说.
其实知道主键的查询也不用多说了,这个实在是简单的厉害....
如上所说, 在解析SQL的时候你必须知道如何获取/设置Field的值. 用上一篇文章里面的代码做个例子. Car有几个属性, 我们无从知晓. 所以使用bean.getClass().getDeclaredMethods(), 拿到所有的Getter/Setter. 需要注意一下Getter包括以"is"和"get"开头的方法, 因为boolean型的参数的Getter通常使用is开头.
拿到这些方法以后我们需要分析一下什么才是和数据库对应的Field, 当然只要和你已经缓存的Bean的声明(Annotation/XML)比较一下一切都十分明了了. 之所以要比较是因为Bean不一定只有关于数据库Column的Getter/Setter, 比如每个类都有的getClass()方法,和数据库一点关系没有. 当然也有人会在Car里面写一个getPrice()方法也不一定, 而这个方法说不定是有其他用途的.
拿到这些方法以后只要动用reflect一切都OK了. 至于reflect,我就不说了.
写到这里, 单表的CRUD都已经解决了. 这里说的都是思路, 真正写代码或许已经上百个类出来了. :)
如果大家觉得什么地方需要一些源代码, 我以后可以写一些例子.