java Web项目Service层通用接口和entityVo对象与entity对象转化问题的解决方案

原创 2015年12月17日 15:42:09
  • 4535

Service层的接口中有一些比较常用方法,一次又一次的在新的Service层中被书写,所以懒惰的程序员又烦了,他们决定写个通用接口来解决这个问题。

有些项目中,实体类即承担接收表单数据的任务,又承担持久化任务,很省心。但有些项目中这两项任务的执行类不是同一个,一个Entity.java来执行数据

持久化的任务,一个EntityVo.java类来执行接收表单数据的任务。那么问题来了:Service层需要的是entityVo对象,而DAO层需要的是entity对象,这两个对象

会有一些相同的属性和方法,也会有一些不同的属性和方法,那么在service层中必然要做entityVo对象到entity对象的转换工作,而这项工作又不属于业务。如果

处理方法与业务混在一起写,代码的清晰度就会受到影响。所以本文中做了这方面的处理,可能并不是最好的方案,但起码比没有处理要好的多。

BaseService.java

package org.lxl.mr.common.base.service;

import java.util.List;

public interface BaseService<EntityVo,PK> {
    /**
     * 增加
     * @param entityVo
     */
    public void save(EntityVo entityVo);
    /**
     * 修改
     * @param entityVo
     */
    public void update(EntityVo entityVo);
    /**
     * 通过主键删除
     * @param pk
     */
    public void deleteByPK(PK pk);
    /**
     * 删除
     * @param entityVo
     */
    public void delete(EntityVo entityVo);
    /**
     * 通过主键查询
     * @param pk
     * @return
     */
    public EntityVo get(PK pk);
    /**
     * 查询全部
     * @return
     */
    public List<EntityVo> findAll();
    
}
使用

UserService.java
package org.lxl.mr.service;

import org.lxl.mr.common.base.service.BaseService;
import org.lxl.mr.vo.UserVo;

public interface UserService extends BaseService<UserVo, String>{
    
}

这个处理非常简单,就是写个父接口,把常用的方法写在父接口中,子接口没有其他的需要就什么都不用写;有

其他的需要就再写相应的方法即可。

BaseServiceImpl.java

package org.lxl.mr.common.base.service;

import org.lxl.mr.common.base.vo.VoTemplate;
import org.springframework.beans.factory.annotation.Autowired;

public class BaseServiceImpl {
    
    private VoTemplate voTemplate;
    
    @Autowired
    public final void setVoTemplate(VoTemplate voTemplate) {
        this.voTemplate = voTemplate;
    }
    
    public final VoTemplate getVoTemplate(){
        return this.voTemplate;
    }
}

这个通用方法并不是用来自动实现BaseService接口中的方法的,而是处理entityVo和entity直接转化的问题的。

这是仿造HibernateDaoSupport的写法,注入voTemplate对象。其中voTemplate的get/set方法都是final修饰的,

是不允许子类重写的,保证了注入的正确执行。

VoTemplate.java

package org.lxl.mr.common.base.vo;

import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

/**
 * 本类的作用是解决service层传递的EntityVo对象与dao层
 * 使用的Entity对象转换的问题,更轻松,更规范的处理该问题
 * @author liuXueLiang
 */
@Component
public class VoTemplate {
    /**
     * 由程序员自己提供一个回调方法
     * @param vo
     * @return
     */
    public <T> T execute(VoCallback<T> vo){
        return vo.doInVo();
    }
    
    /**
     * 默认的回调方法,将v的属性值复制给t,并将t返回
     * @param t    回调对象
     * @param v    目标对象
     * @return
     */
    public <T,V> T defaultExcute(final T t,final V v){
        
        return this.execute(new VoCallback<T>(){
            
            @Override
            public T doInVo() {
                if(v==null) return null;
                BeanUtils.copyProperties(v,t);
                return t;
            }
            
        });
    }
    
    
}

VoCallback.java

package org.lxl.mr.common.base.vo;

public interface VoCallback<T> {
    T doInVo();
}

使用

