剛換了公司,項目架構師提出新的系統架構時仍是愣了一下,搭建難度較低,很容易上手,可是對Spring Data JPA的瞭解不夠深刻,因此仍是有些吃力,在框架搭建初期有許多東西並無很好的集成。前端
20180714-這個項目表與表之間的耦合度過低了,且不容許在實體類中進行外鍵對象關聯,一對多、多對1、多對多的關係處理就比較複雜了,Spring Data JPA提供了好幾種不一樣的接口調用方式,所以何時使用什麼樣的方法顯得尤其重要,不一樣的方法編寫方式也不太同樣,在數據處理方面比較頭疼,若是須要抽取不一樣表之間的數據爲結果,要作聯合查詢且須要額外在聲明一個相應的實體類來接受,否則就只能將外鍵表字段存儲到本表中,至關費勁。vue
框架體系java
Spring Boot + Spring Data JPA + Spring Security + Spring Security oAuth2.0 + Thymeleafnode
Spring Bootwebpack
Spring Data JPAweb
Spring Securityspring
Thymeleafexpress
Vue.jsapache
Vue Element-uinpm
Node.js 與 NPM(輔助,安裝Node後,NPM會附帶安裝),附帶webpack工具、路由等。
實體類中並無聲明任何外鍵關聯關係,所以咱們查詢了許多種方法來解決外鍵關聯查詢並返回結果的方法。
Spring Data JPA - JpaRepository
Spring Data JPA - PagingAndSortingRepository
Spring Data JPA - JpaSpecificationExecutor
Spring Data JPA - Query
Spring Data JPA - QueryDSL
Spring Data JPA - CriteriaBuilder
NPM安裝與配置:
配置npm的全局模塊的存放路徑以及cache的路徑,在node根目錄下創建node_cache和node_global文件夾。
啓動CMD,輸入如下命令:
npm config set prefix "D:\DevelopTool\nodejs\node_global" 以及 npm config set cache "D:\DevelopTool\nodejs\node_cache"
安裝(Express)測試模塊,輸入如下命令,-g表明將該插件安裝到全局目錄中,node_golbal。
npm install express -g
設置環境變量,用戶變量下新建"NODE_PATH",輸入」D:\DevelopTool\Nodejs\node_global「。
用戶變量,修改"PATH",添加「%NODE_PATH%;」。
在D:\DevelopTool\nodejs\node_modules\npm目錄下,使用命令行進行安裝。
# install dependency npm install # develop npm run dev
Spring Boot 與 Spring MVC的區別?
Spring 框架就像一個家族,有衆多衍生產品例如 MVC、boot、security、jpa等等。但他們的基礎都是Spring 的 ioc和 aop ioc 提供了依賴注入的容器 aop ,解決了面向橫切面的編程,而後在此二者的基礎上實現了其餘延伸產品的高級功能。
Spring MVC是一個前端框架。Spring MVC是基於 Servlet 的一個 MVC 框架 主要解決 WEB 開發的問題,由於 Spring 的配置很是複雜,各類XML、 JavaConfig、hin處理起來比較繁瑣。
Spring Boot換而言之,是一個Spring框架的一種形式。
Spring Boot實現了自動配置,下降了項目搭建的複雜度。
衆所周知Spring框架須要進行大量的配置,Spring Boot引入自動配置的概念,讓項目設置變得很容易。Spring Boot自己並不提供Spring框架的核心特性以及擴展功能,只是用於快速、敏捷地開發新一代基於Spring框架的應用程序。也就是說,它並非用來替代Spring的解決方案,而是和Spring框架緊密結合用於提高Spring開發者體驗的工具。同時它集成了大量經常使用的第三方庫配置(例如Jackson, JDBC, Mongo, Redis, Mail等等),Spring Boot應用中這些第三方庫幾乎能夠零配置的開箱即用(out-of-the-box),大部分的Spring Boot應用都只須要很是少許的配置代碼,開發者可以更加專一於業務邏輯。、
DAO層代碼示例-20180720從新更新代碼(使用countBy、getBy、findBy等內部規定表達式能夠完成簡單的操做,後續And等,帶實體類對應的屬性名稱便可)
package com.hz.partyorg.dao; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.repository.PagingAndSortingRepository; import com.hz.partyorg.entity.PartyOrgDeclareBasic; import java.util.List; /** * 黨組織-申報信息與基本信息聯合記錄 * @author Wen.C */ public interface PartyOrgDeclareBasicDAO extends JpaRepository<PartyOrgDeclareBasic, Long>, PagingAndSortingRepository<PartyOrgDeclareBasic,Long>, JpaSpecificationExecutor<PartyOrgDeclareBasic> { Long countByDzzSbxxId(String dzzSbxxId); PartyOrgDeclareBasic getByDzzJbxxIdAndDzzSbxxId(String dzzJbxxId, String dzzSbxxId); PartyOrgDeclareBasic getByDzzSbxxIdAndAuditStatus(String dzzSbxxId, String auditStatus); List<PartyOrgDeclareBasic> findByDzzSbxxIdAndAuditStatus(String dzzSbxxId, String auditStatus); }
Service層示例-20180720從新更新代碼:
package com.hz.partyorg.service; import java.util.ArrayList; import java.util.List; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; import com.hz.common.config.GlobalConfig; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Service; import com.hz.partyorg.dao.PartyOrgDeclareBasicDAO; import com.hz.partyorg.entity.PartyOrgDeclareBasic; /** * 黨組織-申報信息與基本信息聯合記錄 * @author Wen.C */ @Service public class PartyOrgDeclareBasicService { @Autowired private PartyOrgDeclareBasicDAO partyOrgDeclareBasicDAO; /** * 黨組織-申報信息與基本信息聯合記錄-保存數據 * @param partyOrgDeclareBasic */ public PartyOrgDeclareBasic save(PartyOrgDeclareBasic partyOrgDeclareBasic) { return partyOrgDeclareBasicDAO.save(partyOrgDeclareBasic); } /** * 黨組織-申報信息-列表查詢,根據傳入Type判斷,標記爲是否爲 0-須要審批的數據 1-歷史數據 * @param type 0-須要審批的數據 1-歷史數據 null-取消條件 * @param partyOrgDeclareBasic 實體對象 * @return */ public List<PartyOrgDeclareBasic> list(Integer type, PartyOrgDeclareBasic partyOrgDeclareBasic){ Specification<PartyOrgDeclareBasic> spec = new Specification<PartyOrgDeclareBasic>() { @Override public Predicate toPredicate(Root<PartyOrgDeclareBasic> root, CriteriaQuery<?> query, CriteriaBuilder cb) { List<Predicate> list = new ArrayList<>(); if(null != type && 0 == type){ // 0-須要審批的數據 list.add(cb.notEqual(root.get("auditStatus"), GlobalConfig.AUDIT_STATUS_TRANSFER_YES)); list.add(cb.notEqual(root.get("auditStatus"), GlobalConfig.AUDIT_STATUS_YES)); } else if(null != type && 1 == type){ // 1-歷史數據 list.add(cb.notEqual(root.get("auditStatus"), GlobalConfig.AUDIT_STATUS_WAITE)); list.add(cb.notEqual(root.get("auditStatus"), GlobalConfig.AUDIT_STATUS_TRANSFER)); } if(StringUtils.isNotEmpty(partyOrgDeclareBasic.getDzzJbxxId()) && StringUtils.isNotBlank(partyOrgDeclareBasic.getDzzJbxxId())){ list.add(cb.equal(root.get("dzzJbxxId"), partyOrgDeclareBasic.getDzzJbxxId())); } if(StringUtils.isNotEmpty(partyOrgDeclareBasic.getDzzSbxxId()) && StringUtils.isNotBlank(partyOrgDeclareBasic.getDzzSbxxId())){ list.add(cb.equal(root.get("dzzSbxxId"), partyOrgDeclareBasic.getDzzSbxxId())); } Predicate[] p = new Predicate[list.size()]; return cb.and(list.toArray(p)); } }; return partyOrgDeclareBasicDAO.findAll(spec ,new Sort(Sort.Direction.DESC, "id")); } /** * 黨組織-申報信息-分頁查詢 * @param partyOrgDeclareBasic 實體對象 * @param pageNo 當前頁碼 * @param pageSize 顯示條數 * @return */ public Page<PartyOrgDeclareBasic> page(PartyOrgDeclareBasic partyOrgDeclareBasic, Integer pageNo, Integer pageSize){ Specification<PartyOrgDeclareBasic> spec = new Specification<PartyOrgDeclareBasic>() { @Override public Predicate toPredicate(Root<PartyOrgDeclareBasic> root, CriteriaQuery<?> query, CriteriaBuilder cb) { List<Predicate> list = new ArrayList<>(); if(StringUtils.isNotEmpty(partyOrgDeclareBasic.getDzzSbxxId()) && StringUtils.isNotBlank(partyOrgDeclareBasic.getDzzSbxxId())){ list.add(cb.equal(root.get("dzzSbxxId"), partyOrgDeclareBasic.getDzzSbxxId())); } if(StringUtils.isNotEmpty(partyOrgDeclareBasic.getDzzJbxxId()) && StringUtils.isNotBlank(partyOrgDeclareBasic.getDzzJbxxId())){ list.add(cb.equal(root.get("dzzJbxxId"), partyOrgDeclareBasic.getDzzJbxxId())); } if(StringUtils.isNotEmpty(partyOrgDeclareBasic.getAuditResultsTime()) && StringUtils.isNotBlank(partyOrgDeclareBasic.getAuditResultsTime())){ list.add(cb.equal(root.get("auditResultsTime"), partyOrgDeclareBasic.getAuditResultsTime())); } Predicate[] p = new Predicate[list.size()]; return cb.and(list.toArray(p)); } }; return partyOrgDeclareBasicDAO.findAll(spec ,new PageRequest(pageNo, pageSize, new Sort(Sort.Direction.DESC, "id"))); } /** * 黨組織-申報信息-分頁查詢(判斷條件:auditResultsTime 審批時間 不爲空) * @param partyOrgDeclareBasic 實體對象 * @param pageNo 當前頁碼 * @param pageSize 顯示條數 * @return */ public Page<PartyOrgDeclareBasic> pageByAuditResultTimeIsNotNull(PartyOrgDeclareBasic partyOrgDeclareBasic, Integer pageNo, Integer pageSize){ Specification<PartyOrgDeclareBasic> spec = new Specification<PartyOrgDeclareBasic>() { @Override public Predicate toPredicate(Root<PartyOrgDeclareBasic> root, CriteriaQuery<?> query, CriteriaBuilder cb) { List<Predicate> list = new ArrayList<>(); if(null != partyOrgDeclareBasic.getDzzJbxxId() && StringUtils.isNotBlank(partyOrgDeclareBasic.getDzzJbxxId())){ list.add(cb.equal(root.get("dzzJbxxId"), partyOrgDeclareBasic.getDzzJbxxId())); } list.add(root.get("auditResultsTime").isNotNull()); Predicate[] p = new Predicate[list.size()]; return cb.and(list.toArray(p)); } }; return partyOrgDeclareBasicDAO.findAll(spec ,new PageRequest(pageNo, pageSize, new Sort(Sort.Direction.DESC, "id"))); } /** * 根據黨組織ID查詢記錄總數 * @param dzzSbxxId * @return */ public Long countByDzzSbxxId(String dzzSbxxId) { return partyOrgDeclareBasicDAO.countByDzzSbxxId(dzzSbxxId); } /** * 根據黨組織Id和申報信息Id查詢指定數據 * @param dzzJbxxId * @param dzzSbxxId * @return */ public PartyOrgDeclareBasic getByDzzJbxxIdAndDzzSbxxId(String dzzJbxxId, String dzzSbxxId) { return partyOrgDeclareBasicDAO.getByDzzJbxxIdAndDzzSbxxId(dzzJbxxId, dzzSbxxId); } /** * 根據申報信息Id和審批狀態查詢指定數據 * @param dzzSbxxId * @param auditStatus * @return */ public PartyOrgDeclareBasic getByDzzSbxxIdAndAuditStatus(String dzzSbxxId, String auditStatus) { return partyOrgDeclareBasicDAO.getByDzzSbxxIdAndAuditStatus(dzzSbxxId, auditStatus); } /** * 根據申報信息Id和審批狀態查詢數據返回集合 * @param dzzSbxxId * @param auditStatus * @return */ public List<PartyOrgDeclareBasic> findByDzzSbxxIdAndAuditStatus(String dzzSbxxId, String auditStatus) { return partyOrgDeclareBasicDAO.findByDzzSbxxIdAndAuditStatus(dzzSbxxId, auditStatus); } }
Manager特殊業務處理層與Dao同級存在,不一樣業務場景調用(用於關聯表查詢以及返回聯合數據結果)-20180720,使用到QueryDSL。
package com.hz.partyorg.dao; import com.hz.partyorg.entity.*; import com.hz.partyorg.vo.PartyOrgDeclareInformationVo; import com.querydsl.core.Tuple; import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQueryFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 申報信息、申報與黨組織信息聯合處理類,聯合查詢,返回Vo實體類對象,自由封裝 */ @Component public class PartyOrgDeclareBasicManager { @Autowired @PersistenceContext private EntityManager entityManager; private JPAQueryFactory queryFactory; @PostConstruct public void init() { queryFactory = new JPAQueryFactory(entityManager); } /** * 針對申報信息作的聯合查詢方法 * @param dzzJbxxId 黨組織ID * @param dzzSbxxIds 申報信息ID 集合 * @param pageNo 當前頁數 * @param pageSize 每頁顯示條數 * @return */ public Map<String,Object> findList(String dzzJbxxId, List<Long> dzzSbxxIds, Integer pageNo, Integer pageSize){ Map<String,Object> result = new HashMap<>(); QPartyOrgDeclareInformation partyOrgDeclareInformation = QPartyOrgDeclareInformation.partyOrgDeclareInformation; QPartyOrgDeclareBasic partyOrgDeclareBasic = QPartyOrgDeclareBasic.partyOrgDeclareBasic; // JPAQuery<PartyOrgDeclareInformation> jpaQuery = queryFactory.select(partyOrgDeclareInformation).from(partyOrgDeclareInformation) // .leftJoin(partyOrgDeclareBasic) // .on(partyOrgDeclareBasic.dzzSbxxId.eq(partyOrgDeclareInformation.id.toString())) // .where(partyOrgDeclareInformation.id.in(dzzSbxxIds)); int jpaQueryPageAllNum = queryFactory.select(partyOrgDeclareInformation, partyOrgDeclareBasic) .from(partyOrgDeclareInformation) .innerJoin(partyOrgDeclareBasic) .on(partyOrgDeclareBasic.dzzSbxxId.eq(partyOrgDeclareInformation.id.stringValue())) .where(partyOrgDeclareInformation.id.in(dzzSbxxIds)) .where(partyOrgDeclareBasic.dzzJbxxId.eq(dzzJbxxId)) .fetch() .size(); JPAQuery<Tuple> jpaQuery = queryFactory.select(partyOrgDeclareInformation, partyOrgDeclareBasic) .from(partyOrgDeclareInformation) .innerJoin(partyOrgDeclareBasic) .on(partyOrgDeclareBasic.dzzSbxxId.eq(partyOrgDeclareInformation.id.stringValue())) .where(partyOrgDeclareInformation.id.in(dzzSbxxIds)) .where(partyOrgDeclareBasic.dzzJbxxId.eq(dzzJbxxId)) .offset(pageNo) .limit(pageSize); List<Tuple> tuples = jpaQuery.fetch(); List<PartyOrgDeclareInformationVo> voList = new ArrayList<>(); if(null != tuples && !tuples.isEmpty()){ for(Tuple tuple:tuples){ PartyOrgDeclareInformation partyOrgDeclareInformationResult = tuple.get(0, PartyOrgDeclareInformation.class); PartyOrgDeclareBasic partyOrgDeclareBasicResult = tuple.get(1, PartyOrgDeclareBasic.class); PartyOrgDeclareInformationVo vo = new PartyOrgDeclareInformationVo(); // 1- 申報信息 vo.setId(partyOrgDeclareInformationResult.getId()); vo.setDeclarationTypeName(partyOrgDeclareInformationResult.getDeclarationTypeName()); vo.setDeclarationItem(partyOrgDeclareInformationResult.getDeclarationItem()); vo.setDeclarationTime(partyOrgDeclareInformationResult.getDeclarationTime()); vo.setDeclarer(partyOrgDeclareInformationResult.getDeclarer()); vo.setDeclarationOrg(partyOrgDeclareInformationResult.getDeclarationOrg()); vo.setAuditResults(partyOrgDeclareInformationResult.getAuditResults()); // 2- 申報聯合信息 vo.setAuditStatus(partyOrgDeclareBasicResult.getAuditStatus()); vo.setAuditStatusName(partyOrgDeclareBasicResult.getAuditStatusName()); vo.setAuditResultsTime(partyOrgDeclareBasicResult.getAuditResultsTime()); vo.setDzzJbxxId(Long.valueOf(partyOrgDeclareBasicResult.getDzzJbxxId())); voList.add(vo); } } result.put("pageAllNum", jpaQueryPageAllNum); result.put("voList", voList); return result; } }
知識點
Vue
路由跳轉:
this.$router.push({ path: '/partyAffairsManager/partyOrgLifeManager', query: { activeName: 'partyClassRegistration', show: true } });
常見問題
Swagger相關
問題描述:
1.主表設置一對多的實體類對應關係@OneToMany;
2.swagger掃描對應的包路徑;
報錯問題:
項目啓動報錯,註釋掉一對多關係後,可正常啓動。
at springfox.documentation.spring.web.readers.parameter.ModelAttributeParameterExpander.expand(ModelAttributeParameterExpander.java:110) ~[springfox-spring-web-2.6.1.jar:2.6.1]
解決辦法:
數據報錯 JPA 多對一屬性 persist出錯
問題描述:
1.從表設置多對一關係@ManyToOne
報錯問題:
進行數據保存時報錯。
detached entity passed to persis
解決方法:
@Query 註解動態查詢沒法使用LIMIT關鍵詞
JPQL和原生的SQL,JPQL沒有LIMIT關鍵詞
Vue Element-ui
相關命令:
# 安裝 npm install # 版本查詢 npm ls element-ui # 卸載 npm uninstall element-ui # 從新安裝 npm i element-ui -S # 啓動項目 npm run dev # 安裝指定版本 npm install element-ui@2.3.7 -S
樹型控件 Treeselect
https://vue-treeselect.js.org/#customize-key-names
# 安裝命令 npm install --save @riophae/vue-treeselect
時間控件 Moment
# 安裝命令 npm install moment
Vue問題記錄:
若是沒有傳遞迴顯數據給表單對象,則回顯時,表單控件如Select是點擊無反應的。