java Web項目Service層通用接口和entityVo對象與entity對象轉化問題的解決方案


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);

非常的方便!


覺得我的這個方案可行的小伙伴不妨在項目中用用,有更好的想法記得告訴我,我們一起提高!



原文地址:https://blog.csdn.net/jianmo777/article/details/50342575


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM