Title:VO的封装
我在上一篇博客(
http://tan4836128.iteye.com/blog/1152147)介绍了一个小型的持久层处理类,一个可以兼容各类数据操作的方法。其中最主要的方法,就是构建各类数据操作的SQL,和解析查询结果并返回的数据集合。本文主要针对这个解析后返回的数据集合,做实体类与之耦合的需求进行讨论。
为了实现自动化匹配,我设置几个对VO类编码的基本要求:
1. 数据库表理论上对应一个实体类VO,表中每一个字段都能在VO中找到对应变量,附带表名、字段名、主键名等各返回名称的方法。
2. 实体类VO应针对表中每一个字段,都提供一个返回字段名称的方法,这个用于自动匹配查询返回的数据集合(因为,在返回的数据集中对表字段名做了记录)。
3. 为了方便阅读,VO类中方法、变量应有足够的注释
为了不再重复对VO进行编码,我设计了一个生成实体类代码的小程序,这个程序辅助我设计实体类VO,它本身并不是持久层的一部分。但是由它(按照一定规范和要求)生成的实体类VO是持久层的重要数据传输对象,由这些VO搭建起跟执行查询后返回的数据集的耦合关系。
首先看一个生成出来的VO类,Role.java
package com.accout.role.pojo;
/***
* 角色
* @author db2admin
* 2010-12-23
*/
public class Role implements java.io.Serializable {
/**角色ID*/
private int RoleId;
/**角色名称*/
private String RoleName;
/**角色等级:1为普通员工、2为经理用户、3为系统管理员*/
private String RoleLevel;
/**角色资源,当前角色对应的浏览权限*/
private String RoleResource;
/***/
private String Remark;
/***
* 字段代理方法:role_id
* 角色ID
* @return
*/
public static String RoleId(){
return "role_id";
}
/***
* 字段代理方法:role_name
* 角色名称
* @return
*/
public static String RoleName(){
return "role_name";
}
/***
* 字段代理方法:role_level
* 角色等级:1为普通员工、2为经理用户、3为系统管理员
* @return
*/
public static String RoleLevel(){
return "role_level";
}
/***
* 字段代理方法:role_resource
* 角色资源,当前角色对应的浏览权限
* @return
*/
public static String RoleResource(){
return "role_resource";
}
/***
* 字段代理方法:remark
*
* @return
*/
public static String Remark(){
return "remark";
}
/***
* 实体类对应表:role
* @return
*/
public static String getTableName(){
return "role";
}
/***
* 表主键:role_id
* @return
*/
public String getPrimaryKey(){
return "role_id";
}/***
* 设置主键值:RoleId
* @return
*/
public void setPrimaryKeyValue(int value){
this.RoleId = value;
}/***
* 获取主键值:RoleId
* @return
*/
public int getPrimaryKeyValue(){
return this.RoleId;
}
}
该类包含字段对应的变量、表名和表字段名称以及主键名称的返回方法,这些都是通过读取数据库自动生成的,包括数据类型、字段注释等,再看表结构,如下:
注:没有对get/set方法做自动生成,Eclipse有这功能,so...
好,现在VO类有了,再看看怎样与查询得到的数据集合自动装配,先看代码:
public static void main(String[] args) {
PublicDao dao = new PublicDao();
Map<Object, String> mk = new HashMap<Object, String>();
Map<Object, Object> mv = new HashMap<Object, Object>();
//设置要查询的列
mk.put(1, Role.RoleId());
mk.put(2, Role.RoleLevel());
mk.put(3, Role.RoleName());
mk.put(4, Role.RoleResource());
mk.put(5, Role.Remark());
/**单表查询测试*/
String sql = dao.createSql(PublicDao.SELECT, Role.getTableName(), mk, mv, "");
System.out.println(sql);
List list = dao.executeSql(PublicDao.SELECT, sql);
}
得到SQL:
select role_id,role_level,role_name,role_resource,remark from role
我们先到数据库里查询一下看看情况:
//执行查询之后,list中就有3条数据了,接下来遍历list,取出数据
List list = dao.executeSql(PublicDao.SELECT, sql);
//用于封装并返回数据的集合对象
List<Role> list_t = new ArrayList<Role>();
//取出列名Map
Map mk_n = (Map) list.get(0);
//取出每一行数据
List list_mv = (List) list.get(1);
//封装的对象
Role role = null;
for(int i=0;i<list_mv.size();i++){
Map mv_n = (Map) list_mv.get(i);
//这里每循环一次代表每一行数据,即一个对象
role = new Role();
for(int j=1;j<=mk_n.size();j++){
Object temp = mv_n.get(mk_n.get(j));
if(Role.RoleId().equals(mk_n.get(j))){
role.setRoleId(temp==null?null:(Integer)temp);
}
if(Role.RoleName().equals(mk_n.get(j))){
role.setRoleName(temp==null?"":temp.toString());
}
if(Role.RoleResource().equals(mk_n.get(j))){
role.setRoleResource(temp==null?"":temp.toString());
}
if(Role.RoleLevel().equals(mk_n.get(j))){
role.setRoleLevel(temp==null?"":temp.toString());
}
}
list_t.add(role);
}
有图才有真相:
到此,就可以返回这个List<Role>对象了,传递到表示层该怎么读取就怎么读,数据从数据库,经持久层封装,再到VO封装出来,这个流程其实很简单,有了固定的持久不变的持久层API,有了可以自动生成VO的小程序,一下子模型层,持久层代码都不用关心,你只需要分析需求、设计好表结构,其他的就剩下表示层的业务逻辑了。
另外,VO类中还有getPrimaryKey,getPrimaryKeyValue,setPrimaryKeyValue等方法,这些方法用于数据的删除和修改操作,用起来也很简单,比如删除:
/***
* 如果使用Struts 1.x,这里的keyId可以直接通过request.getParameter()方法获取,不需要传递参数
* 当然,方法就应该改为
* public ActionForward deleteRole(ActionMapping mapping, ActionForm form,
* HttpServletRequest request, HttpServletResponse response){。。。}
* @param keyId
*/
public void deleteRole(String keyId){
Map<Object,String> mk = new HashMap<Object,String>();
Map<Object,Object> mv = new HashMap<Object,Object>();
//设置主键、主键值
mk.put(1, Role.getPrimaryKey());
//request.getParameter("keyId")
mv.put(mk.get(1), "="+keyId);
PublicDao dao = new PublicDao();
String sql = dao.createSql(PublicDao.DELETE, Role.getTableName(), mk, mv, "");
dao.executeSql(PublicDao.DELETE, sql);
}
新增或修改数据,如下:
/***
* 这里的type、Role对象封装的值,可以直接通过request.getParameter()方法获取,不需要传递这两个参数
* 当然,方法就应该改为
* public ActionForward addAndUpdateRole(ActionMapping mapping, ActionForm form,
* HttpServletRequest request, HttpServletResponse response){。。。}
* @param type
* @param role
*/
public void addAndUpdateRole(String type, Role role){
Map<Object,String> mk = new HashMap<Object,String>();
Map<Object,Object> mv = new HashMap<Object,Object>();
mk.put(1, Role.RoleName());
mk.put(2, Role.RoleResource());
mk.put(3, Role.RoleLevel());
mv.put(mk.get(1), role.getRoleName());
//request.getParameter("RoleName")
mv.put(mk.get(2), role.getRoleResource());
//request.getParameter("RoleResource")
//request.getParameter("RoleLevel")
mv.put(mk.get(3), role.getRoleLevel());
PublicDao dao = new PublicDao();
String sql = "";
//request.getParameter("type")
if("Add".equals(type)){
sql = dao.createSql(PublicDao.ADD, Role.getTableName(), mk, mv, "");
dao.executeSql(PublicDao.ADD, sql);
} else if("Update".equals(type)) {
//设置条件
String condition = Role.getPrimaryKey()+"="+role.getPrimaryKeyValue();
sql = dao.createSql(PublicDao.UPDATE, Role.getTableName(), mk, mv, condition);
dao.executeSql(PublicDao.UPDATE, sql);
}
}
总结,实体类的自动装配跟VO类的映射就需要有这样高耦合度,为满足数据传输,这是必须的。VO类中设置getTableName、getPrimaryKey等方法能够参与业务逻辑,给编码带来的好处还是有的,起码在需要获取主键值得时候,你不再需要关心某张表的主键到底是谁,而直接拿来就用。当然也有问题,这些问题都可以通过建单扩展既可以解决,比如:
1. 多主键的处理,返回数组
2. (多)外键的处理,返回数组
3. VO中加入表索引信息
同前一篇一样,这样的思路也只是基于一些简单的小型项目,应用到大项目中,需要不停的扩展VO的功能,比如加入索引,在业务逻辑层面,你可以通过指定索引,直接优化一些大型的、复杂的SQL查询,提升效率,当然,这就要求前一篇中PublicDao类的createSql方法更高了,实现也更复杂了。
最后,附上我自己写的一个VO类的代码生成类。
文中有任何大小问题,请各位不吝赐教,我会在日后继续改进。
分享到:
相关推荐
《小钢炮蓝牙音箱PADS9.5设计详解——硬件原理与PCB解析》 在电子设备领域,蓝牙音箱凭借其无线便捷性受到广大消费者的喜爱。"小钢炮"蓝牙音箱,以其小巧便携、音质出色的特点,成为市场上的一款热门产品。本资料...
在介绍MicroPython读取小钢炮开发板上的HTS221温湿度传感器的文章中,我们首先需要了解HTS221传感器的基本信息。HTS221是一款由STMicroelectronics生产的数字输出相对湿度和温度传感器,该传感器能够提供高精度的...
Skylake平台小钢炮Z170芯片组ITX主板.pdf
在本项目中,我们关注的是使用PADS 9.5软件进行小钢炮蓝牙音箱的BGA(Ball Grid Array)两层板设计。这涉及到电子工程中的多个关键知识点,包括硬件设计、电路板布局、BGA封装处理以及PCB设计流程。 首先,硬件设计...
基于PADS9.5设计的小钢炮蓝牙音箱硬件(原理图+PCB)文件+RDA58硬件应用指南,可供学习及设计参考。
市场上各种蓝牙音箱数不胜数,小钢炮系列的蓝牙音箱也颇受欢迎。 这个是我收集的蓝牙音箱原理图和PCB,之所有拿出来分享,这个PCB是两层板,但是包含了BGA封装的蓝牙模块,layout的活不错,可以借鉴一下。原理图和...
2.5寸硬盘抽取式机箱DWG图 大小: 101103 字节 MD5: A5972B2DC6CD17A6D0169A02BB7B6AC8 SHA1: B11C8ED0B7A7AD9D655554B4FB65B0257E8D1758
描述中提到的“小钢炮 I7-8850H,UHD 630黑苹果10.14.4成功”,意味着有人成功地在配备 i7-8850H 和 UHD 630 显卡的紧凑型高性能电脑(可能指小型台式机或笔记本电脑)上安装了 macOS 10.14.4,并且提供了详细的教程...
【Huan】_高CP值的小鋼砲組合!_全漢FSP_CST350機殼+金鋼彈850W_SFX電源開箱_FSP_CST350_Cas
MyBatis则是一个轻量级的持久层框架,实现了SQL语句与Java代码的解耦。 二、前端设计 1. HTML5与CSS3:项目采用现代Web技术,提供响应式布局,确保在不同设备上都能良好显示。 2. Bootstrap框架:用于快速构建美观...
以上介绍了Micropython中文教程针对STM32开发板的相关知识点,包括编译环境配置、终端软件选择、固件升级、硬件故障恢复、I2C引脚配置调整以及小钢炮开发板的简介。这些知识点不仅帮助初学者理解Micropython在STM32...
在本项目中,我们将基于开源电子网的官方库函数,通过串口打印HTS221所测得的温湿度值,并利用小钢炮开发板进行IIC通信,以16MHz的晶振频率为系统提供时钟支持。 首先,我们需要了解HTS221的基本特性。这款传感器...
Hibernate作为持久层框架,简化了数据库操作。它提供了对象关系映射(Object-Relational Mapping,ORM),使得开发人员可以使用面向对象的方式处理数据库事务,而无需编写大量的SQL语句。Hibernate支持事务管理,...
直接驱动小米所有蓝牙设备~ 找了很久,只有这个才真正有用~
Kali for Android 是一种将 Kali 系统安装到安卓设备上的解决方案,将安卓设备变成渗透测试小钢炮。以下是实现 Kali for Android 的详细步骤和知识点: 一、前提条件 * 安卓设备已经获取了 root 权限 * 安卓设备...
研究目的 主要研究内容是基于多目相机,利用图像拼接技术...摄像头:采用淘宝上最便宜的小钢炮摄像头,单个价格25元左右 摄像头固定装置:计算摄像头的视场,使用Autodesk 3ds Max设计固定装置,并使用3D打印技术打印
2. **细分市场多样化**:除了传统的车型之外,本次车展还展示了多款针对特定细分市场设计的新车型,例如A00级敞篷车(五菱宏光MINIEV敞篷版)、两厢钢炮(第八代高尔夫GTI、领克02 Hatchback)、敞篷跑车(MG ...
此外,小众细分市场的新车如A00级敞篷车、两厢钢炮、敞篷跑车、豪华SUV和乘用化皮卡等也吸引了不少关注。 新品牌和新标识的出现是本次车展的另一大亮点。长城汽车的坦克品牌独立,上汽智己、吉利极氪首次参展,现代...
1. **第一标段**:主要招标A3、A4、16K、8K四种型号的亚龙小钢炮静电复印纸,要求70克100%纯木浆,含水量符合国际标准。 2. **第二标段**:招标381-1、381-2、241-1、241-2型号的亚龙小钢炮打印纸,要求为一等品。 ...