这篇“怎么利用泛型封装通用的service层”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“怎么利用泛型封装通用的service层”文章吧。
身为一名开发人员,大家都知道,我们经常会在项目中大量的编写许多重复的代码,比如说
public Entity find(String id);
像这种代码,简单,但是写多了,可能也会容易出错,那么我们能不能直接编写一套完整的,通用的方法呢,这样既不用重复编写,还不用出错,说道通用的方法,泛型是个不错的选择.
基础架构:spring-boot+spring mvc+spring jpa.
jpa是个好东西,个人感觉它最大的好处是不需要自己手动建表.还能在修改了表字段以后,自动给你添加上上去,它不像mybatis,业务改了之后,还需要调整sql语句,
好了,废话不多说,上代码:
一、首先建立一个实体类WebVisitRecordEntity
继承BaseEntity.BaseEntity在项目里面,是所有实体类的最顶层.里面是封装了一些通用的属性.
BaseEntity
package cn.yxw.function; import cn.yxw.function.Enum.status.StatusEnum; import javax.persistence.Column;import javax.persistence.Id;import javax.persistence.MappedSuperclass;import java.io.Serializable;import java.util.Date; @MappedSuperclasspublic abstract class BaseEntity implements Serializable{ @Id @Column(length = 32 ) private String id; private Date createTime; @Column(length = 32 ) private String createUser; private Date updateTime; @Column(length = 32 ) private String updateUser; @Column(length = 8 ) private String delStatus = StatusEnum.FALSE.getStatus(); @Column(length = 8 ) private String enAbleStatus = StatusEnum.TRUE.getStatus(); public String getId() { return id; } public void setId(String id) { this.id = id; } public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } public String getCreateUser() { return createUser; } public void setCreateUser(String createUser) { this.createUser = createUser; } public Date getUpdateTime() { return updateTime; } public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; } public String getUpdateUser() { return updateUser; } public void setUpdateUser(String updateUser) { this.updateUser = updateUser; } public String getDelStatus() { return delStatus; } public void setDelStatus(String delStatus) { this.delStatus = delStatus; } public String getEnAbleStatus() { return enAbleStatus; } public void setEnAbleStatus(String enAbleStatus) { this.enAbleStatus = enAbleStatus; }}
WebVisitRecordEntity
package cn.yxw.function.domain.plugins; import cn.yxw.function.BaseEntity; import javax.persistence.Entity;import javax.persistence.Inheritance;import javax.persistence.InheritanceType;import javax.persistence.Table; @Entity()@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)@Table(name = "web_visit_Record")public class WebVisitRecordEntity extends BaseEntity { private static final long serialVersionUID = 341666498307329777L; private int count = 0; public int getCount() { return count; } public void setCount(int count) { this.count = count; }}
二、有了实体类之后
首先建立一个顶层的api接口。所有通用的api方法,可以放在这里(ResultBean是一个封装了一个结果的数据类,里面包含了定义执行是否成功,执行返回的数据,执行错误提示的消息)
package cn.yxw.function; import cn.yxw.function.result.ResultBean;import org.springframework.data.domain.Page;import org.springframework.data.domain.Pageable; public interface BaseApi<T extends BaseEntity> { T get(String id); T find(String id); ResultBean<T> delete(String id); ResultBean<T> delete(T entity); ResultBean<T> create(T entity); ResultBean<T> update(T entity); Page<T> page(Pageable pageable); boolean exists(String id); }
三、实现BaseApi
既然是要定义通用的api,那么不仅仅只是一套接口,我们需要在定义一个可以实现BaseApi的BaseServiceImpl,之后的所有实现类,都可以继承这个BaseServiceImpl.java的泛型,给了我们的项目很好的扩展性,而顶层BaseEntity也给了我很好的实现方案,将BaseEntity作为泛型的入口
基本时限BaseApi
package cn.yxw.function.service.impl.domain.userCenter; import cn.yxw.function.BaseApi;import cn.yxw.function.BaseEntity;import cn.yxw.function.result.ResultBean;import org.springframework.data.domain.Page;import org.springframework.data.domain.Pageable; public class BaseServiceImpl<T extends BaseEntity> implements BaseApi<T> { @Override public T get(String id) { return null; } @Override public T find(String id) { return null; } @Override public ResultBean<T> delete(String id) { return null; } @Override public ResultBean<T> delete(T entity) { return null; } @Override public ResultBean<T> create(T entity) { return null; } @Override public ResultBean<T> update(T entity) { return null; } @Override public Page<T> page(Pageable pageable) { return null; } @Override public boolean exists(String id) { return false; }}
使用jpa作为BaseServiceImpl的属性.
package cn.yxw.function.service.impl.domain.userCenter; import cn.yxw.function.BaseApi;import cn.yxw.function.BaseEntity;import cn.yxw.function.Enum.code.ServiceCodeEnum;import cn.yxw.function.result.ResultBean;import cn.yxw.function.util.ObjectUtil;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.domain.Page;import org.springframework.data.domain.Pageable;import org.springframework.data.jpa.repository.JpaRepository; public class BaseServiceImpl<T extends BaseEntity> implements BaseApi<T> { @Autowired private JpaRepository<T, String> baseRepository; @Override public T get(String id) { T entity = this.baseRepository.getOne(id); return entity; } @Override public T find(String id) { return this.baseRepository.findById(id).get(); } @Override public ResultBean<T> delete(String id) { this.baseRepository.deleteById(id); return ResultBean.success(""); } @Override public ResultBean<T> delete(T entity) { this.baseRepository.delete(entity); return ResultBean.success(entity); } @Override public ResultBean<T> create(T entity) { if(ObjectUtil.isNull(entity)){ return ResultBean.failfure("数据为空,无法创建!"); } if(this.exists(entity.getId())){ return ResultBean.failfure("实体id相同,无法重复创建!"); } entity = this.baseRepository.saveAndFlush(entity); if(ObjectUtil.isNull(entity)){ return ResultBean.failfure(ServiceCodeEnum.CORE_SYSTEM_FAILURE); } return ResultBean.success(entity); } @Override public ResultBean<T> update(T entity) { if(ObjectUtil.isNull(entity)){ return ResultBean.failfure("数据为空,无法创建!"); } if(!this.exists(entity.getId())){ return ResultBean.failfure("数据库不存在该数据,无法执行更新"); } entity = this.baseRepository.saveAndFlush(entity); if(ObjectUtil.isNull(entity)){ return ResultBean.failfure(ServiceCodeEnum.CORE_SYSTEM_FAILURE); } return ResultBean.success(entity); } @Override public Page<T> page(Pageable pageable) { return null; } @Override public boolean exists(String id) { return this.baseRepository.existsById(id); }}
四、定义类自己的api
继承BaseApi,定义实现类,继承BaseServiceImpl.并实现自己的api
package cn.yxw.function.domain.userCenter; import cn.yxw.function.BaseApi;import cn.yxw.function.domain.plugins.WebVisitRecordEntity; public interface WebVisitRecordApi extends BaseApi<WebVisitRecordEntity> {}
package cn.yxw.function.service.impl.domain.userCenter; import cn.yxw.function.domain.plugins.WebVisitRecordEntity;import cn.yxw.function.domain.userCenter.WebVisitRecordApi;import org.springframework.stereotype.Service; @Servicepublic class WebVisitRecordServiceImpl extends BaseServiceImpl<WebVisitRecordEntity> implements WebVisitRecordApi { }
五、测试
到这里,代码已经结束. 测试一下,构建下controller层. 并进行测试
package cn.yxw.function.controller.System.admin; import cn.yxw.function.controller.BaseController;import cn.yxw.function.domain.plugins.WebVisitRecordEntity;import cn.yxw.function.result.ResultBean;import cn.yxw.function.service.impl.domain.userCenter.WebVisitRecordServiceImpl;import cn.yxw.function.util.ObjectUtil;import com.alibaba.druid.util.StringUtils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController; import java.util.Date;import java.util.Map; @RestController()@RequestMapping(value = "web/record")public class WebVisitRecordsController extends BaseController { @Autowired private WebVisitRecordServiceImpl webVisitRecordService; @GetMapping(value = "/get") public Map get(String id){ if(StringUtils.isEmpty(id)){ return this.errorWithMsg("参数不得为空"); } WebVisitRecordEntity entity = this.webVisitRecordService.find(id); return this.result(entity,""); } @PostMapping(value = "/create") public Map create(int num){ WebVisitRecordEntity entity = new WebVisitRecordEntity(); entity.setId(System.currentTimeMillis()+""); entity.setCreateTime(new Date()); entity.setCount(num); ResultBean<WebVisitRecordEntity> result = this.webVisitRecordService.create(entity); return this.result(result.getDate(),result.getMsg()); } @PostMapping(value = "/update") public Map update(String id, int num){ if(StringUtils.isEmpty(id)){ return this.errorWithMsg("参数不得为空"); } WebVisitRecordEntity entity = this.webVisitRecordService.find(id); if(ObjectUtil.isNull(entity)){ return this.errorWithMsg("不存在该数据"); } entity.setUpdateTime(new Date()); entity.setCount(entity.getCount()+num); ResultBean<WebVisitRecordEntity> result = this.webVisitRecordService.update(entity); return this.result(result.getDate(),result.getMsg()); } }
三次测试都已经成功,但是我们真实的项目不可能这么简单.所以我们再次测试下扩展性
等等,不知道你们发现没有,上面的代码有一段是错误的.
我在controller层的属性不是api,而是实现类.......
虽然不影响,但是就无法扩展了...此处做修正
六、扩展性
WebVisitRecordApi
package cn.yxw.function.domain.userCenter; import cn.yxw.function.BaseApi;import cn.yxw.function.domain.plugins.WebVisitRecordEntity; public interface WebVisitRecordApi extends BaseApi<WebVisitRecordEntity> { int countAll();}
WebVisitRecordServiceImpl
package cn.yxw.function.service.impl.domain.userCenter; import cn.yxw.function.domain.plugins.WebVisitRecordEntity;import cn.yxw.function.domain.userCenter.WebVisitRecordApi;import cn.yxw.function.util.ObjectUtil;import org.springframework.stereotype.Service; import java.util.List; @Servicepublic class WebVisitRecordServiceImpl extends BaseServiceImpl<WebVisitRecordEntity> implements WebVisitRecordApi { @Override public int countAll() { List<WebVisitRecordEntity> list = super.baseRepository.findAll(); int count = 0; if(ObjectUtil.isNull(list) || list.size() <= 0){ return count; } for (WebVisitRecordEntity entity : list){ count += entity.getCount(); } return count; }}
WebVisitRecordController
@GetMapping(value = "count") public Map count(){ return this.result(this.webVisitRecordService.countAll(),"执行成功"); }
测试
以上就是关于“怎么利用泛型封装通用的service层”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网行业资讯频道。