一个数据层的设计与实现,大伙帮忙看看是否可行,谢谢!

这里我没有使用Hibernate,我一直都嫌Hibernate配置起来麻烦,而我最希望有一种最好是零配置的框架来实现基本的功能,所以我

尝试做了一个类似的这种“框架”,想利用这个和代码生成器结合提高开发的速度。


首先需要将表名和数据类的名字对应起来,我使用的Oracle数据库,定义规则如下:
1、表名的单词之间由下划线"_"分割,例如ADMIN_USER
2、数据类的名字和表的名字有一定的关系,例如ADMIN_USER,类的名字就是AdminUser
3、字段名的定义和表明规则一样
4、数据类里面的属性名字和数据类的名字规则相同

每个数据类都是由程序自动生成,生成以后不能修改,因此每个数据类还需要有一个VO类,继承数据类,以便存放数据库中没有的属

性或者存放与其他表关联的对象。

为了实现最基本的插入、删除、修改和查询功能,有些信息是数据类无法提供的,比如主键是哪个,哪个字段是通过序列生成的,因

此这里需要将一些额外的属性加到程序中,这里我使用了 Annotation ,将是否主键和序列的名字定义在每个属性的get方法上,这样不仅

可以告诉程序哪些属性是数据库中有的,而且可以在程序中知道数据表的关键的一些信息,可以实现一些操作的自动化。

例如:
[code]
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
{

}
[/code]
我希望最终插入一条数据的代码是这样的:
[code]
DataSource ds = ....//获得数据源
BaseDAO dao = new BaseDAO(ds);
AdminUserVO user = new AdminUserVO();
user.setName("admin");
dao.saveObject(user);
[/code]
删除数据是这样:
[code]
DataSource ds = ....//获得数据源
BaseDAO dao = new BaseDAO(ds);
AdminUserVO user = new AdminUserVO();
user.setId(10000);
dao.deleteObject(user);
[/code]
编辑数据是这样:
[code]
DataSource ds = ....//获得数据源
BaseDAO dao = new BaseDAO(ds);
AdminUserVO user = new AdminUserVO();
user.setId(10000);
user.setName("a new name");
dao.updateObject(user);
[/code]
根据主键查询是这样:
[code]
DataSource ds = ....//获得数据源
BaseDAO dao = new BaseDAO(ds);
AdminUserVO user = new AdminUserVO();
user.setId(10000);
user = dao.findObject(user);
[/code]

以上的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(也就是前面

定义的数据类)。这样就可以实现单表的查询操作,查询操作一般是这样进行:
[code]
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);
}
[/code]
这样单表查询很容易就可以实现,对于多表关联,我是这样实现:
首先如果一个表和另外的表有关联,上边的例子如果ADMIN_USER表中的roleId和另外一张表的roleId关联,例如
[code]
public class AdminRole
{
private long roleId;
private String roleName;


....get和set方法与上边基本类似

}
pubilc class AdminRoleVO extends AdminRole implements IVO
{

}
[/code]
这样我们需要ADMIN_USER和ADMIN_ROLE里面关联查询,才能知道某个管理员是什么角色,这样管理员的VO对象里面需要有一个对象

adminRole
[code]
public class AdminUserVO extends AdminUser implements IVO
{
private AdminRole adminRole;

...adminRole的get和set方法
}
[/code]
select语句将所有需要的表的字段全部关联取出,放到Map里(和前面没什么区别),然后在调用从Map生成Object的方法查询目标class的

每个属性的时候需要判断这个树形是否实现了IVO接口,如果实现了,则递归调用这个方法,生成另外一个VO对象,再Set进去,这样,就

可以实现了两个表的简单关联。

例如上边的例子,查询方法应该是这样:
[code]
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);
}
[/code]
但这里存在一个问题,就是如果两个数据表的字段名相同但又不是相关联的字段(两个表有一个字段名相同但值不同),这样取出的数据

就会有问题,因为在Map里面key是唯一的。这个问题暂时我还没有想到好的解决办法,所以也只能在设计的时候避免有不相关的同名字段



以上就是我的大概的想法,请各位帮忙看一下这种想法是否可行,效率如何,程序实现我放到附件里面去了,请各位多多指教,谢谢!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这个问题可以使用荷兰国旗问题的思路来解决。荷兰国旗问题是指将一个数组所有小于等于某个数x的数放在数组的左侧,所有大于等于某个数y的数放在数组的右侧,而所有介于x和y之间的数放在数组的间。这个问题可以用三个指针来解决,分别指向当前处理的数、小于等于x的数的右边界、大于等于y的数的左边界。初始时,这三个指针都指向数组的起始位置。然后,我们遍历数组,如果当前处理的数小于x,就将它和小于等于x的数的右边界的下一个数交换,然后将小于等于x的数的右边界和当前处理的数都向右移动一位;如果当前处理的数大于y,就将它和大于等于y的数的左边界的上一个数交换,然后将大于等于y的数的左边界向左移动一位,但当前处理的数不用移动,因为我们还没有处理它。如果当前处理的数介于x和y之间,就将它和小于等于x的数的右边界的下一个数交换,然后将小于等于x的数的右边界向右移动一位,但当前处理的数也要向右移动一位,因为我们已经处理过它了。最终,数组就会被分成三个部分,分别是小于等于x的数、介于x和y之间的数、大于等于y的数。对于这个问题,我们可以将x设为0,y设为2,然后按照荷兰国旗问题的思路来解决。具体实现过程如下: ``` def sort_array(nums): n = len(nums) left = 0 right = n - 1 i = 0 while i <= right: if nums[i] == 0: nums[left], nums[i] = nums[i], nums[left] left += 1 i += 1 elif nums[i] == 2: nums[right], nums[i] = nums[i], nums[right] right -= 1 else: i += 1 return nums ``` 这个算法的时间复杂度为O(n),空间复杂度为O(1),符合题目要求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值