基于SpringMVC+MyBatis+Vue实现客户关系管理平台(CRUD)

要求:SpringToolSuite4,Postman测试工具,VsCode,数据库等,

为了方便小伙伴们可以更快的掌握,代码注释很详细。

控制器:


	1.接收HTTP请求
	2.调用业务逻辑或数据操作(Model)
	3.返回视图名(View)
	4.返回数据(application/json/xml)

 数据库:

create table customers(
  id int primary key auto_increment,
  name varchar(64) not null,
  area enum('东北','华北','华东','西北','华南','西南','中南') not null,
  principal varchar(64) not null,
  level enum('普通客户','大客户','合作伙伴','重点开发客户') not null
);

SpringToolSuite4工程目录

基于SpringMVC+MyBatis+Vue实现客户关系管理平台(CRUD)


application.properties

#数据源
spring.datasource.url=jdbc:mysql://阿里云ip:3306/a
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

spring.http.log-request-details=true
logging.level.web=debug

 


Customer.java

package com.newer.test.pojo;

/**
 * 实体(POJO - 简单的 Java 对象 / JavaBean) JavaBean 组件(规范) 1)无参数构造器 2)getters、setters
 * 访问方法 3)有访问方法的字段(成员变量)才称属性
 * @author Admin
 *
 */
public class Customer {

	int id;

	String name;
	String area;
	String principal;
	String level;

	public Customer() {
	}

	public int getId() {
		return id;
	}

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

	public String getName() {
		return name;
	}

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

	public String getArea() {
		return area;
	}

	public void setArea(String area) {
		this.area = area;
	}

	public String getPrincipal() {
		return principal;
	}

	public void setPrincipal(String principal) {
		this.principal = principal;
	}

	public String getLevel() {
		return level;
	}

	public void setLevel(String level) {
		this.level = level;
	}

	@Override
	public String toString() {
		return "Customer [id=" + id + ", name=" + name + ", area=" + area + ", principal=" + principal + ", level="
				+ level + "]";
	}

}

CustomerMapper.java

package com.newer.test.mapper;

import java.util.List;

import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.SelectProvider;
import org.apache.ibatis.annotations.Update;
import org.apache.ibatis.jdbc.SQL;

import com.newer.test.pojo.Customer;

/**
 *  MyBatis 是一个 Java 的 SQL 映射框架(ORM - 对象关系映射) 1)类属性映射表字段 2)类与类的关系映射表与表的关系
 * @author Admin
 *
 */
@Mapper
public interface CustomerMapper {

	/**
	 * 添加客户
	 * 
	 * @param customer
	 * @return 是否成功
	 */
	@Insert("insert into customers(name,area,principal,level) values(#{name},#{area},#{principal},#{level})")
	@Options(useGeneratedKeys = true, keyProperty = "id")
	boolean save(Customer customer);

	/**
	 * 显示所有客户信息
	 * 
	 * @return 客户列表
	 */
	@Select("select * from customers")
	List<Customer> findAll();
	
	
	/**
	 * 删除客户
	 */

	@Delete("delete from customers where id=#{id}")
	void remove(int id);
	
	/**
	 * 更新客户
	 */
	@Update("update customers set name=#{name},area=#{area},principal=#{principal},level=#{level} where id=#{id} ")
	void updata(Customer customer);
	
	/**
	 * 条件查询(基于动态 SQL)
	 * 
	 * @param customer
	 * @return
	 */
	@SelectProvider(type = CustomerProvider.class, method = "find")
	List<Customer> search(Customer customer);

	/**
	 * 动态 SQL 定义
	 * 
	 * @author wtao
	 *
	 */
	static class CustomerProvider {

		/**
		 * 字段是否有值
		 * 
		 * @param field
		 * @return
		 */
		static boolean isExist(String field) {
			return field != null && field.trim().length() > 0;
		}

		/**
		 * 条件查询
		 * 
		 * @param customer
		 * @return
		 */
		public String find(Customer customer) {
			return new SQL() {
				{
					SELECT("*");
					FROM("customers");
					if (customer != null) {
						if (isExist(customer.getName())) {
							WHERE("name like concat('%',#{name},'%')");
						}
						if (isExist(customer.getArea())) {
							WHERE("area like #{area}");
						}
						if (isExist(customer.getPrincipal())) {
							WHERE("principal like #{principal}");
						}
						if (isExist(customer.getLevel())) {
							WHERE("level like #{level}");
						}
					}
					ORDER_BY("id");
				}
			}.toString();
		}
	}

}

CustomerController.java

package com.newer.test.controller;

import java.util.List;

import org.apache.ibatis.annotations.Delete;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
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.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.newer.test.mapper.CustomerMapper;
import com.newer.test.pojo.Customer;

/**
 * 控制器
 * 1)接收 HTTP 请求
 * 2)调用业务逻辑或数据操作(Model
 * 3)返回视图名(View
 * 4)返回数据(application/json/xml
 * 
 * @author 
 *
 */
@Controller
public class CustomerController {

	/**
	 * 控制器依赖数据操作(自动注入/装配
	 */
	@Autowired
	CustomerMapper customerMapper;

	// 返回视图名
	@GetMapping("/")
	public String index() {
		return "index.html";
	}
	

	/**
	 * GET /api/search
	 * 
	 * @param customer HTTP GET,HTTP 请求中的字符串查询参数,不是 payload(@RequestBody)
	 * @return
	 */
	@GetMapping("/api/search")
	@ResponseBody
	public List<Customer> search(Customer customer) {
		// 约定由于配置
		// 使用约定好的规则,则很简单
		return customerMapper.search(customer);
	}
	
	// HTTP 字符串查询参数名称任意命名
	// 1)映射请求参数和方法参数
	// 2)设置是否必须(required
	// 3)可以设置默认值(defaultValue)
	@GetMapping("/api/search2")
	@ResponseBody
	public List<Customer> search(
			@RequestParam(name = "n", required = false) String name,
			@RequestParam(name = "a", required = false) String area,
			@RequestParam(name = "p", required = false) String principal,
			@RequestParam(name = "l", defaultValue = "", required = false) String level
			) {
		
		// 参数名不一致,手动装配
		Customer c = new Customer();
		c.setName(name);
		c.setArea(area);
		c.setPrincipal(principal);
		c.setLevel(level);
		
		return customerMapper.search(c);
	}
	
	
	
	/**
	 * POST /api/customer
	 * 
	 * @param customer HTTP 请求中的负载(payload),格式为 application/json,必须指定 @RequestBody 注解
	 * 
	 * @return 存储在数据库中的客户对象
	 */
	@ResponseBody
	@PostMapping("/api/customer")
	public Customer create(@RequestBody Customer customer) {
		// 存入数据库前 customer 状态成为:瞬时,没有主键值(PK)
		// 存储存储库
		customerMapper.save(customer);
		// 存入数据库后 customer 状态成为:持久化,存在主键值
		return customer;
	}
	
	/**
	 * GET /api/customer
	 * 
	 * @return 客户列表
	 */
	@GetMapping("/api/customer")
//	@ResponseBody
	public @ResponseBody List<Customer> findAll() {
		return customerMapper.findAll();
	}
	
	
	/**
	 * delete
	 */
	@DeleteMapping("/api/customer/{id}")
	@ResponseBody
	public void remove(@PathVariable int id) {
		customerMapper.remove(id);
	}
	
	/**
	 * put
	 */
	
	@PutMapping("/api/customer/{id}")
	@ResponseBody
	public void updata(@PathVariable int id,@RequestBody Customer customer) {
		 customer.setId(id);
		 customerMapper.updata(customer);
	}
	
	
	
}

