乐趣区

ReactSpring-Data-JPAMySQL-增查改删

视频演示:

https://www.bilibili.com/video/BV1La4y1a7Rp/

工程概述:

  1. 前后端分离,进行简单增查改删(CRUD)
  2. 前端使用 React
  3. 后端使用 Spring Data JPA
  4. 数据库使用 MySQL

后台端代码上一节已经展示,这里将不再重复,仅展示 React 代码既可。

往期内容

内容

01

Vue+Spring Boot JPA+MySQL 增查改删

02

Thymeleaf+Spring Boot JPA+MySQL 增查改删

03

Vue+Spring Boot 文件操作,上传、预览和删除

04

Thymeleaf+Spring Boot 文件操作,上传、预览和删除

EmployeeService.js


import http from "../http-common";

class EmployeeService {getAll(pageNumber) {return http.get(`/employee?page=${pageNumber}`);
    }
  
    get(id) {return http.get(`/employee/${id}`);
    }
  
    create(data) {return http.post("/employee", data);
    }
  
    update(data) {return http.put("/employee", data);
    }
  
    delete(id) {return http.delete(`/employee/${id}`);
    }
  
  }
  
  export default new EmployeeService();

EmployeesCreateComponent.js


import React, {Component} from "react";
import {Redirect} from "react-router-dom";
import EmployeeService from "../services/EmployeeService";

export default class EmployeesCreateComponent extends Component {constructor(props) {super(props);
    this.saveEmployee = this.saveEmployee.bind(this);
    this.onChangeName = this.onChangeName.bind(this);
    this.onChangeGender = this.onChangeGender.bind(this);
    this.onChangeAge = this.onChangeAge.bind(this);
    this.onChangeIntroduce = this.onChangeIntroduce.bind(this);
    
    this.state = {
      id: null,
      name: "",
      gender: "MALE", 
      age: 18,
      introduce: "",
      ageRange: [],
      redirect: false 
    };
  }


  componentDidMount() {
    // 初始化年龄下拉列表
    var rows = [], i = 17, len = 60;
    while (++i <= len) rows.push(i);
    this.setState({ageRange : rows})
  }


  onChangeName(e) {
    this.setState({name: e.target.value});
  }
  onChangeGender(e) {
    this.setState({gender: e.target.value});
  }
  onChangeAge(e){
    this.setState({age: e.target.value});
  }
  onChangeIntroduce(e){
    this.setState({introduce: e.target.value});
  }

  // 保存
  saveEmployee() {
    var data = {
      name: this.state.name,
      gender: this.state.gender,
      age: this.state.age,
      introduce: this.state.introduce
    };

    EmployeeService.create(data)
      .then(response => {
        this.setState({redirect: true});
      })
      .catch(e => {console.log(e);
      });
  }


  render() {const { redirect} = this.state;
    return (
      <div className="submit-form">
        {redirect ? (<Redirect to='/employees'/>) : (

          <div>
            <div className="form-group">
              <label htmlFor="name">Name</label>
              <input
                type="text"
                className="form-control"
                id="name"
                required
                value={this.state.name}
                onChange={this.onChangeName}
                name="name"
              />
            </div>

            <div className="form-group">
              <input
                type="radio"
                id="male"
                name="gender"
                value="MALE"
                onChange={this.onChangeGender}
              />
              <label htmlFor="male">Male</label>

              <input
                type="radio"
                id="female"
                name="gender"
                value="FEMALE"
                onChange={this.onChangeGender}
              />
              <label htmlFor="female">Female</label>
             
              
              <div className="form-group">
                <label> Age:</label>
                <select  className="form-control"  value={this.state.age} name="age" onChange={this.onChangeAge}>
                  {this.state.ageRange.map((a, index) => (<option value={a} key={index}>{a}</option>
                  ))}  
                </select>
              </div>

              <div className="form-group">
                <label> Introduce:</label>
                <textarea  className="form-control" value={this.state.introduce} name="introduce" onChange={this.onChangeIntroduce} ></textarea>
              </div>

            </div>  
           
            <button onClick={this.saveEmployee} className="btn btn-success">
              Add Employee
            </button>
          </div>

        )}
      </div>
    );
  }
}

EmployeesEditComponent.js


import React, {Component} from "react";
import EmployeesService from "../services/EmployeeService";

export default class Tutorial extends Component {constructor(props) {super(props);
    this.getEmployee = this.getEmployee.bind(this);

    this.onChangeName = this.onChangeName.bind(this);
    this.onChangeGender = this.onChangeGender.bind(this);
    this.onChangeAge = this.onChangeAge.bind(this);
    this.onChangeIntroduce = this.onChangeIntroduce.bind(this);
    
    this.updateEmployee = this.updateEmployee.bind(this);
  
    this.state = {
      currentEmployee: {
        id: null,
        name: "",
        gender: "MALE", 
        age: 0,
        introduce: ""
      },
      ageRange: []};
  }

  componentDidMount() {
    // 初始化年龄列表
    var rows = [], i = 17, len = 60;
    while (++i <= len) rows.push(i);
    this.setState({ageRange : rows})
    // 根据 ID 获取员工信息
    this.getEmployee(this.props.match.params.id);
  }

  onChangeName(e) {
    const name = e.target.value;
    this.setState(function(prevState) {
      return {
        currentEmployee: {
          ...prevState.currentEmployee,
          name: name
        }
      };
    });
  }

  onChangeGender(e) {
    const gender = e.target.value;
    this.setState(function(prevState) {
      return {
        currentEmployee: {
          ...prevState.currentEmployee,
          gender: gender
        }
      };
    });
  }

  onChangeAge(e) {
    const age = e.target.value;
    this.setState(function(prevState) {
      return {
        currentEmployee: {
          ...prevState.currentEmployee,
          age: age
        }
      };
    });
  }

  onChangeIntroduce(e) {
    const introduce = e.target.value;
    this.setState(function(prevState) {
      return {
        currentEmployee: {
          ...prevState.currentEmployee,
          introduce: introduce
        }
      };
    });
  }

  // 根据 ID 获取员工信息
  getEmployee(id) {EmployeesService.get(id)
      .then(response => {
        this.setState({currentEmployee: response.data.content});
        console.log(response.data);
      })
      .catch(e => {console.log(e);
      });
  }


  // 更新员工信息
  updateEmployee() {EmployeesService.update(this.state.currentEmployee)
      .then(response => {console.log(response.data);
        this.props.history.push('/employees');
      })
      .catch(e => {console.log(e);
      });
  }

  render() {const { currentEmployee} = this.state;
    return (
      <div>
      
         <div className="submit-form">
           
            <form>
              <div className="form-group">
                <label htmlFor="name">Name</label>
                <input
                  type="text"
                  className="form-control"
                  id="name"
                  value={currentEmployee.name}
                  onChange={this.onChangeName}
                />
              </div>
              <div className="form-group">
                <input
                  type="radio"
                  id="male"
                  name="gender"
                  checked={currentEmployee.gender === "MALE"}
                  value="MALE"
                  onChange={this.onChangeGender}
                />
                <label htmlFor="male">Male</label>
                <input
                    type="radio"
                    id="female"
                    name="gender"
                    checked={currentEmployee.gender === "FEMALE"}
                    value="FEMALE"
                    onChange={this.onChangeGender}
                />
                <label htmlFor="female">Female</label>

                <div className="form-group">
                  <label> Age:</label>
                  <select  className="form-control"  value={this.state.currentEmployee.age} name="age" onChange={this.onChangeAge}>
                    {this.state.ageRange.map((a, index) => (<option value={a} key={index}>{a}</option>
                    ))}  
                  </select>
                </div>

                <div className="form-group">
                  <label> Introduce:</label>
                  <textarea  className="form-control" value={this.state.currentEmployee.introduce} name="introduce" onChange={this.onChangeIntroduce} ></textarea>
                </div>

              </div>
            </form>
           
            <button
              type="submit"
              className="btn btn-success"
              onClick={this.updateEmployee}
            >
              Update Employee
            </button>
            <p>{this.state.message}</p>
          </div>
       
      </div>
    );
  }
}

EmployeesListComponent.js


import React, {Component} from "react";
import EmployeeService from '../services/EmployeeService';
import Pagination from "react-js-pagination";
import Table from 'react-bootstrap/Table';
import Button from 'react-bootstrap/Button';


export default class EmployeesListComponent extends Component {constructor(props) {super(props);
    this.retrieveEmployee = this.retrieveEmployee.bind(this);
   
    this.state = {employees: [],           // 数据 
      activePage: 1,           // 默认首页
      itemsCountPerPage: 3,    // 每页记录数
      totalItemsCount: 0,      // 总记录数
      pageRangeDisplayed: 5    // 分页栏只显示 5 个分页 
     
    };
  }

  // 点击分页
  handlePageChange(activePage) {this.setState({activePage: activePage});
    this.retrieveEmployee(activePage);
  }
   
  componentDidMount() {
    // 获取首页
    this.retrieveEmployee(1);
  }

  // 根据 ID 删除员工
  deleteEmployee(id){EmployeeService.delete(id).then(response =>{
      // 删除成功后, 也可以直接调用后台获取当前页面数据 
      this.retrieveEmployee(this.state.activePage);

    });
  }

  // 编辑页面
  editEmployee(id) {this.props.history.push('/employee/'+id)
  }


  // 获取数据方法
  retrieveEmployee(activePage) {
    // 前端页面从 1 开始,而后台页面从 0 开始,所以 -1
    EmployeeService.getAll(activePage-1)
      .then(response => {
        this.setState({
          employees: response.data.content.content,
          totalItemsCount: response.data.content.totalElements,
          itemsCountPerPage: response.data.content.size
        });
        console.log(response.data);
      })
      .catch(e => {console.log(e);
      });
  }

  render() {const { employees} = this.state;
    return (
        <div>
            <Table striped bordered hover>
              <thead >
                <tr>
                  <th >ID</th>
                  <th >Name</th>
                  <th >Gender</th>
                  <th >Age</th>
                  <th >Introduce</th>
                  <th >Actions</th>
                </tr>
              </thead>

              <tbody>
                {employees && employees.map((tutorial, index) => (<tr  key={index}>
                      <td>{tutorial.id}</td>
                      <td>{tutorial.name}</td>
                      <td>{tutorial.gender}</td>
                      <td>{tutorial.age}</td>
                      <td>{tutorial.introduce}</td>
                      <td>
                
                      <Button variant="info"  onClick={() => this.editEmployee(tutorial.id) }> 编辑 </Button>
                      <Button variant="danger"  onClick={() => this.deleteEmployee(tutorial.id) }> 删除 </Button>
                      
                      </td>
                    </tr>
                  ))}  
              </tbody>
            </Table>
            { this.state.totalItemsCount > 0 &&
              <div className="col-md-6">
                <Pagination
                  activePage={this.state.activePage}
                  itemsCountPerPage={this.state.itemsCountPerPage}
                  totalItemsCount={this.state.totalItemsCount}
                  pageRangeDisplayed={this.state.pageRangeDisplayed}
                  onChange={this.handlePageChange.bind(this)}
                  itemClass="page-item"
                  linkClass="page-link"
                />
              </div>
            }
          
        </div>

    );
   
  }
}
退出移动版