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
java Web项目Service层通用接口和entityVo对象与entity对象转化问题的解决方案的更多相关文章
- java web项目war包部署,使用tomcat对指定接口设置身份认证
先简单说一下需求: 将一个基于springboot2.0开发的java web项目打成war包,通过tomcat部署到一台linux服务器上,项目相关的一些图片等资源也按照一定规则放置在服务器构建好的 ...
- SpringMVC内容略多 有用 熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器、过滤器等Web组件以及MVC架构模式进行Java Web项目开发的经验。
熟悉基于JSP和Servlet的Java Web开发,对Servlet和JSP的工作原理和生命周期有深入了解,熟练的使用JSTL和EL编写无脚本动态页面,有使用监听器.过滤器等Web组件以及MVC架构 ...
- Intellij IDEA Java web 项目搭建
Java web 项目搭建 简介 在上一节java web环境搭建中,我们配置了开发java web项目最基本的环境,现在我们将采用Spring MVC+Spring+Hibernate的架构搭建一个 ...
- Intellij IDEA采用Maven+Spring MVC+Hibernate的架构搭建一个java web项目
原文:Java web 项目搭建 Java web 项目搭建 简介 在上一节java web环境搭建中,我们配置了开发java web项目最基本的环境,现在我们将采用Spring MVC+Spring ...
- Java web 项目搭建
Java web 项目搭建 简介 在上一节java web环境搭建中,我们配置了开发java web项目最基本的环境,现在我们将采用Spring MVC+Spring+Hibernate的架构搭建一个 ...
- Java web项目综合练习(Estore)
Java web项目综合练习(Estore) 复习day18: ajax代码的书写步骤 2)json格式文本,转js对象的方法是那个 项目开发流程介绍 这里学习的JavaWEB项目实战,主要是把前面学 ...
- 一个完整Java Web项目背后的密码
前言 最近自己做了几个Java Web项目,有公司的商业项目,也有个人做着玩的小项目,写篇文章记录总结一下收获,列举出在做项目的整个过程中,所需要用到的技能和知识点,带给还没有真正接触过完整Java ...
- java web项目为什么我们要放弃jsp?
前戏: 以前的项目大多数都是java程序猿又当爹又当妈,又搞前端(ajax/jquery/js/html/css等等),又搞后端(java/mysql/Oracle等等). 随着时代的发展,渐渐的许多 ...
- java web项目答辩答辩题总结(书本网上语言答辩+自己的语言答辩)
答辩每个人的总分为1.5分.每个人主要问3个问题. 开发流程===>系统架构====>项目模块+功能===>项目得失重定向与转发:?九个隐式对象?get与post的区辨:?jsp有静 ...
随机推荐
- GeoTools坐标转换(投影转换和仿射变换)
GeoTools是在java下的gis开源软件,以下介绍坐标转换的两种方法:投影转换和仿射变换 投影转换 这里以xian80经纬度坐标转xian80,3度分带 111中央经线平面坐标为例 转换函数如下 ...
- 毕业设计:HomeFragment(一)
一.主要思路 主要是通过ListView实现. 考虑到以后会添加长按修改功能,所以好几个地方都是用的FramLayout,而且CheckBox初始状态是被隐藏的.给ListView添加OnItemCl ...
- Tcl介绍和基础语法
Tcl的背景 Tcl(读作tickle)诞生于80年代的加州大学伯克利分校,作为一种简单高效可移植性好的脚本语言,目前已经广泛应用在几乎所有的EDA工具中.Tcl 的最大特点就是其语法格式极其简单,采 ...
- COGS 1361. 树
★ 输入文件:treed.in 输出文件:treed.out 简单对比时间限制:1 s 内存限制:128 MB [问题描述] 在一个凉爽的夏夜,xth和rabbit来到花园里砍树.为啥 ...
- Android(java)学习笔记182:多媒体之撕衣服的案例
1.撕衣服的案例逻辑: 是两者图片重叠在一起,上面我们看到的是美女穿衣服的图片,下面重叠(看不到的)是美女没有穿衣服的图片.当我们用手滑动画面,上面美女穿衣服的图片就会变成透明,这样的话下 ...
- HDU 5778 abs (暴力枚举)
abs Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Problem De ...
- window Chrome 下允许跨域访问服务端接口设置
关闭chrome,使用cmd命令进入chrome安装目录cd C:\Program Files (x86)\Google\Chrome\Application 然后使用命令打开chromechrome ...
- 树状数组 || POJ 2352 Stars
Astronomers often examine star maps where stars are represented by points on a plane and each star h ...
- 关于DTCC数据库技术大会
本次DTCC数据库技术大会是第9届了,这次大会虽然有不少公司的产品推介,总体来说还是有不少干货的. 专场较多,有选择地主要听了大数据实践跟流式计算这块.网易跟滴滴的分享比较不错. 了解到了现在大家是用 ...
- 数据结构——RMQ
RMQ 今天临放学前终于是学会了RMQ,特此写一篇题解来缅怀 RMQ是一种数据结构,用途是查询区间内最大值或最小值 或者你所要求的任意条件,主要思想是二进制的思想,其中还用到了dp的思想, 是一种非常 ...