package org.lxl.mr.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import org.lxl.mr.common.base.service.BaseServiceImpl;
import org.lxl.mr.common.base.vo.VoCallback;
import org.lxl.mr.dao.UserDao;
import org.lxl.mr.pojo.User;
import org.lxl.mr.service.UserService;
import org.lxl.mr.vo.UserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl extends BaseServiceImpl implements UserService {
    
    private UserDao userDao;
    
    @Autowired
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    /**
     * 增加,方法一
     */
    @Override
    public void save(UserVo entityVo) {
        User user = new User();
        user = super.getVoTemplate().defaultExcute(user, entityVo);
        this.userDao.save(user);
    }
    
    /**
     * 增加,方法二
     */
//    @Override
//    public void save(final UserVo entityVo) {
//        
//        //这里是处理entityVo与entity转换的地方
//        User user = super.getVoTemplate().execute(new VoCallback<User>(){
//
//            @Override
//            public User doInVo() {
//                User u = new User();
//                //这句根据主键生成策略决定要、不要、改
//                u.setUuid(UUID.randomUUID().toString().replace("-", ""));
//                u.setUsername(entityVo.getUsername());
//                u.setPassword(entityVo.getPassword());
//                return u;
//            }
//            
//        });
//        
//        //处理业务
//        this.userDao.save(user);
//    }
    
    /**
     * 增加,方法三
     */
//    @Override
//    public void save(UserVo entityVo) {
//        //这里是处理entityVo与entity转换的地方
//        User user = super.getVoTemplate().execute(new UserVoCallback(entityVo));
//        //这里是处理业务的地方
//        this.userDao.save(user);
//    }
    
    /**
     * 增加,方法四
     */
//    @Override
//    public void save(UserVo entityVo) {
//        //这里是处理entityVo与entity转换的地方
//        User user = super.getVoTemplate().execute(new UserVoCallback2(entityVo));
//        //这里是处理业务的地方
//        this.userDao.save(user);
//    }
    
    @Override
    public void update(UserVo entityVo) {
        User user = new User();
        user = super.getVoTemplate().defaultExcute(user, entityVo);
        this.userDao.update(user);
    }

public UserDao getUserDao() {
        return userDao;
    }

@Override
    public void deleteByPK(String pk) {
        this.userDao.deleteByPK(pk, UserVo.PK_NAME);
    }

@Override
    public void delete(UserVo entityVo) {
        User user = new User();
        user = super.getVoTemplate().defaultExcute(user, entityVo);
        this.userDao.delete(user);
        
    }

@Override
    public UserVo get(String pk) {
        User user = this.userDao.get(pk);
        UserVo userVo = new UserVo();
        userVo = super.getVoTemplate().defaultExcute(userVo,user);
        return userVo;
    }

@Override
    public List<UserVo> findAll() {
        List<User> list = this.userDao.findAll();
        List<UserVo> listVo = new ArrayList<UserVo>();
        if(list==null) return null;
        for(User user : list){
            UserVo userVo = new UserVo();
            userVo = super.getVoTemplate().defaultExcute(userVo, user);
            listVo.add(userVo);
        }
        return listVo;
    }

}

上面的例子以save方法为例,给出了voTemplate处理entityVo与entity转化的4种用法。

方法1

使用voTemplate的defaultExcute方法,简单的从 v -> t 复制属性

方法2

使用voTemplate的excute方法,自定义处理方法。

方法2、3、4都是自定义处理方法,只不过在提供VoCallback<T>的实现类方式上有所差别。

这里是用内部类实现的

方法3

提供一个UserVoCallback.java,实现VoCallback接口

以这个类的对象作为voTemplate.execute的参数来实现的。

UerVoCallback.java

package org.lxl.mr.vo.callback;

import org.lxl.mr.common.base.vo.VoCallback;
import org.lxl.mr.pojo.User;
import org.lxl.mr.vo.UserVo;

public class UserVoCallback implements VoCallback<User> {
    private UserVo userVo;
    
    public UserVoCallback(UserVo userVo){
        this.userVo = userVo;
    }
    
    @Override
    public User doInVo() {
        if(userVo==null) return null;
        User user = new User();
        user.setUsername(userVo.getUsername());
        user.setPassword(userVo.getPassword());
        return user;
    }

}

方法4

1) 提供一个VoCallback接口的抽象实现类VoCallbackSupport.java:

VoCallbackSupport.java

package org.lxl.mr.common.base.vo;

public abstract class VoCallbackSupport<T,V> implements VoCallback<T> {
    protected V v;
    public VoCallbackSupport(V v){
        this.v = v;
    }
    @Override
    public abstract T doInVo();

}

2)提供一个UserVoCallback2.java,继承VoCallbackSupport抽象类。

以这个类的对象作为voTemplate.execute的参数来实现的。

UserVoCallback2.java

package org.lxl.mr.vo.callback;

import org.lxl.mr.common.base.vo.VoCallbackSupport;
import org.lxl.mr.pojo.User;
import org.lxl.mr.vo.UserVo;

public class UserVoCallback2 extends VoCallbackSupport<User, UserVo>{

public UserVoCallback2(UserVo v) {
        super(v);
    }

@Override
    public User doInVo() {
        User user = new User();
        user.setUsername(v.getUsername());
        user.setPassword(v.getPassword());
        return user;
    }
    
}

这种方式处理entityVo与entity之间转换与传统的方式一样,还是要程序员自己去处理。

它真正的好处是:

1、规范化处理entityVo与entity之间的转换

2、处理entityVo与entity之间转换的代码与业务代码分离,使代码更清晰

3、在entityVo与entity相似度极高,可以直接复制相同属性的情况下,使用VoTemplate

提供的defalutExcute方法一句话即可实现entityVo与entity的转换,如:

User user = super.getVoTemplate().defaultExcute(new User,entityVo);

非常的方便!

觉得我的这个方案可行的小伙伴不妨在项目中用用,有更好的想法记得告诉我,我们一起提高!

