Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 801|回复: 0

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

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-5-31 07:06:29 | 显示全部楼层 |阅读模式

    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
    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-2 16:00 , Processed in 0.058254 second(s), 27 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表