index.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="bootstrap.min.css">

    <!-- 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 p-3">
        <div class="container">
            <h1 class="display-3">客户关系管理平台</h1>
            <p class="lead"><span class="badge badge-pill badge-danger">牛耳教育</span></p>
        </div>
    </div>

    <!-- 主体 -->
    <div id="app" class="container-fluid">
        <div class="row">
            <div class="col-lg-3 col-sm-12">
                <div class="card">
                    <div class="card-body">
                        <h4 class="card-title">添加客户资料</h4>
                        <!-- 表单 添加新客户 -->
                        <!-- <form action=""> -->
                        <div class="form-group">
                            <label for="">客户名称</label>
                            <input v-model="name" type="text" class="form-control" name="" required placeholder="客户名称">
                        </div>
                        <div class="form-group  ">
                            <label for="">地区</label>
                            <select class="form-control" v-model="area">
                                <option>请选择</option>
                                <option>北京</option>
                                <option>华北</option>
                                <option>华东</option>
                                <option>中南</option>
                            </select>
                        </div>
                        <div class="form-group">
                            <label for="">客户经理</label>
                            <select class="form-control" v-model="principal">
                                <option>请选择</option>
                                <option>小明</option>
                                <option>旺财</option>
                                <option>球球</option>
                                <option>孙小美</option>
                            </select>
                        </div>
                        <div class="form-group  ">
                            <label for="">客户等级</label>
                            <select class="form-control" v-model="level">
                                <option>请选择</option>
                                <option>普通客户</option>
                                <option>大客户</option>
                                <option>合作伙伴</option>
                                <option>重点开发客户</option>
                            </select>
                        </div>

                        <button @click="create" type="submit" class="btn btn-block btn-success">保存</button>
                        <!-- </form> -->
                    </div>
                </div>
            </div>
            <div class="col-lg-9 col-sm-12">

                <div class="card">
                    <div class="card-body">
                        <!-- 条件查询 -->
                        <form class="form-inline" action="" method="">

                            <!-- 整排查询框 -->



                            <label>客户名称:</label>
                            <input type="text" v-model="sName">

                            <label>地区:</label>
                            <select v-model="sArea" @change="search">
                                <option value="">所有</option>
                                <option>东北</option>
                                <option>华北</option>
                                <option>华东</option>
                                <option>中南</option>
                            </select>


                            <label>客户经理:</label>
                            <select v-model="sPrinicpal" @change="search">
                                <option value="">所有</option>
                                <option>小明</option>
                                <option>旺财</option>
                                <option>球球</option>
                                <option>孙小美</option>
                            </select>



                            <label>客户等级:</label>
                            <select v-model="sLevel" @change="search">
                                <option value="">所有</option>
                                <option>普通客户</option>
                                <option>大客户</option>
                                <option>合作伙伴</option>
                                <option>重点开发客户</option>
                            </select>

                            <button @click="search" class="btn-primary" type="button">
                                查询
                            </button>


                        </form>
                    </div>
                </div>

                <!-- 显示数据 -->
                <table class="table table-bordered">
                    <thead>
                        <tr>
                            <th>编号</th>
                            <th>客户名称</th>
                            <th>地区</th>
                            <th>客户经理</th>
                            <th>客户等级</th>
                            <th style="width:30%">操作</th>
                        </tr>
                        </tr>
                    </thead>
                    <tbody>
                        <tr v-for="(item, index) in customerList" :key="index">
                            <td>{{item.id}}</td>
                            <td>{{item.name}}</td>
                            <td>{{item.area}}</td>
                            <td>{{item.principal}}</td>
                            <td>{{item.level}}</td>
                            <td>
                                <!-- 按钮 -->
                                <div class="row">

                                    <div class="col">


                                        <button @click="edit(index)" type="button" name="" id=""
                                            class="btn btn-primary  btn-block" data-toggle="modal"
                                            data-target="#modelId">编辑</button>
                                        <!-- 模态框 -->
                                        <!-- Button trigger modal -->


                                        <!-- 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="" required
                                                                placeholder="客户名称">
                                                        </div>
                                                        <div class="form-group  ">
                                                            <label for="">地区</label>
                                                            <select class="form-control" v-model="editItem.area">
                                                                <option>请选择</option>
                                                                <option>北京</option>
                                                                <option>华北</option>
                                                                <option>华东</option>
                                                                <option>中南</option>
                                                            </select>
                                                        </div>
                                                        <div class="form-group">
                                                            <label for="">客户经理</label>
                                                            <select class="form-control" v-model="editItem.principal">
                                                                <option>请选择</option>
                                                                <option>小明</option>
                                                                <option>旺财</option>
                                                                <option>球球</option>
                                                                <option>孙小美</option>
                                                            </select>
                                                        </div>
                                                        <div class="form-group  ">
                                                            <label for="">客户等级</label>
                                                            <select class="form-control" v-model="editItem.level">
                                                                <option>请选择</option>
                                                                <option>普通客户</option>
                                                                <option>大客户</option>
                                                                <option>合作伙伴</option>
                                                                <option>重点开发客户</option>
                                                            </select>
                                                        </div>
                                                    </div>
                                                    <div class="modal-footer">
                                                        <button type="button" class="btn btn-secondary"
                                                            data-dismiss="modal">取消</button>
                                                        <button @click="updata" type="button" class="btn btn-primary"
                                                            data-dismiss="modal">确定</button>
                                                    </div>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                    <div class="col">


                                        <button @click="remove(item.id)" type="button" name="" id=""
                                            class="btn btn-danger  btn-block">删除</button>
                                    </div>
                                </div>
                            </td>
                        </tr>
                    </tbody>
                </table>


            </div>
        </div>
    </div>

    <script>
        new Vue({
            el: '#app',
            data: {
                // 加载
                customerList: [],
                // 创建
                name: '',
                area: '请选择',
                level: '普通客户',
                principal: '请选择',
                // 条件查询
                sName: undefined,
                sArea: '所有',
                sLevel: '所有',
                sPrinicpal: '所有',

                // 编辑
                editItem: {},
                editIndex: 0

            },
            methods: {

                // 编辑的方法
                edit: function (i) {
                    // 获取编辑的索引
                    this.editIndex = i;
                    this.editItem = {};
                    this.editItem.id = this.customerList[i].id;
                    this.editItem.name = this.customerList[i].name;
                    this.editItem.area = this.customerList[i].area;
                    this.editItem.principal = this.customerList[i].principal;
                    this.editItem.level = this.customerList[i].level;

                },

                // 更新
                updata: function () {
                    // console.log(this.editItem);
                    let url = `/api/customer/${this.editItem.id}`;
                    let params = this.editItem;
                    axios.put(url, params)
                        .then(res => {
                            console.log(res)
                            axios.get("/api/customer")
                                .then(res => {
                                    console.log(res)
                                    this.customerList = res.data;
                                })
                                .catch(err => {
                                    console.error(err);
                                })

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




                // 条件查询
                search: function () {
                    // 请求路径 RESTful API
                    let url = '/api/search2';
                    // 字符串查询参数(键值对),编码后追加在 URL 后面的
                    // 参数键的名称,可以自定义,最好与实体一致
                    // 约定的参数名
                    let params = {
                        name: this.sName,
                        area: this.sArea === '所有' ? undefined : this.sArea,
                        level: this.sLevel === '所有' ? undefined : this.sLevel,
                        principal: this.sPrinicpal === '所有' ? undefined : this.sPrinicpal
                    };
                    // 参数名不匹配(任意的
                    let params2 = {
                        n: this.sName,
                        a: this.sArea === '所有' ? undefined : this.sArea,
                        l: this.sLevel === '所有' ? undefined : this.sLevel,
                        p: this.sPrinicpal === '所有' ? undefined : this.sPrinicpal
                    };
                    // GET
                    // 1) 请求路径
                    // 2)字符串查询参数
                    axios.get(
                        url,
                        { params: params2 }
                    )
                        .then(res => {
                            // console.log(res);
                            this.customerList = res.data;
                        });
                },
                // 创建
                create: function () {
                    // RESTful API 及参数
                    let url = '/api/customer';
                    let payload = {
                        name: this.name,
                        principal: this.principal,
                        area: this.area,
                        level: this.level
                    };
                    // AJAX POST 请求
                    axios.post(url, payload)
                        .then(res => {
                            // console.log(res.data)
                            this.customerList.push(res.data);
                            this.name = '',
                                this.area = '请选择',
                                this.principal = '请选择',
                                this.level = '普通客户'
                        })
                        .catch(err => {
                            // console.error(err); 
                        })
                },


                // 删除
                remove: function (id) {
                    let url = `/api/customer/${id}`;
                    axios.delete(url)
                        .then(res => {
                            console.log(res)
                            axios.get("/api/customer")
                                .then(res => {
                                    console.log(res)
                                    this.customerList = res.data;
                                })
                                .catch(err => {
                                    console.error(err);
                                })
                        })
                        .catch(err => {
                            console.error(err);
                        })
                }
            },
            created() {
                // 前端、后端在同一个进程中
                let url = '/api/customer';
                // 加载
                axios.get(url)
                    .then(res => {
                        // console.log(res)
                        this.customerList = 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>

效果如图: 

基于SpringMVC+MyBatis+Vue实现客户关系管理平台(CRUD)


 基于SpringMVC+MyBatis+Vue实现客户关系管理平台(CRUD)就到这结束啦!有问题的小伙伴可以留言。

上一篇:基于Spring oauth2.0统一认证登录,返回自定义用户信息


下一篇:动态规划3:连续子数组类问题