entityVo对象与entity对象的更多相关文章

  1. java Web项目Service层通用接口和entityVo对象与entity对象转化问题的解决方案

    Service层的接口中有一些比较常用方法,一次又一次的在新的Service层中被书写,所以懒惰的程序员又烦了,他们决定写个通用接口来解决这个问题. 有些项目中,实体类即承担接收表单数据的任务,又承担 ...

  2. Dynamics CRM - 在 Dynamics CRM 开发中创建一个 Entity 对象

    在 Dynamics CRM 的开发中,我们时不时需要创建 Entity 对象,而对于如何创建 Entity 对象,在 C# plugin 和 JS 的写法存在些许差异. 一.C# Plugin 创建 ...

  3. EBS OAF开发中实体对象和视图对象的属性设置器

    EBS OAF开发中实体对象和视图对象的属性设置器 (版权声明.本人原创或者翻译的文章如需转载,如转载用于个人学习,请注明出处:否则请与本人联系,违者必究) 源文: Home > Oracle ...

  4. 判断一个对象是jQuery对象还是DOM对象

    今天调试一段代码的时候,看到其中一个变量,想知道它到底是jquery对象还是dom对象. 虽然直接console出这个对象,看它的内部可以判断出来.但是我想有没有什么更方便的方法呢. 后来我想到了一个 ...

  5. 一种简单,轻量,灵活的C#对象转Json对象的方案(续)

    本文参考资料 一种简单,轻量,灵活的C#对象转Json对象的方案 [源码]Literacy 快速反射读写对象属性,字段 一段废话 之前我已经介绍了这个方案的名称为JsonBuilder,这套方案最大的 ...

  6. jQuery对象和DOM对象的区别

    jQuery对象和DOM对象使用说明,需要的朋友可以参考下.1.jQuery对象和DOM对象第一次学习jQuery,经常分辨不清哪些是jQuery对象,哪些是 DOM对象,因此需要重点了解jQuery ...

  7. request 对象和 response 对象

    Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象.和代表响应的response对象 HttpServletResponse HttpServletR ...

  8. DOM对象与jQuery对象的相互转换

    DOM  对象可以使用 js       中的方法,  不能使用jQuery中的方法:jQuery对象只能使用jQuery中的方法, 不能使用js中的方法:jQuery对象是通过jQuery包装DOM ...

  9. js压缩xml字符串,将xml字符串转换为xml对象,将xml对象转换为json对象

    /** * 压缩xml字符串 */ function compressXmlStr(str){ var prefix, suffix; var i = str.indexOf("\r&quo ...

随机推荐

  1. Python脚本之Lrc歌词去时间轴转Txt文件,附带酷狗音乐APP关联已有krc歌词

    一.Lrc歌词去时间轴转Txt文件 环境:Python2.7.x, Mac(Windows需装cygwin环境,当然你也可以自己改代码,Python新手,勿喷) # -*- coding: UTF-8 ...

  2. 一般处理程序获取get,post数据

    ashx具体代码: public class GuanWangWC : IHttpHandler { public void ProcessRequest(HttpContext context) { ...

  3. yolo v2使用总结

    以下都是基于yolo v2版本的,对于现在的v3版本,可以先clone下来,再git checkout回v2版本. 玩了三四个月的yolo后发现数值相当不稳定,yolo只能用来小打小闹了. v2训练的 ...

  4. python 开发接口(一)

    一.首先导入模块  pip install flask 二 1 import flas 2 import json import flask #1.启动一个服务 #2.接收到客户端传过来的数据 #3. ...

  5. html的换行代码<br/>介绍和写法

    在网页中,我们要对文字进行换行,就需要使用到<br/>标签,写法如下 换行:<br/> <br/>属于一个单独标签,仅需要将需要换行的文字后方加入此标签即可实现换行 ...

  6. windows 下借助7zip实现命令行解压缩

    windows 下借助7zip实现命令行解压缩 64位电脑下载 https://www.7-zip.org/a/7z1805-x64.exe 安装 安装目录下所有文件如下: 在命令行下只需要用到 7z ...

  7. Broadcom BCM94352z/DW1560驱动新姿势

    转自:https://blog.daliansky.net/Broadcom-BCM94352z-DW1560-drive-new-posture.html Broadcom WiFi/BlueToo ...

  8. Kubernetes及Dashboard详细安装配置(Ubuntu14.04)

    前些日子部门计划搞并行开发,需要对开发及测试环境进行隔离,所以打算用kubernetes对docker容器进行版本管理,搭建了下Kubernetes集群,过程如下: 本流程使用了阿里云加速器,配置流程 ...

  9. 部分视图 - partial

    对于partia来说,可以理解为组件化的运用,即将对应的html/js/css进行封装,然后通过模板引擎直接进行调用 1.partial的注册 //可以直接写在app.js,也可以写在之前所说的hel ...

  10. React面试题

    React 简述下React的生命周期,性能优化在哪个生命周期,ajax操作在哪个生命周期 React中key的作用是什么 什么是虚拟DOM diff算法原理 React中refs的作用是什么