JPA+Vue+axios实现员工管理系统(CRUD)

JPA

    定义:java持久化API规范(抽象的定义)
    实现:hibernate,toplink等。


JPA与JDBC的关系

    相同点:官方数据持久化的技术规范。
    不同点:
        出现时间:JDBC是最早数据持久化方案,慢慢出现EJB,JPA是最新的。
        架构:JPA在JDBC之上。
        JPA比JDBC更加简单高效。


Java与关系型数据库的持久化方案

.   1.JDBC (官方)
    2.EJB (官方)
    3.MyBatis(社区)
    4.Hibernate(社区)
    5.JDO(社区)
    6.JPA (官方)
    7....(社区)
   

  JDBC太繁琐,低效。EJB过分复杂。因此开发人员自发的创建了MyBatis,Hibernate之类的持久化技术,
    大量开发人员不使用官方技术规范,官方从社区吸取经验,定义新的规范JPA,底层实现还是Hibernate
    或toplink之类的第三方框架。


 MyBatis与JPA(Hibernate)

   mybatis是SQL映射。半自动化,写SQL语句
    hibernate是对象关系映射。自动化,不写SQL,调用方法,方法不够时,写HQL。
    初步上手Hibernate简单,如果业务复杂,需要性能优化,学习曲线上升高。不可控。
    mybatis总体上更加简单,关注点依旧在SQiL。
    国外JPA多,国内MyBatis多。


JPA是官方的ORM(对象关系映射)的API规范

 对象与表的映射 


  
        对象所在类名与表之间的映射。
        对象中的字段与表中的列之间的映射
    
    

对象之间的关系到表与表之间的关系的映射 


        一对一
        一对多
        继承


接下来让我们通过代码来认识JPA

 首先选择需要的依赖


工程目录 

 


Dept.java

package com.newer.jpa2.pojo;
/**
 * 部门
 */

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "dept")
public class Dept {

	/**
	 * 主键字段,数据库中生成的值,策略IDENTITY(MySQL自动增长)
	 */
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;
	
	@Column(name = "title")
	private String title;
	
	@Column(name = "loc")
	private String loc;
	
	
	public Dept() {
		
	}


	public Long getId() {
		return id;
	}


	public void setId(Long id) {
		this.id = id;
	}


	public String getTitle() {
		return title;
	}


	public void setTitle(String title) {
		this.title = title;
	}


	public String getLoc() {
		return loc;
	}


	public void setLoc(String loc) {
		this.loc = loc;
	}


	@Override
	public String toString() {
		return "Dept [id=" + id + ", title=" + title + ", loc=" + loc + "]";
	}
	
	
}

Job.java

package com.newer.jpa2.pojo;
/**
 * 职位
 */
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "job")
public class Job {

	/**
	 * 主键字段,数据库中生成的值,策略IDENTITY(MySQL自动增长)
	 */
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;
	
	@Column(name = "title")
	private String title;
	
	@Column(name = "info")
	private String info;
	
	public Job() {
		
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getInfo() {
		return info;
	}

	public void setInfo(String info) {
		this.info = info;
	}

	@Override
	public String toString() {
		return "Job [id=" + id + ", title=" + title + ", info=" + info + "]";
	}
	
	
}

Staff.java

package com.newer.jpa2.pojo;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;

/**
 * 实体(JPA)
 * @author Admin
 *
 */
@Entity
public class Staff {

	  @Id
	  @GeneratedValue(strategy = GenerationType.IDENTITY)
	  Long id;

	  String name;

	  String phone;

	  

	  @OneToOne
	  @JoinColumn(referencedColumnName = "id")
	  Dept dept;
	  
	  @OneToOne
	  @JoinColumn(referencedColumnName = "id")
	  Job job;
	
	public Staff() {
		
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	public Dept getDept() {
		return dept;
	}

	public void setDept(Dept dept) {
		this.dept = dept;
	}

	public Job getJob() {
		return job;
	}

	public void setJob(Job job) {
		this.job = job;
	}

	@Override
	public String toString() {
		return "Staff [id=" + id + ", name=" + name + ", phone=" + phone + ", dept=" + dept + ", job=" + job + "]";
	}

	
	

	
	
}

application.properties

spring.datasource.url=jdbc:mysql://127.0.0.1:3306/jpa?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123456

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

spring.http.log-request-details=true

logging.level.web=debug

#JPA
#根据实体(POJO)的注解自动生成 SQL DDL 创建表结构
spring.jpa.generate-ddl=true
#显示底层执行的 SQL 语句
spring.jpa.show-sql=true


通过上面的代码,我们不需要手动去创建数据库的表,程序会帮我们自动创建表。这也是JPA的优点之一,自动化

DeptRepository.java

package com.newer.jpa2.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.newer.jpa2.pojo.Dept;

@Repository
public interface DeptRepository extends JpaRepository<Dept, Long> {

//	基本操作已实现了
}

JobRepository.java

package com.newer.jpa2.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.newer.jpa2.pojo.Job;

@Repository
public interface JobRepository extends JpaRepository<Job, Long>{

	
}

StaffRepository.java

package com.newer.jpa2.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.newer.jpa2.pojo.Staff;

@Repository
public interface StaffRepository extends JpaRepository<Staff, Long> {

}

上面的是数据访问所需的接口。

DeptController.java

package com.newer.jpa2.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.newer.jpa2.pojo.Dept;
import com.newer.jpa2.repository.DeptRepository;

@RestController
@RequestMapping("/api/dept")
public class DeptController {

	@Autowired
	DeptRepository deptRepository;
	
	@GetMapping
	public List<Dept> findAll(){
		return deptRepository.findAll();
	}
	
	@PostMapping
	public Dept save(@RequestBody Dept dept) {
		return deptRepository.save(dept);
	}
	
	@GetMapping("/{id}")
	public Dept load(@PathVariable Long id) {
		return deptRepository.findById(id).get();
	}
	
	@DeleteMapping("{id}")
	public void remove(@PathVariable Long id) {
		deptRepository.deleteById(id);
	}
	
	@PutMapping("{id}")
	public Dept updata(@PathVariable Long id,@RequestBody Dept dept) {
//		设置id
		dept.setId(id);
		return deptRepository.saveAndFlush(dept);
	}
	
}

JobController.java

package com.newer.jpa2.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.newer.jpa2.pojo.Job;
import com.newer.jpa2.repository.JobRepository;

@RestController
@RequestMapping("/api/job")
public class JobController {

	@Autowired
	JobRepository jobRepository;
	
	@GetMapping
	public List<Job> findAll(){
		return jobRepository.findAll();
	}
	
	@PostMapping
	public Job create(@RequestBody Job job) {
		return jobRepository.save(job);
	}
	
	@GetMapping("/{id}")
	public Job load(@PathVariable Long id) {
		return jobRepository.findById(id).get();
	}
	
	@DeleteMapping("/{id}")
	public void remove(@PathVariable Long id) {
		jobRepository.deleteById(id);
	}
	
	@PutMapping("/{id}")
	public Job update(@PathVariable Long id,@RequestBody Job job) {
		job.setId(id);
		return jobRepository.saveAndFlush(job);
	}
}

StaffController.java

package com.newer.jpa2.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.newer.jpa2.pojo.Staff;
import com.newer.jpa2.repository.StaffRepository;

@RestController
@RequestMapping("/api/staff")
public class StaffController {

	@Autowired
	
	StaffRepository staffRepository;
	
	@GetMapping
	public List<Staff> findAll(){
		return staffRepository.findAll();
	}
	
	@PostMapping
	public Staff create (@RequestBody Staff staff) {
		return staffRepository.save(staff);
	}
	
	@GetMapping("/{id}")
	public Staff load(@PathVariable Long id) {
		return staffRepository.findById(id).get();
	}
	
	@DeleteMapping("/{id}")
	public void remove(@PathVariable Long id) {
		staffRepository.deleteById(id);
	}
	
	@PutMapping("{id}")
	public Staff update(@PathVariable Long id,@RequestBody Staff staff) {
		staff.setId(id);
		return staffRepository.saveAndFlush(staff);
	}
}

由于实现的只是基本的CRUD,可以不用到业务逻辑(service)。如果以后开发项目,会经常用到service。然后再通过Controller去操作数据。

HomeController.java(通过前端去访问服务端的数据),vue路由的实现也可以通过HTML 超链接 + Spring MVC 完成的路由。这篇博客就是用HTML 超链接 + Spring MVC 完成的路由。关于vue路由,有兴趣的小伙伴可以去前面的博客看。

package com.newer.jpa2.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
/**
 * SPA 前后端分离(Vue Cli,Angular,JS,React),这个就不需要
 * 
 * SSR 没有前后端分离(模板引擎,ajax,Vue),此处在进行视图的路由
 * @author Admin
 *
 */
@Controller
public class HomeController {

	@GetMapping("/")
	public String home() {
		return "index.html";
	}
	
	@GetMapping("/dept")
	public String dept() {
		return "dept.html";
	}
	
	@GetMapping("/staff")
	public String staff() {
		return "staff.html";
	}
	
	@GetMapping("/job")
	public String job() {
		return "job.html";
	}
}

接下来是前端的代码

index.html

<!doctype html>
<html lang="en">
  <head>
    <title>JPA</title>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
  </head>
  <body>
      <nav class="navbar navbar-expand-lg navbar-light bg-light">
          <a class="navbar-brand" href="#">JPA</a>
          <button class="navbar-toggler d-lg-none" type="button" data-toggle="collapse" data-target="#collapsibleNavId" aria-controls="collapsibleNavId"
              aria-expanded="false" aria-label="Toggle navigation">
              <span class="navbar-toggler-icon"></span>
          </button>
          <div class="collapse navbar-collapse" id="collapsibleNavId">
              <ul class="navbar-nav mr-auto mt-2 mt-lg-0">
                  <li class="nav-item active">
                      <a class="nav-link" href="#">首页 <span class="sr-only">(current)</span></a>
                  </li>
                  <li class="nav-item">
                      <a class="nav-link" href="dept">部门</a>
                  </li>
                  <li class="nav-item">
                      <a class="nav-link" href="staff">员工</a>
                  </li>
                  <li class="nav-item">
                      <a class="nav-link" href="job">职位</a>
                  </li>
                  
              </ul>
              <form class="form-inline my-2 my-lg-0">
                  <input class="form-control mr-sm-2" type="text" placeholder="Search">
                  <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
              </form>
          </div>
      </nav>
    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
  </body>
</html>

dept.html

<!doctype html>
<html lang="en">

<head>
    <title>部门</title>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
        integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    <!-- axios -->
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <!-- vue -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
    <div class="jumbotron jumbotron-fluid py-3 mb-0">
        <div class="container">
            <h1 class="display-3">部门管理</h1>


        </div>

    </div>

    <nav class="breadcrumb mt-0">

        <a class="breadcrumb-item" href="/">首页</a>
        <span class="breadcrumb-item active">部门</span>
    </nav>

    <div id="app" class="container-fluid">
        <div class="row">
            <div class="col-lg-4">
                <!-- 表单 -->
                <div class="card">

                    <div class="card-body">
                        <div class="form-group">
                            <label for="">部门名称</label>
                            <input
                            v-model="title"
                            type="text" class="form-control" name="" id="" aria-describedby="helpId"
                                placeholder="部门名称">

                        </div>
                        <div class="form-group">
                            <label for="">办公地点</label>
                            <input 
                            v-model="loc"
                            type="text" class="form-control" name="" id="" aria-describedby="helpId"
                                placeholder="办公地点">

                        </div>

                        <button
                        @click="create"
                        type="button" class="btn btn-primary btn-lg btn-block">添加</button>
                    </div>
                </div>
            </div>

            <div class="col-lg-8">
                <!-- 表格 -->
                <table class="table">
                    <thead>
                        <tr>
                            <th><input type="checkbox"></th>
                            <th>编号</th>
                            <th>名称</th>
                            <th>工作地点</th>
                            <th></th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr v-for="(dept, index) in deptList" :key="index">
                            <td><input type="checkbox" ></td>
                            <td >{{dept.id}}</td>
                            <td>{{dept.title}}</td>
                            <td>{{dept.loc}}</td>
                            <td></td>
                           
                        </tr>
                      
                    </tbody>
                </table>
            </div>
        </div>
    </div>

    <script>
        new Vue({
            el:"#app",
            data:{
                title:'',
                loc:'',
                // 员工列表
                deptList:[]
            },
            methods: {
                // 创建部门的方法
                create:function(){
                    let url='/api/dept';
                    params={
                        title:this.title,
                        loc:this.loc
                    };
                    axios.post(url,params)
                    .then(res => {
                        // console.log(res)
                        this.deptList.push(res.data);
                    })
                    .catch(err => {
                        console.error(err); 
                    })
                } 
            },

            created() {
                // Get /api/dept

                axios.get('/api/dept')
                .then(res => {
                    console.log(res)
                    this.deptList=res.data;
                })
                .catch(err => {
                    console.error(err); 
                })
            },
        })
    </script>
    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
        integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
        crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
        integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"
        crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
        integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
        crossorigin="anonymous"></script>
</body>

</html>

job.html

<!doctype html>
<html lang="en">

<head>
    <title>职位</title>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
        integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    <!-- axios -->
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <!-- vue -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
    <div class="jumbotron jumbotron-fluid py-3 mb-0">
        <div class="container">
            <h1 class="display-3">职位管理</h1>


        </div>

    </div>

    <nav class="breadcrumb mt-0">

        <a class="breadcrumb-item" href="/">首页</a>
        <span class="breadcrumb-item active">职位</span>
    </nav>

    <div id="app" class="container-fluid">
        <div class="row">
            <div class="col-lg-4">
                <!-- 表单 -->
                <div class="card">

                    <div class="card-body">
                        <div class="form-group">
                            <label for="">职位名称</label>
                            <input
                            v-model="title"
                            type="text" class="form-control" name="" id="" aria-describedby="helpId"
                                placeholder="职位名称">

                        </div>
                        <div class="form-group">
                            <label for="">职位信息</label>
                            <input 
                            v-model="info"
                            type="text" class="form-control" name="" id="" aria-describedby="helpId"
                                placeholder="职位信息">

                        </div>

                        <button
                        @click="create"
                        type="button" class="btn btn-primary btn-lg btn-block">添加</button>
                    </div>
                </div>
            </div>

            <div class="col-lg-8">
                <!-- 表格 -->
                <table class="table">
                    <thead>
                        <tr>
                            <th><input type="checkbox"></th>
                            <th>编号</th>
                            <th>名称</th>
                            <th>职位信息</th>
                            <th></th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr v-for="(job, index) in jobList" :key="index">
                            <td><input type="checkbox" ></td>
                            <td >{{job.id}}</td>
                            <td>{{job.title}}</td>
                            <td>{{job.info}}</td>
                            <td></td>
                           
                        </tr>
                      
                    </tbody>
                </table>
            </div>
        </div>
    </div>

    <script>
        new Vue({
           el:'#app',
           data:{
               title:'',
               info:'',
            //    部门列表
               jobList:[]
           },
           methods: {
            //    创建职位的方法
               create:function(){
                   let url='/api/job';
                   let params={
                       title:this.title,
                       info:this.info
                   }
                   axios.post(url,params)
                   .then(res => {
                       console.log(res)
                       this.jobList.push(res.data);
                   })
                   .catch(err => {
                       console.error(err); 
                   })
               }
           }, 

           created() {
               axios.get('/api/job')
               .then(res => {
                   console.log(res)
                   this.jobList=res.data;
               })
               .catch(err => {
                   console.error(err); 
               })
           },
        })
    </script>
    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
        integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
        crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
        integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"
        crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
        integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
        crossorigin="anonymous"></script>
</body>

</html>

staff.html

<!doctype html>
<html lang="en">

<head>
    <title>员工</title>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
        integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    <!-- axios -->
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <!-- vue -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
    <div class="jumbotron jumbotron-fluid py-3">
        <div class="container">
            <h1 class="display-3">员工管理</h1>


        </div>

    </div>
    <nav class="breadcrumb mt-0">

        <a class="breadcrumb-item" href="/">首页</a>
        <span class="breadcrumb-item active">部门管理</span>
    </nav>

    <div id="app" class="container-fluid">
        <div class="row">
            <div class="col-lg-4">
                <!-- 表单 -->
                <div class="card">

                    <div class="card-body">
                        <div class="form-group">
                            <label for="">姓名</label>
                            <input v-model="name" type="text" class="form-control" name="" id=""
                                aria-describedby="helpId" placeholder="姓名">

                        </div>
                        <div class="form-group">
                            <label for="">联系方式</label>
                            <input v-model="phone" type="text" class="form-control" name="" id=""
                                aria-describedby="helpId" placeholder="联系方式">

                        </div>
                        <div class="form-group">
                            <label for="">职位</label>
                            <select v-model="jobId" class="form-control">
                                <option v-for="(job, index) in jobList" :key="index" :value="job.id">
                                    {{job.title}}
                                </option>

                            </select>
                        </div>

                        <div class="form-group">
                            <label for="">部门</label>
                            <select v-model="deptId" class="form-control">
                                <option v-for="(dept, index) in deptList" :key="index" :value="dept.id">
                                    {{dept.title}}
                                </option>

                            </select>
                        </div>

                        <button @click="create" type="button" class="btn btn-primary btn-lg btn-block">添加</button>
                    </div>
                </div>
            </div>

            <div class="col-lg-8">
                <!-- 表格 -->
                <table class="table">
                    <thead>
                        <tr>
                            <th><input type="checkbox"></th>
                            <th>编号</th>
                            <th>姓名</th>
                            <th>联系方式</th>
                            <th>职位</th>
                            <th>部门</th>
                            <th>工作地点</th>
                            <th>操作</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr v-for="(staff, index) in staffList" :key="index">
                            <td><input type="checkbox"></td>
                            <td>{{staff.id}}</td>
                            <td>{{staff.name}}</td>
                            <td>{{staff.phone}}</td>
                            <td>{{staff.job.title}}</td>
                            <td>{{staff.dept.title}}</td>
                            <td>{{staff.dept.loc}}</td>
                            <td>
                                <button @click="edit(index)" type="button" class="btn btn-primary" data-toggle="modal"
                                    data-target="#modelId">编辑</button>


                                <!-- Modal -->
                                <div class="modal fade" id="modelId" tabindex="-1" role="dialog"
                                    aria-labelledby="modelTitleId" aria-hidden="true">
                                    <div class="modal-dialog" role="document">
                                        <div class="modal-content">
                                            <div class="modal-header">
                                                <h5 class="modal-title">修改员工的信息:</h5>
                                                <button type="button" class="close" data-dismiss="modal"
                                                    aria-label="Close">
                                                    <span aria-hidden="true">&times;</span>
                                                </button>
                                            </div>
                                            <div class="modal-body">
                                                <!-- 表单 -->



                                                <div class="form-group">
                                                    <label for="">姓名</label>
                                                    <input v-model="editItem.name" type="text" class="form-control"
                                                        name="" id="" aria-describedby="helpId" placeholder="姓名">

                                                </div>

                                                <div class="form-group">
                                                    <label for="">联系方式</label>
                                                    <input v-model=" editItem.phone" type="text" class="form-control"
                                                        name="" id="" aria-describedby="helpId" placeholder="联系方式">

                                                </div>

                                                
                                                <div class="form-group">
                                                    <label for="">职位</label>
                                                    <select v-model="editItem.job_id" class="form-control">
                                                        <option v-for="(job, index) in jobList" :key="index" :value="job.id">
                                                            {{job.title}}
                                                        </option>
                        
                                                    </select>
                                                </div>

                                                <div class="form-group">
                                                    <label for="">部门</label>
                                                    <select v-model="editItem.dept_id" class="form-control">
                                                        <option v-for="(dept, index) in deptList" :key="index" :value="dept.id">
                                                            {{dept.title}}
                                                        </option>
                        
                                                    </select>
                                                </div>

                                                <div class="form-group">
                                                    <label for="">工作地点</label>
                                                    <select v-model="editItem.dept_id" class="form-control">
                                                        <option v-for="(dept, index) in deptList" :key="index" :value="dept.id">
                                                            {{dept.loc}}
                                                        </option>
                        
                                                    </select>
                                                </div>

                                            </div>
                                            <div class="modal-footer">
                                                <button type="button" class="btn btn-secondary"
                                                    data-dismiss="modal">取消</button>
                                                <button @click="update" type="button" class="btn btn-primary"
                                                    data-dismiss="modal">确定</button>
                                            </div>
                                        </div>

                                    </div>
                                </div>
                                <button @click="del(staff.id)" type="button" class="btn btn-danger">删除</button>
                            </td>



                        </tr>

                    </tbody>
                </table>
            </div>
        </div>
    </div>

    <script>
        new Vue({
            el: '#app',
            data: {
                // 部门列表
                deptList: [],
                // 职位列表
                jobList: [],
                name: '',
                phone: '',
                deptId: '',
                jobId: '',
                // 员工列表
                staffList: [],

                // 更新
                editIndex: 0,
                editItem: {}
            },
            methods: {
                // 创建员工
                create: function () {
                    let url = '/api/staff';
                    let params = {
                        name: this.name,
                        phone: this.phone,
                        job: {
                            id: this.jobId
                        },
                        dept: {
                            id: this.deptId
                        }

                    };

                    axios.post(url, params)
                        .then(res => {
                            // console.log(res)
                            // this.staffList.push(res.data)
                            // 再次加载
                            axios.get('/api/staff')
                                .then(res => {
                                    // console.log(res)
                                    this.staffList = res.data;
                                })
                                .catch(err => {
                                    console.error(err);
                                })

                        })
                        .catch(err => {
                            console.error(err);
                        })
                },

                // 删除员工
                del: function (id) {
                    let url = `/api/staff/${id}`;
                    axios.delete(url)
                        .then(res => {
                            // console.log(res)
                            // 再次加载
                            axios.get('/api/staff')
                                .then(res => {
                                    // console.log(res)
                                    this.staffList = res.data;
                                })
                                .catch(err => {
                                    console.error(err);
                                })

                        })
                        .catch(err => {
                            console.error(err);
                        })
                },

                // 编辑员工的方法
                edit: function (i) {
                    // 获得更新的内容
                    this.editIndex = i;
                    this.editItem = {},
                        // console.log(this.staffList);


                    // staffList的内容赋给editItem
                    this.editItem.id = this.staffList[i].id;
                    this.editItem.name = this.staffList[i].name;
                    this.editItem.phone = this.staffList[i].phone;
                   
                    this.editItem.dept_id = this.staffList[i].dept.id;
                 
                    
                    this.editItem.job_id = this.staffList[i].job.id;
                    
                    // console.log(this.editItem);
                    console.log(this.staffList[i].dept.id);
                    console.log(this.staffList[i].job.id);
                    console.log(this.editItem);
                    

                },


                // 更新员工
                update: function () {
                   

                    let url = `/api/staff/${this.editItem.id}`;
                    let params ={
                        name:this.editItem.name,
                        phone:this.editItem.phone,
                        dept:{
                            id:this.editItem.dept_id
                        },
                        job:{
                            id:this.editItem.job_id
                        }
                    }

                    axios.put(url, params)
                        .then(res => {
                            // console.log(res)
                            // 再次加载
                            axios.get(`/api/staff`)
                            .then(res => {
                                // console.log(res)
                                this.staffList=res.data;
                            })
                            .catch(err => {
                                console.error(err); 
                            })
                        })
                        .catch(err => {
                            console.error(err);
                        })
                }


            },

            created() {
                // 加载部门信息
                axios.get('/api/dept')
                    .then(res => {
                        // console.log(res)
                        this.deptList = res.data;
                        // 获得·默认的部门
                        this.deptId = this.deptList[0].id;
                    })
                    .catch(err => {
                        console.error(err);
                    }),

                    // 加载职位信息
                    axios.get('/api/job')
                        .then(res => {
                            // console.log(res)
                            this.jobList = res.data;
                            //   获得·默认的职位
                            this.jobId = this.jobList[0].id;
                        })
                        .catch(err => {
                            console.error(err);
                        }),

                    axios.get('/api/staff')
                        .then(res => {
                            // console.log(res)
                            this.staffList = res.data;
                        })
                        .catch(err => {
                            console.error(err);
                        })
            },
        })
    </script>
    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
        integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
        crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
        integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"
        crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
        integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
        crossorigin="anonymous"></script>
</body>

</html>

运行程序,然后我们就可以通过浏览器看到效果了

这个界面相当于Vue路由。可以跳转,不是通过超链接跳转的,那样太lowl了。Vue CLI 开发 SPA ,则 Vue 路由才是必须的。SPA 有且只有一个 html,在唯一的页面中组件替换渲染,地址栏路径的变换(表象)。


以staff为例,基本实现了staff表的CRUD操作。

 


 到这里,关于JPA+Vue+axios实现员工管理系统(CRUD)就差不多结束了。有问题的小伙伴可以留言!!!

发布了131 篇原创文章 · 获赞 332 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_44364444/article/details/105493883