zoukankan      html  css  js  c++  java
  • spring-boot-jap-layui-mysql 完整的jpa多对一

      前言:网上很少见到完整版的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 dept
         * @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 depNo
         * @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 查询条件 
         * @param 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=" 200px;">
                    <input id="dname" class="layui-input" placeholder="请输入部门名称">
                </div>
                <div class="layui-input-inline" style=" 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">&#x1002;</i>刷新
                    </a>
                    <a class="layui-btn layui-btn layui-btn-sm" lay-event="insertBtnEve">
                     <i class="layui-icon">&#xe608;</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=" 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=" 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>员工</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=" 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=" 100px;">
                    <select id="dnameSeach">
                        <option value="">--请选择--</option>
                    </select>
                </div>
                <label class="layui-form-mid">卡号:</label>
                <div class="layui-input-inline" style=" 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=" 200px;">
                    <input id="hiredate" type="text" autocomplete="off"
                        class="layui-input" placeholder="请选择开始日期">
                </div>
                <div class="layui-input-inline" style=" 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">&#xe608;</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=" 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=" 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=" 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=" 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=" 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=" 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>
  • 相关阅读:
    JQuery 日历控件
    恢复xp_cmdshell SQL Server阻止了对组件 'xp_cmdshell' 的过程'sys.xp_cmdshell' 启用
    XML基础总结
    09.09.16总结
    草根
    设计模式学习总结
    检索 COM 类工厂中 CLSID 为{0002450000000000C000000000000046} 的组件时失败,原因是出现以下错误: 80070005。
    09.09.22总结
    Singleton 单态模式
    【Tomcat源码学习】5.请求处理
  • 原文地址:https://www.cnblogs.com/xfyuao/p/12889821.html
Copyright © 2011-2022 走看看