浏览 5892 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-04-20
最后修改:2008-11-19
尝试做了一个类似的这种“框架”,想利用这个和代码生成器结合提高开发的速度。 首先需要将表名和数据类的名字对应起来,我使用的Oracle数据库,定义规则如下: 1、表名的单词之间由下划线"_"分割,例如ADMIN_USER 2、数据类的名字和表的名字有一定的关系,例如ADMIN_USER,类的名字就是AdminUser 3、字段名的定义和表明规则一样 4、数据类里面的属性名字和数据类的名字规则相同 每个数据类都是由程序自动生成,生成以后不能修改,因此每个数据类还需要有一个VO类,继承数据类,以便存放数据库中没有的属 性或者存放与其他表关联的对象。 为了实现最基本的插入、删除、修改和查询功能,有些信息是数据类无法提供的,比如主键是哪个,哪个字段是通过序列生成的,因 此这里需要将一些额外的属性加到程序中,这里我使用了 Annotation ,将是否主键和序列的名字定义在每个属性的get方法上,这样不仅 可以告诉程序哪些属性是数据库中有的,而且可以在程序中知道数据表的关键的一些信息,可以实现一些操作的自动化。 例如: public class AdminUser { private String name; private long id; private long roleId; @FieldFlag(pk=true,seq="seq_admin_user") public long getId(){return id;}; @FieldFlag public String getName(){return name;} @FieldFlag public long getRoleId(){return roleId;}; ///set方法略 } public class AdminUserVO extends AdminUser implements IVO { } 我希望最终插入一条数据的代码是这样的: DataSource ds = ....//获得数据源 BaseDAO dao = new BaseDAO(ds); AdminUserVO user = new AdminUserVO(); user.setName("admin"); dao.saveObject(user); 删除数据是这样: DataSource ds = ....//获得数据源 BaseDAO dao = new BaseDAO(ds); AdminUserVO user = new AdminUserVO(); user.setId(10000); dao.deleteObject(user); 编辑数据是这样: DataSource ds = ....//获得数据源 BaseDAO dao = new BaseDAO(ds); AdminUserVO user = new AdminUserVO(); user.setId(10000); user.setName("a new name"); dao.updateObject(user); 根据主键查询是这样: DataSource ds = ....//获得数据源 BaseDAO dao = new BaseDAO(ds); AdminUserVO user = new AdminUserVO(); user.setId(10000); user = dao.findObject(user); 以上的AdminUser类只是举例,最后的效果应该是任何一个根据规则建立的数据类,都可以用这样的代码实现基本的操作。 现在详细说一下针对数据库的各个操作我的实现和想法: 1)插入、删除和修改 我的最终目的是需要拿来一个数据对象,设置了里面属性的值以后,就可以调用插入方法将数据插入进去,而不需要每个DAO里面还要 写一些罗嗦的insert、update、delete等语句(当然特殊情况除外),仔细分析,Insert、update、delete语句需要的信息,基本上我的 数据类都可以提供,数据库的字段名可以用数据类的属性名转换,字段个数可以根据数据类的树形数量以及Annotation来获得,序列也可 以由Annotation获取,这样,insert语句的所有元素我们都具备了,只要利用反射将数据类的信息搜集起来再生成insert的语句和需要的 参数就可以了。有了这些,就可以使用JdbcTemplate进行数据库操作了。例如,我的表叫做ADMIN_USER,里面有name和id还有roleId属性 ,其中id是由seq_admin_user序列生成的。为了避免空值的插入,因此需要在生成insert语句时候动态判断对象里面的属性值是否为空, 如果为空则不对这个字段进行插入或者更新操作。这样,就可以实现根据不同的对象进行同样的操作,避免了写那么多无聊的insert、 update和delete代码(当然这些只是最基本的,如果有特殊的应用肯定还是得手写sql的) 2)查询和表的关联 查询部分我是这样设计:先考虑一条记录的情况,首先,使用一个工具类将一条select语句的结果保存到一个HashMap(JdbcTemplate 就可以实现),例如select * from admin_user,查询出来的结果应该是一个HashMap,key是字段名,value是查询出来的值。然后根据这 个Map来进行转换,将这个Map转换为某个Class的一个实例,当然这个Class是要作为参数传递过去的,告诉程序需要将 Map转换成什么class,转换的原则也很简单,将这个class中的所有属性名提取出来,转换成字段名,再到Map去找有没有这个key,如果有 ,将存储在里面的值取出,调用这个类的Set方法将值set进去,这样select取出来的数据就可以转换为一个或者多个Object(也就是前面 定义的数据类)。这样就可以实现单表的查询操作,查询操作一般是这样进行: DataSource ds = ...//获取数据源 BaseDAO dao = new BaseDAP(ds); List list = dao.query("select * from admin_user where id=?",AdminUserVO.class,123); for(int i=0;i<list.size();i++) { AdminUserVO user = (AdminUserVO)list.get(i); System.out.println(user); } 这样单表查询很容易就可以实现,对于多表关联,我是这样实现: 首先如果一个表和另外的表有关联,上边的例子如果ADMIN_USER表中的roleId和另外一张表的roleId关联,例如 public class AdminRole { private long roleId; private String roleName; ....get和set方法与上边基本类似 } pubilc class AdminRoleVO extends AdminRole implements IVO { } 这样我们需要ADMIN_USER和ADMIN_ROLE里面关联查询,才能知道某个管理员是什么角色,这样管理员的VO对象里面需要有一个对象 adminRole public class AdminUserVO extends AdminUser implements IVO { private AdminRole adminRole; ...adminRole的get和set方法 } select语句将所有需要的表的字段全部关联取出,放到Map里(和前面没什么区别),然后在调用从Map生成Object的方法查询目标class的 每个属性的时候需要判断这个树形是否实现了IVO接口,如果实现了,则递归调用这个方法,生成另外一个VO对象,再Set进去,这样,就 可以实现了两个表的简单关联。 例如上边的例子,查询方法应该是这样: DataSource ds = ...//获取数据源 BaseDAO dao = new BaseDAO(ds); List list = dao.query("select * from admin_user a inner join admin_role b on a.role_id=b.role_id",AdminUserVO.class); for(int i=0;i<list.size();i++) { AdminUserVO user = (AdminUserVO)list.get(i); System.out.println(user); AdminRoleVO role = user.getAdminRole(); System.out.println(role); } 但这里存在一个问题,就是如果两个数据表的字段名相同但又不是相关联的字段(两个表有一个字段名相同但值不同),这样取出的数据 就会有问题,因为在Map里面key是唯一的。这个问题暂时我还没有想到好的解决办法,所以也只能在设计的时候避免有不相关的同名字段 。 以上就是我的大概的想法,请各位帮忙看一下这种想法是否可行,效率如何,程序实现我放到附件里面去了,请各位多多指教,谢谢! 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2007-04-20
我觉得这个实际上,走的还是Hibernate的思路,所谓的零配置,Hibernate使用Annotation也可以做到。
|
|
返回顶楼 | |
发表时间:2007-06-22
支持你的想法,我自己也做了一套非Hibernate的数据库处理类,主要是嫌hibernate在多表关联时使用不爽。
我的实现如下: 1、支持mysql5/db2/oracle9/sqlserver2005 2、支持简单jdbc/C3P0/服务器jndi 3、基本处理类,处理数据库打开、关闭、提交等 3、数据处理类,执行sql/procude等 4、查询处理,给定sql,按list/map/类返回多行或一行,统计总行数,在使用分页时根据不同数据库采用不同分页方式(所以先支持这4种数据库) 5、提供当前日期、序列号 6、根据数据单元定义,进行增、删、改、查询、判断是否存在,它的查询和保存分别对应独立表或视图,主要是我们在查询时往往取一些关联名称等信息,而且对一些复杂系统,只有dba写出的sql才能保证高的执行效率 7、对数据单元采用单独的xml配置,在产品模式下只在首次使用读取配置, 8、特定业务处理,包括锁定数据(乐观锁)、备份修改的数据、根据key从表中取出value 9、有自己的工具选择表生成配置xml和封装类。以上功能基本实现,完全自己的东西,大家看看有什么要补充的。整理一下准备把代码发上来 |
|
返回顶楼 | |
发表时间:2007-06-22
重复发明轮子,想要零配置,只要不用Hibernate的多表关联,就可以用工具实现config文件和PO,VO,DAO类代码自动生成,(本人花了一天时间就编好了)。 Hibernate天然支持跨数据库,缓存,分页,锁,这些难道你也要从头开始做吗?
|
|
返回顶楼 | |