标签:tput lin 员工信息 map framework 使用 ase 额外 column
前言:网上很少见到完整版的spring boot+jpa的整套规范写法,这里自己写了下,选择了最常用的多对一,花费了横跨好几周的三个下午的大片零碎时间,写了三个版本,现在发布一下其中较简单且规范的一版。这里的规范指的是jpa规范,取巧的方式很多,但完整符合jpa多对一写法的,在本文当中。下图是完整目录结构:
项目内的一些功能的实现,多数都使用了两种写法,按需自取。部分代码可能因作者的喜好或局限性问题,导致并不符合某些开发规范,有不同意见请留言。前方高能,大量代码出没,请自重。
工具、技术版本:jdk 8.18、eclipse 2019-6、maven 3.3.9、spring boot 2.2.6、lombok 1.18.12、mysql 5.5.61、layui 2.5.4
话不多说,直接粘代码,注释很全了。
1.pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.xfyuao</groupId> <artifactId>spring-boot-jpa-layui-2</artifactId> <version>0.0.1-SNAPSHOT</version> <name>spring-boot-jpa-layui-2</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot.version>2.2.6.RELEASE</spring-boot.version> </properties> <dependencies> <!-- jpa依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <!-- springmvc依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- mysql依赖 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <!-- lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <!-- 热部署 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> <scope>true</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <!-- springboot版本 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> </project>
2.application.properties
#应用项目名称 #server.context-path=/mydemo #应用端口 #server.port=8080 # 数据源配置,IDEA当中需主动配置时区为GMT+8 spring.datasource.url=jdbc:mysql://localhost:3306/ace?serverTimezone=GMT%2B8 spring.datasource.username=root spring.datasource.password=admin spring.datasource.driver-class-name=com.mysql.jdbc.Driver ##Spring Data JPA 配置,指明用的数据库,数据库方言,因为要生成sql语句 spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect ##运行时输出 jpa 执行的 sql 语句 spring.jpa.show-sql=true ## spring-boot-starter-data-jpa 自动映射创建表动作 配置: 有表更新,无表创建,按名称判断不会更新类型 spring.jpa.hibernate.ddl-auto=update #修改 tomcat 的 URIEncoding 为 UTF-8 server.tomcat.uri-encoding=UTF-8 #集中解决各种编码问题 #banner.charset=UTF-8 spring.http.encoding.charset=UTF-8 spring.http.encoding.enabled=true spring.http.encoding.force=true spring.messages.encoding=UTF-8 #jackson 对日期时间格式化设置 #springmvc(也就是controller层)返回前端页面时遵守的日期格式,把Date转化为String spring.jackson.date-format=yyyy-MM-dd HH:mm:ss #jackson 对日期时间格式化设置:时区设置 spring.jackson.time-zone=GMT+8
3.启动类
package com.xfyuao; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; @SpringBootApplication @EnableJpaRepositories("com.xfyuao.dao") public class App { public static void main(String[] args) { SpringApplication.run(App.class,args); } }
4.实体类、一:Dept
package com.xfyuao.domain; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import javax.persistence.*; import java.io.Serializable; @Entity//基于该类建表 @Table(name = "t_dept")//表名 @Data//主要要getter、setter、toString @AllArgsConstructor//全参构造器 @NoArgsConstructor//无参构造器 public class Dept implements Serializable { @Id//标注主键列 @GeneratedValue(strategy = GenerationType.IDENTITY)//mysql支持主键自增 @Column(columnDefinition="int unsigned NOT NULL comment ‘备注:部门编号,主键自动增长‘") private Integer deptNo; @Column(columnDefinition="varchar(20) NOT NULL comment ‘备注:部门名称‘") private String dname; @Column(columnDefinition="text comment ‘备注:办公地点‘") private String loc; }
package com.xfyuao.domain; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import javax.persistence.*; import org.springframework.format.annotation.DateTimeFormat; import java.io.Serializable; import java.util.Date; @Entity @Table(name = "t_emp") @Data @AllArgsConstructor @NoArgsConstructor public class Emp implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(columnDefinition = "int unsigned NOT NULL comment ‘备注:员工编号,主键自动增长‘") private Integer empNo; @Column(columnDefinition = "char(34) NOT NULL comment ‘备注:后台生成的卡号‘") private String empCardNo; @Column(columnDefinition = "varchar(20) NOT NULL comment ‘备注:员工姓名‘") private String ename; @Column(columnDefinition = "datetime NOT NULL comment ‘备注:入职日期‘") @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")//springmvc接收日期字符串时按该格式转化成日期 private Date hiredate; @Column(columnDefinition = "char(1) NOT NULL comment ‘备注:员工状态,0表示正常在职‘") private Integer state; @Column(columnDefinition = "text comment ‘备注:备注‘") private String remake; // 不要级联增删改 @ManyToOne(targetEntity = Dept.class, cascade = CascadeType.REFRESH, fetch = FetchType.EAGER) //会自动在emp表新建非空列dept_no,作为外键,但不会创建外键约束 @JoinColumn(name = "deptNo", referencedColumnName = "deptNo") private Dept dept; }
5.接口
package com.xfyuao.dao; import com.xfyuao.domain.Dept; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import javax.transaction.Transactional; /** * 部门的dao接口,一个方法对于一条sql语句 * 继承JpaRepository接口获取基本的crud方法 * 继承JpaSpecificationExecutor获取实现动态sql查询的方法 * */ public interface DeptDao extends JpaRepository<Dept, Integer>, JpaSpecificationExecutor<Dept> { /** * 这个方法完全不用写,就使用save方法返回实体类即可 * 原因:继承的修改方法,在修改时如果没有某一列的值会把该列修改为null, * 所以想修改部分列、但不修改的列未传值,就需要使用自定义修改语句:JPQL或原生SQL * 方式:原生SQL * @return Modifying queries can only use void or int/Integer as return type! * */ @Query(value = "update t_dept set dname=?1,loc=?2 where dept_no=?3 ", nativeQuery = true) @Modifying @Transactional public Integer updateDept(String dame,String loc,Integer deptNo); }
package com.xfyuao.dao; import com.xfyuao.domain.Dept; import com.xfyuao.domain.Emp; import java.util.List; import javax.transaction.Transactional; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; public interface EmpDao extends JpaRepository<Emp, Integer>, JpaSpecificationExecutor<Emp> { /** * 根据外键id查询,使用的是关键字抽象方法,也可以使用原生sql实现; * @param dept 只需要部门编号即可 * @return 该部门下的学生 * */ /*关键字抽象方法:findBy/readBy/getBy开头,加上属性名, * 表示根据该属性查询,参数对应该属性,有多个条件使用关键字拼接 */ public List<Emp> findByDept(Dept dept); }
6.dto
package com.xfyuao.dto; import java.util.Date; import org.springframework.format.annotation.DateTimeFormat; import com.xfyuao.domain.Emp; import lombok.Data; /** * 数据传输类,有额外的查询条件在该类中定义 * 如:日期区间的多的一个日期 * */ @Data public class EmpDto extends Emp { @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") private Date hiredate2;//结束日期 //page分页的一种实现方式,另一种是每次接数据直接用PageUtil类接,参见DeptController的selectPageDept方法 private Integer page=1 ;// 页码 private Integer limit=10;// 每页条数 @Override public String toString() { return super.toString() + " EmpDto [hiredate2=" + hiredate2 + ", page=" + page + ", limit=" + limit + "]"; } }
7.service
package com.xfyuao.service; import com.xfyuao.domain.Dept; import com.xfyuao.util.PageUtil; import java.util.List; import org.springframework.data.domain.Page;
/** * 部门的业务层,一个方法对应页面一个按钮功能 * 复杂业务逻辑要在本接口的实现类实现 * */ public interface DeptService { /** * 新增部门 * * @param dept 页面传递的要新增的部门信息 * @return 返回带id的部门对象 */ public Dept insert(Dept dept); /** * 删除部门 * * @param deptNo 要删除的部门的编号 * @return 返回状态码,1表示成功 */ public Integer delete(Integer deptNo); /** * 修改部门 * * @param dept 页面传递的要修改的部门信息 * @return 返回修改后的部门对象 */ public Integer update(Dept dept); /** * 动态条件分页查 * * @param deptDto 查询条件,包含分页 * @return 查询到的Page对象 */ public Page<Dept> selectByDynamicSQLPage(Dept dept, PageUtil pageUtil); /** * 查所有 * 员工的条件查、新增和修改员工、不能重复添加,都需要查所有 * @return 查询到的部门结果集 */ public List<Dept> selectAll(); }
package com.xfyuao.service; import com.xfyuao.domain.Emp; import com.xfyuao.domain.Emp; import com.xfyuao.dto.EmpDto; import com.xfyuao.dto.EmpDto; import java.util.List; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; public interface EmpService { /** * 新增员工 * * @param emp 页面传递的要新增的员工信息 * @return 返回带id的员工对象 */ public Emp insert(Emp emp); /** * 删除员工 * * @param empNo 要删除的员工的id * @return 返回状态码 */ public Integer delete(Integer empNo); /** * 修改员工 * * @param emp 页面传递的要修改的员工信息 * @return 返回修改后的员工对象 */ public Emp update(Emp emp); /** * 动态条件分页查 * * @param empDto 查询条件,包含分页 * @return 查询到的Page对象 */ public Page<Emp> selectByDynamicSQLPage(EmpDto empDto); /** * 根据外键查询 * * @param deptNo 要查询的部门 * @return 该部门下的员工 */ public List<Emp> selectByDeptNo(Integer deptNo); }
8.impl
package com.xfyuao.service.impl; import java.util.List; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Expression; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Service; import com.xfyuao.dao.DeptDao; import com.xfyuao.domain.Dept; import com.xfyuao.service.DeptService; import com.xfyuao.util.PageUtil; @Service // spring的ioc的体现,当前类交给spring管理(创建对象)并标注为service层 public class DeptServiceImpl implements DeptService { @Autowired private DeptDao deptDao; @Override public Dept insert(Dept dept) { return deptDao.save(dept); } @Override public Integer delete(Integer deptNo) { try { deptDao.deleteById(deptNo); return 1;// 不报错就返回1,模仿数据库成功则受影响的行是1 } catch (Exception e) { e.printStackTrace(); System.out.println("删除失败!"); } return 0; } @Override public Integer update(Dept dept) { return deptDao.updateDept(dept.getDname(), dept.getLoc(), dept.getDeptNo()); } @Override public Page<Dept> selectByDynamicSQLPage(Dept dept, PageUtil pageUtil) { // 根据主键倒叙 Sort sort = Sort.by(Sort.Direction.DESC, "deptNo"); // 传入分页条件:页码和条数 Pageable pageable = PageRequest.of(pageUtil.getPage() - 1, pageUtil.getLimit(), sort); // 动态SQL语句 Specification<Dept> spec = this.myWhere(dept); return deptDao.findAll(spec, pageable); } @Override public List<Dept> selectAll() { return deptDao.findAll(); } private Specification<Dept> myWhere(Dept dept) { Specification<Dept> spec = new Specification<Dept>() { @Override public Predicate toPredicate(Root<Dept> root, CriteriaQuery<?> query, CriteriaBuilder cb) { Predicate predicate = cb.conjunction();// 动态 SQL 表达式 List<Expression<Boolean>> exList = predicate.getExpressions(); // 如果传来的条件中包含dname,就对dname模糊查 if (dept.getDname() != null && !"".equals(dept.getDname())) { exList.add(cb.like(root.<String>get("deptName"), "%" + dept.getDname() + "%")); } return predicate; } }; return spec; } }
package com.xfyuao.service.impl; import java.util.Date; import java.util.List; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Expression; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Service; import com.xfyuao.dao.EmpDao; import com.xfyuao.domain.Dept; import com.xfyuao.domain.Emp; import com.xfyuao.dto.EmpDto; import com.xfyuao.service.EmpService; @Service public class EmpServiceImpl implements EmpService { @Autowired private EmpDao empDao; @Override public Emp insert(Emp emp) { return empDao.save(emp); } @Override public Integer delete(Integer empNo) { try { empDao.deleteById(empNo); return 1; } catch (Exception e) { e.printStackTrace(); System.out.println("删除失败!"); } return 0; } @Override public Emp update(Emp emp) { return empDao.save(emp); } @Override public Page<Emp> selectByDynamicSQLPage(EmpDto empDto) { Sort sort = Sort.by(Sort.Direction.ASC, "empNo"); Pageable pageable = PageRequest.of(empDto.getPage() - 1, empDto.getLimit(), sort); Specification<Emp> spec = this.myWhere(empDto); return empDao.findAll(spec, pageable); } private Specification<Emp> myWhere(EmpDto empDto) { Specification<Emp> spec = new Specification<Emp>() { @Override public Predicate toPredicate(Root<Emp> root, CriteriaQuery<?> query, CriteriaBuilder cb) { Predicate predicate = cb.conjunction();// 动态 SQL 表达式 List<Expression<Boolean>> exList = predicate.getExpressions(); if (empDto.getEname() != null && !"".equals(empDto.getEname())) { exList.add(cb.like(root.<String>get("ename"), "%" + empDto.getEname() + "%")); } if (empDto.getEmpCardNo() != null && !"".equals(empDto.getEmpCardNo())) { exList.add(cb.like(root.<String>get("empCardNo"), "%" + empDto.getEmpCardNo() + "%")); } //大于开始日期 if (empDto.getHiredate() != null) { exList.add(cb.greaterThanOrEqualTo(root.<Date>get("hiredate"), empDto.getHiredate())); } //小于结束日期 if (empDto.getHiredate2() != null) { exList.add(cb.lessThanOrEqualTo(root.<Date>get("hiredate"), empDto.getHiredate2())); } // 根据外键列查询 if (empDto.getDept() != null && empDto.getDept().getDeptNo() != null) { // 等值使用equal(x,y) exList.add(cb.equal(root.<Integer>get("dept"), empDto.getDept().getDeptNo())); } return predicate; } }; return spec; } @Override public List<Emp> selectByDeptNo(Integer deptNo) { return empDao.findByDept(new Dept(deptNo, null, null)); } }
9.controller
package com.xfyuao.web; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.xfyuao.domain.Dept; import com.xfyuao.domain.Emp; import com.xfyuao.service.DeptService; import com.xfyuao.service.EmpService; import com.xfyuao.util.PageUtil; import com.xfyuao.util.Result; /** * 控制层 */ @RestController // 每个方法都返回json数据,不走视图解析器 public class DeptController { @Autowired // spring的DI,依赖注入,这个是自动注入,自动去spring容器找同名或同类型的对象给该属性赋值 private DeptService deptService; @Autowired private EmpService empService; /** * http://localhost:8080/insertDept 新增,id自增 * * @param dep * @return 0代表成功 */ @RequestMapping("/insertDept") public Object insertDept(Dept dept) { // 简单的业务逻辑可以放在controller层实现 /* 新增前先判断是否已存在 * 1.查询所有记录,然后判断名称是否存在, * 2.数据行和列较少,考虑没必要单独查名称 * 3.员工模块的条件查也会用到全查所有部门 * */ List<Dept> list = deptService.selectAll(); for (Dept d : list) { if (d.getDname().equals(dept.getDname())) { return new Result(1, "添加失败,该名称已存在!"); } } Dept de = deptService.insert(dept); if (de != null) { return new Result(0, "添加成功!"); } return new Result(2, "添加失败!"); } /** * http://localhost:8080/deleteDept 根据id删除 * * @param depId * @return 0代表成功 */ @RequestMapping("/deleteDept") public Object deleteDept(Integer deptNo) { // 删除前先判断该部门下是否有数据(员工) List<Emp> list = empService.selectByDeptNo(deptNo); if (!list.isEmpty()) { return new Result(1, "该部门下有数据,删除失败!"); } Integer i = deptService.delete(deptNo); if (i == 1) { return new Result(0, "删除成功!"); } return new Result(1, "删除失败!"); } /** * http://localhost:8080/updateDept 修改 * * @param dept * @return 0代表成功 */ @RequestMapping("/updateDept") public Object updateDept(Dept dept) { List<Dept> list = deptService.selectAll(); for (Dept d : list) { // if (d.getDname().equals(dept.getDname())) { // 如果只判断名字,没修改直接提交时会报错,因为原名字是存在的 // 所以还要判断id,如果传入的名字、id和某一条数据的完全一样,表示是同一条 if (d.getDname().equals(dept.getDname()) && !d.getDeptNo().equals(dept.getDeptNo())) { return new Result(1, "修改失败,该名称已存在!"); } } Integer i = deptService.update(dept); if (i == 1) { return new Result(0, "修改成功!"); } return new Result(1, "修改失败!"); } /** * http://localhost:8080/selectPageDept 动态条件分页查 * * @param dept 查询条件 pageUtil 分页数据 * @return layui数据表格要的数据格式 */ @RequestMapping("/selectPageDept") public Object selectPageDept(Dept dept, PageUtil pageUtil) { Page<Dept> page = deptService.selectByDynamicSQLPage(dept, pageUtil); /*layui要的正确数据: 该页数据 总条数 * 成功时:{"code":0, "msg":"", data:[{},{}...], count:100} * code不为0则为失败,需要在msg中放入失败原因 */ return new Result(0, "", page.getContent(), page.getTotalElements()); } /** * http://localhost:8080/selectAllDept 查全部 * * @return 全部部门 */ @RequestMapping("/selectAllDept") public Object selectAllDept() { return deptService.selectAll(); } }
package com.xfyuao.web; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.xfyuao.domain.Emp; import com.xfyuao.dto.EmpDto; import com.xfyuao.service.EmpService; import com.xfyuao.util.CardUtil; import com.xfyuao.util.Result; @RestController public class EmpController { @Autowired private EmpService empService; /** * http://localhost:8080/insertEmp 新增,id自增 * * @param emp * @return 0代表成功 */ @RequestMapping("/insertEmp") public Object insertEmp(Emp emp) { System.out.println("接收到的要新增的emp:"+emp); //调用工具类获取一个员工卡号 emp.setEmpCardNo(CardUtil.getEmpCard()); Emp e = empService.insert(emp); if (e != null) { return new Result(0, "添加成功!"); } return new Result(2, "添加失败!"); } /** * http://localhost:8080/deleteEmp 根据id删除 * * @param empNo * @return 0代表成功 */ @RequestMapping("/deleteEmp") public Object deleteEmp(Integer empNo) { Integer i = empService.delete(empNo); if (i == 1) { return new Result(0, "删除成功!"); } return new Result(1, "删除失败!"); } /** * http://localhost:8080/updateEmp 修改 * * @param emp * @return 0代表成功 */ @RequestMapping("/updateEmp") public Object updateEmp(Emp emp) { Emp e = empService.update(emp); if (e != null) { return new Result(0, "修改成功!"); } return new Result(1, "修改失败!"); } /** * http://localhost:8080/selectPageEmp 动态条件分页查 * * @param empDto 查询条件 * @return layui数据表格要的数据格式 */ @RequestMapping("/selectPageEmp") public Object selectPageEmp(EmpDto empDto) { System.out.println("emp查询条件:"+empDto); Page<Emp> page = empService.selectByDynamicSQLPage(empDto); return new Result(0, "查询成功", page.getContent(), page.getTotalElements()); } }
10-1.工具类1:CardUtil类
package com.xfyuao.util; import java.util.UUID; /** * 生成学生和老师的uuid卡号 * */ public class CardUtil { public static String getUUID(){ String uuid= UUID.randomUUID().toString().replace("-",""); return uuid; } public static String getStudentCard(){ return "s"+getUUID(); } public static String getTeacherCard(){ return "t"+getUUID(); } public static String getEmpCard(){ return "e"+getUUID(); } }
10-2.工具类2:PageUtil类
package com.xfyuao.util; import lombok.Data; /*** * 封装分页类 * @author Administrator * * @param <T> */ @Data public class PageUtil { private int page=1;//当前页数 private int limit=10;//每页显示多少条 private int offset;//偏移量 从哪个下标开始,sql语句limit后的第一个数字 /* * 其实不需要这样设置 * 1.前端layui自己管理分页 * 2.持久层jpa自己处理偏移量 * 3.以上两者都只需要页码和条数就行了 * */ public void setPage(int page) { this.page = page; this.offset=(this.page-1)*this.limit; } }
10-3.工具类3:Result类
package com.xfyuao.util; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; /** * 封装结果对象,经过springmvc转换成json对象返回给页面 * */ @Data @AllArgsConstructor @NoArgsConstructor public class Result { private Integer code; // 0成功 private String msg; // 响应失败状态码 private Object data; private Long count; public Result(Integer code, String msg) { super(); this.code = code; this.msg = msg; } }
11.页面,首页就提供了,目录结构中的css和images目录都是为首页提供的,也不再提供。其实主要是因为我不知道怎么添加附件啊,放网盘就算了,后台页面随便找一个都能用的,自去。。。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>院系</title> <link rel="stylesheet" type="text/css" href="js/layui-v2.5.4/css/layui.css" /> <script src="js/layui-v2.5.4/layui.js" type="text/javascript" charset="utf-8"></script> </head> <body> <!-- 条件区 --> <div class="layui-form-item" style="margin-top: 10px; margin-left: 10px"> <form class="layui-form" method="post" onsubmit="return false;"> <label class="layui-form-mid">部门名称</label> <div class="layui-input-inline" style="width: 200px;"> <input id="dname" class="layui-input" placeholder="请输入部门名称"> </div> <div class="layui-input-inline" style="width: 100px;"> <button class="layui-btn" id="mySearch" data-type="mySearchTableReload">搜索</button> </div> </form> </div> <!-- 顶部工具栏 --> <script type="text/html" id="topToolbar"> <a href="dept.html" class="layui-btn layui-btn-sm"> <i class="layui-icon">ဂ</i>刷新 </a> <a class="layui-btn layui-btn layui-btn-sm" lay-event="insertBtnEve"> <i class="layui-icon"></i> 添加 </a> </script> <!--行内工具栏--> <script type="text/html" id="barDemo"> <a class="layui-btn layui-btn-xs" lay-event="updateBtnEve">修改</a> <a class="layui-btn layui-btn-xs" lay-event="detailBtnEve">详情</a> <a class="layui-btn layui-btn-xs" lay-event="deleteBtnEve">删除</a> </script> <!-- 表格 --> <table class="layui-hide" id="myTable" lay-filter="myTableFil"></table> <!-- 增、改、单查共用页面,都不要id,否则和条件区重复了,直接调用serialize即可获取表单数据 --> <div id="myHtml" style="display: none; margin-top: 20px;"> <form class="layui-form" id="myForm" lay-filter="myFormFil" onsubmit="return false;"> <!-- 隐藏id --> <input type="hidden" id="deptNo" name="deptNo" value="0"> <div class="layui-form-item"> <label class="layui-form-label">部门名称:</label> <div class="layui-input-inline" style="width: 350px;"> <input type="text" name="dname" class="layui-input"> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">办公地点:</label> <div class="layui-input-inline" style="width: 350px;"> <input type="text" name="loc" class="layui-input"> </div> </div> <div class="layui-btn-container" style="text-align: center;" id="mySubmitDiv"> <button class="layui-btn" lay-filter="mySubmitFil" lay-submit="">提交</button> </div> </form> </div> <script> /* 所有js代码都写这一行里面 */ layui.use([ ‘table‘, ‘form‘ ], function() { var table = layui.table; var form = layui.form; var $ = layui.$; //渲染表格数据 table.render({ elem : ‘#myTable‘, url : ‘selectPageDept‘, //数据接口 toolbar : ‘#topToolbar‘, method : ‘post‘, title : ‘部门列表‘, page : true, //开启分页 cols : [ [ { field : ‘deptNo‘, title : ‘部门编号‘, align : ‘center‘, sort : true //开启排序,layui自己排 }, { field : ‘dname‘, title : ‘部门名称‘, align : ‘center‘ }, { field : ‘loc‘, title : ‘办公地点‘, align : ‘center‘ }, { fixed : ‘‘, title : ‘操作‘, align : ‘center‘, toolbar : ‘#barDemo‘ } ] ], id : "myTableReloadId" }); /* 以layui格式创建函数,暂时只有一个函数:mySearchTableReload */ active = { //定义搜索按钮函数 mySearchTableReload : function() { table.reload(‘myTableReloadId‘, { where : { //点搜索时以id形式获取表单数据,而不是提交表单 ‘dname‘ : $(‘#dname‘).val() } }); } }; //监听搜索按钮,执行mySearchTableReload方法 $(‘#mySearch‘).on(‘click‘, function() { var type = $(this).data(‘type‘); active[type] ? active[type].call(this) : ‘‘; }); //监听顶部工具栏事件,添加/修改按钮,点击弹出页面 table.on(‘toolbar(myTableFil)‘, function(obj) { switch (obj.event) { case ‘insertBtnEve‘: { $(‘#mySubmitDiv‘).css("display", "block"); //如果先点击了修改按钮,表单里有值了,这里重置一下 $(‘#myForm‘)[0].reset(); //重置不了id,这里手动重置一下 $(‘#deptNo‘).val(0); layer.open({ type : 1, title : ‘添加部门‘, content : $("#myHtml"), area : [ ‘500px‘, ‘400px‘ ] }); } break; } }); //监听行内工具条 table.on(‘tool(myTableFil)‘, function(obj) { //获取该行数据 var data = obj.data; if (obj.event === ‘updateBtnEve‘) { $(‘#mySubmitDiv‘).css("display", "block"); form.val("myFormFil", data); edit_index = layer.open({ type : 1, title : ‘您正在修改‘ + data.dname + ‘的信息‘, content : $("#myHtml"), scrollbar : true, /* 滚动条 */ resize : true, /* 是否允许拉伸 */ area : [ ‘600px‘, ‘300px‘ ] }); } else if (obj.event === ‘detailBtnEve‘) { //隐藏提交按钮 $(‘#mySubmitDiv‘).css("display", "none"); form.val("myFormFil", data); edit_index = layer.open({ type : 1, title : ‘您正在查看‘ + data.dname + ‘的信息‘, content : $("#myHtml"), scrollbar : true, /* 滚动条 */ resize : true, /* 是否允许拉伸 */ area : [ ‘600px‘, ‘200px‘ ] }); } else if (obj.event === ‘deleteBtnEve‘) { form.val("myFormFil", data); console.log(data.deptNo); layer.confirm(‘确认删除id为[‘ + data.deptNo + ‘]的信息吗?‘, function(index) { $.post("deleteDept", { "deptNo" : data.deptNo }, function(res) { console.log(res); if (res.code == 0) { layer.msg(res.msg, { icon : 1, time : 1000 }, function() { layer.close(layer.index); window.location.reload(); }); } else { layer.msg(res.msg, { icon : 2, time : 1000 }); } }, "json"); return false; }); } }); //监听新增/修改页面的提交按钮 form.on(‘submit(mySubmitFil)‘, function(data) { $(‘#mySubmitDiv‘).css("display", "block"); var str = $("#myForm").serialize();//根据name属性获取表单数据 console.log(str); //判断是添加还是修改 var myUrl; if ($(‘#dname‘).val() != null) {//简单的做个输入判断,未输入提交无效 if ($(‘#deptNo‘).val() == "0") {//为0说明没赋值,说明是添加 myUrl = "insertDept"; } else { myUrl = "updateDept"; } } $.post(myUrl, str, function(res) { if (res.code == 0) { //根据后台提示信息弹出msg layer.msg(res.msg, { icon : 1, time : 1000 }, function() { layer.close(layer.index); window.location.reload(); }); } else { layer.msg(res.msg, { icon : 5, time : 1000 }); } }, "json"); }); }); </script> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> <link rel="stylesheet" type="text/css" href="js/layui-v2.5.4/css/layui.css" /> <script src="js/layui-v2.5.4/layui.js" type="text/javascript" charset="utf-8"></script> </head> <body> <!-- 条件区 --> <div class="layui-form-item" style="margin-top: 10px; margin-left: 10px"> <form class="layui-form" method="post" onsubmit="return false;"> <label class="layui-form-mid">姓名:</label> <div class="layui-input-inline" style="width: 100px;"> <input type="text" id="ename" autocomplete="off" class="layui-input" placeholder="请输入姓名"> </div> <label class="layui-form-mid">部门</label> <div class="layui-input-inline" style="width: 100px;"> <select id="dnameSeach"> <option value="">--请选择--</option> </select> </div> <label class="layui-form-mid">卡号:</label> <div class="layui-input-inline" style="width: 300px;"> <input type="text" id="empCardNoSeach" autocomplete="off" class="layui-input" placeholder="请输入卡号,一部分即可"> </div> <label class="layui-form-mid">入职日期:</label> <div class="layui-input-inline" style="width: 200px;"> <input id="hiredate" type="text" autocomplete="off" class="layui-input" placeholder="请选择开始日期"> </div> <div class="layui-input-inline" style="width: 200px;"> <input id="hiredate2" type="text" autocomplete="off" class="layui-input" placeholder="请选择结束日期"> </div> </form> <button class="layui-btn" id="mySearch" data-type="mySearchTableReload">搜索</button> <button class="layui-btn" onclick="renovates()">刷新</button> </div> <script type="text/javascript"> function renovates() { window.location.reload(true); } </script> <!-- 顶部工具栏 --> <script type="text/html" id="topToolbar"> <a class="layui-btn layui-btn layui-btn-sm" lay-event="insertBtnEve"> <i class="layui-icon"></i> 添加 </a> </script> <!--行内工具栏--> <script type="text/html" id="barDemo"> <a class="layui-btn layui-btn-xs" lay-event="updateBtnEve">修改</a> <a class="layui-btn layui-btn-xs" lay-event="detailBtnEve">详情</a> <a class="layui-btn layui-btn-xs" lay-event="deleteBtnEve">删除</a> </script> <!-- 表格 --> <table class="layui-hide" id="myTable" lay-filter="myTableFil"></table> <!-- 增、改、单查共用页面,都不要id,否则和条件区重复了,直接调用serialize即可获取表单数据 --> <div id="myHtml" style="display: none; margin-top: 20px;"> <form class="layui-form" id="myForm" lay-filter="myFormFil" onsubmit="return false;"> <!-- 隐藏id --> <input type="hidden" id="empNo" name="empNo" value="0"> <!-- 隐藏卡号栏,修改回显时显示 --> <div id="empCardNoSave" class="layui-form-item" style="display: none"> <label class="layui-form-label">卡号:</label> <div class="layui-input-inline" style="width: 350px;"> <input type="text" name="empCardNo" class="layui-input layui-disabled"> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">姓名:</label> <div class="layui-input-inline" style="width: 350px;"> <input type="text" name="ename" class="layui-input"> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">入职日期:</label> <div class="layui-input-inline" style="width: 350px;"> <input id="hiredateSave" type="text" name="hiredate" class="layui-input"> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">状态:</label> <div class="layui-input-inline" style="width: 350px;"> <input type="radio" name="state" value="0" title="在职" checked> <input type="radio" name="state" value="1" title="离职"> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">部门:</label> <div class="layui-input-inline" style="width: 150px;"> <select id="dnameSave" name="dept.deptNo"> <option value="">请选择</option> </select> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">备注:</label> <div class="layui-input-inline" style="width: 350px;"> <input type="text" name="remake" class="layui-input"> </div> </div> <div class="layui-btn-container" style="text-align: center;" id="mySubmitDiv"> <button class="layui-btn" lay-filter="mySubmitFil" lay-submit="">提交</button> </div> </form> </div> <script> /* 所有js代码都写这一行里面 */ layui.use([ ‘table‘, ‘form‘, ‘laydate‘ ], function() { var table = layui.table; var form = layui.form; var laydate = layui.laydate; var $ = layui.$; //绑定日期插件 laydate.render({ elem : ‘#hiredate‘, //开始日期 type : ‘datetime‘ }); laydate.render({ elem : ‘#hiredate2‘, //结束日期 type : ‘datetime‘ }); laydate.render({ elem : ‘#hiredateSave‘, //save日期 type : ‘datetime‘ }); //渲染表格数据 table.render({ elem : ‘#myTable‘, url : ‘selectPageEmp‘, //数据接口 toolbar : ‘#topToolbar‘, method : ‘post‘, title : ‘教师表‘, page : true, //开启分页 cols : [ [ { field : ‘empNo‘, title : ‘编号‘, width : ‘10%‘, align : ‘center‘, sort : true //开启排序,layui自己排 }, { field : ‘ename‘, title : ‘姓名‘, width : ‘10%‘, align : ‘center‘ }, { field : ‘empCardNo‘, title : ‘卡号‘, width : ‘30%‘, align : ‘center‘ }, { field : ‘dname‘, title : ‘部门名称‘, width : ‘10%‘, align : ‘center‘, templet : function(d) { return d.dept.dname } }, { field : ‘state‘, title : ‘状态‘, width : ‘10%‘, align : ‘center‘, templet : function(d) { if (d.state == 0) { return "在职"; } else if (d.state == 1) { return "离职"; } else { return "异常"; } } }, { field : ‘remake‘, title : ‘备注‘, width : ‘10%‘, align : ‘center‘ }, { fixed : ‘‘, title : ‘操作‘, width : ‘15%‘, align : ‘center‘, toolbar : ‘#barDemo‘ } ] ], id : "myTableReloadId" }); /* 以layui格式创建函数,暂时只有一个函数:mySearchTableReload */ active = { mySearchTableReload : function() { table.reload(‘myTableReloadId‘, { where : { ‘ename‘ : $(‘#ename‘).val(), ‘empCardNo‘ : $(‘#empCardNoSeach‘).val(), ‘hiredate‘ : $(‘#hiredate‘).val(), ‘hiredate2‘ : $(‘#hiredate2‘).val(), ‘dept.deptNo‘ : $(‘#dnameSeach‘).val() } }); } }; //监听搜索按钮,执行mySearchTableReload方法 $(‘#mySearch‘).on(‘click‘, function() { var type = $(this).data(‘type‘); active[type] ? active[type].call(this) : ‘‘; }); $.post("selectAllDept", function(res) { var shtml = "<option></option>"; $.each(res, function(index, value) { shtml += ‘<option value="‘ + value.deptNo + ‘" > ‘ + value.dname + ‘</option>‘; }); $(‘#dnameSeach‘).html(shtml); $(‘#dnameSave‘).html(shtml); form.render(‘select‘); //刷新select选择框渲染 }, "json"); //监听顶部工具栏事件,添加/修改按钮,点击弹出页面 table.on(‘toolbar(myTableFil)‘, function(obj) { switch (obj.event) { case ‘insertBtnEve‘: { $(‘#mySubmitDiv‘).css("display", "block"); //如果先点击了修改按钮,表单里有值了,这里重置一下 $(‘#myForm‘)[0].reset(); $(‘#myformselect‘).val(""); //重置不了id,这里手动重置一下 $(‘#empNo‘).val(0); layer.open({ type : 1, title : ‘添加页面‘, content : $("#myHtml"), area : [ ‘500px‘, ‘500px‘ ] }); } break; } }); table.on(‘tool(myTableFil)‘, function(obj) { var data = obj.data; if (obj.event === ‘updateBtnEve‘) { //异步请求到所有部门,res就是返回的全部部门集合 $.post("selectAllDept", function(res) { var shtml = "<option></option>"; $.each(res, function(index, value) { //如果选中的这行的部门 和 所有的部门中的某个部门一致 if (data.dept.deptNo == value.deptNo) { shtml += ‘<option value="‘ + value.deptNo + ‘" selected > ‘ + value.dname + ‘</option>‘; } else { shtml += ‘<option value="‘ + value.deptNo + ‘" > ‘ + value.dname + ‘</option>‘; } }); $(‘#dnameSave‘).html(shtml); form.render(‘select‘); //刷新select选择框渲染 }, "json"); $(‘#empCardNoSave‘).css("display", "block"); $(‘#mySubmitDiv‘).css("display", "block"); form.val("myFormFil", data); edit_index = layer.open({ type : 1, title : ‘您正在修改‘ + data.ename + ‘的信息‘, content : $("#myHtml"), scrollbar : true, /* 滚动条 */ resize : true, /* 是否允许拉伸 */ area : [ ‘600px‘, ‘500px‘ ] }); } else if (obj.event === ‘detailBtnEve‘) { //隐藏提交按钮 $(‘#mySubmitDiv‘).css("display", "none"); form.val("myFormFil", data); edit_index = layer.open({ type : 1, title : ‘您正在查看‘ + data.ename + ‘的信息‘, content : $("#myHtml"), scrollbar : true, /* 滚动条 */ resize : true, /* 是否允许拉伸 */ area : [ ‘600px‘, ‘400px‘ ] }); } else if (obj.event === ‘deleteBtnEve‘) { layer.confirm(‘确认删除id为[‘ + data.empNo + ‘]的信息吗?‘, function(index) { $.post("deleteEmp", { "empNo" : data.empNo, }, function(res) { if (res.code == 0) { layer.msg(res.msg, { icon : 1, time : 1000 }, function() { layer.close(layer.index); window.location.reload(); }); } else { layer.msg(res.msg, { icon : 2, time : 1000 }); } }, "json"); }); } }); //监听新增/修改页面的提交按钮 form.on(‘submit(mySubmitFil)‘, function(data) { $(‘#mySubmitDiv‘).css("display", "block"); console.log(data.field); //判断是添加还是修改 var myUrl; if ($(‘#ename‘).val() != null) { if ($(‘#empNo‘).val() == "0") {//为0说明没赋值,说明是添加 myUrl = "insertEmp"; } else { myUrl = "updateEmp"; } } $.post(myUrl, data.field, function(res) { if (res.code == 0) { //根据后台提示信息弹出msg layer.msg(res.msg, { icon : 1, time : 1000 }, function() { layer.close(layer.index); window.location.reload(); }); } else { layer.msg(res.msg, { icon : 5, time : 1000 }); } }, "json"); }); }); </script> </body> </html>
spring-boot-jap-layui-mysql 完整的jpa多对一
标签:tput lin 员工信息 map framework 使用 ase 额外 column
原文地址:https://www.cnblogs.com/xfyuao/p/12889821.html