刚换了公司,项目架构师提出新的系统架构时仍是愣了一下,搭建难度较低,很容易上手,可是对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是点击无反应的。