<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
身為一名開發人員,大家都知道,我們經常會在專案中大量的編寫許多重複的程式碼,比如說
public Entity find(String id);
像這種程式碼,簡單,但是寫多了,可能也會容易出錯,那麼我們能不能直接編寫一套完整的,通用的方法呢,這樣既不用重複編寫,還不用出錯,說道通用的方法,泛型是個不錯的選擇.
基礎架構:spring-boot+spring mvc+spring jpa.
jpa是個好東西,個人感覺它最大的好處是不需要自己手動建表.還能在修改了表欄位以後,自動給你新增上上去,它不像mybatis,業務改了之後,還需要調整sql語句,
好了,廢話不多說,上程式碼:
繼承BaseEntity.BaseEntity在專案裡面,是所有實體類的最頂層.裡面是封裝了一些通用的屬性.
1.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; /** * @Author : yuanxw * @Description: 所有實體的父類別 * @Date: Created in 17:03 2018/5/15 */ @MappedSuperclass public abstract class BaseEntity implements Serializable{ /** * id */ @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; } }
2.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; /** * @Author : yuanxw * @Description: * @Date: Created in 15:16 2018/6/20 */ @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; /** * @Author : yuanxw * @Description: * @Date: Created in 10:32 2018/5/25 */ public interface BaseApi<T extends BaseEntity> { /** * 查詢 * @param id * @return */ T get(String id); /** * 查詢 * @param id * @return */ T find(String id); /** * 刪除 * @param id * @return */ ResultBean<T> delete(String id); ResultBean<T> delete(T entity); /** * 建立 * @param entity * @return */ ResultBean<T> create(T entity); /** * 更新 * @param entity * @return */ ResultBean<T> update(T entity); /** * 讀取所有 * @param pageable * @return */ Page<T> page(Pageable pageable); /** * 判斷id是否存在 * @param id * @return */ boolean exists(String id); }
既然是要定義通用的api,那麼不僅僅只是一套介面,我們需要在定義一個可以實現BaseApi的BaseServiceImpl,之後的所有實現類,都可以繼承這個BaseServiceImpl.java的泛型,給了我們的專案很好的擴充套件性,而頂層BaseEntity也給了我很好的實現方案,將BaseEntity作為泛型的入口
1.基本時限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; /** * @Author : yuanxw * @Description: * @Date: Created in 14:31 2018/6/20 */ 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; } }
2.使用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; /** * @Author : yuanxw * @Description: * @Date: Created in 14:31 2018/6/20 */ 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); } }
繼承BaseApi,定義實現類,繼承BaseServiceImpl.並實現自己的api
package cn.yxw.function.domain.userCenter; import cn.yxw.function.BaseApi; import cn.yxw.function.domain.plugins.WebVisitRecordEntity; /** * @Author : yuanxw * @Description: * @Date: Created in 14:44 2018/6/22 */ 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; /** * @Author : yuanxw * @Description: * @Date: Created in 15:22 2018/6/20 */ @Service public 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; /** * @Author : yuanxw * @Description: * @Date: Created in 15:23 2018/6/20 */ @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,而是實現類.......
雖然不影響,但是就無法擴充套件了...此處做修正
1. WebVisitRecordApi
package cn.yxw.function.domain.userCenter; import cn.yxw.function.BaseApi; import cn.yxw.function.domain.plugins.WebVisitRecordEntity; /** * @Author : yuanxw * @Description: * @Date: Created in 14:44 2018/6/22 */ public interface WebVisitRecordApi extends BaseApi<WebVisitRecordEntity> { /** * 統計所有的記錄之和 * @return */ int countAll(); }
2. 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; /** * @Author : yuanxw * @Description: * @Date: Created in 15:22 2018/6/20 */ @Service public 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; } }
3. WebVisitRecordController
@GetMapping(value = "count") public Map count(){ return this.result(this.webVisitRecordService.countAll(),"執行成功"); }
4.測試
emmmm.....其實我上面還有個小錯誤,就留給你們尋找吧
其實,封裝的這個service層,也有很大的侷限性,比如說,如果我需要自定義dao層的方法,怎麼辦?需要執行sql語句怎麼辦,仔細想想,我們能不能再封裝一個BaseRepository呢?然後作為BaseServiceImpl中的屬性傳入??????
以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45