10.Spring Boot 实战~Spring Boot总结 ( 增,删,查,改,上传,分页 )

10.Spring Boot 实战~Spring Boot总结 ( 增,删,查,改,上传,分页 )

本文是上一篇文章的后续,详情点击该链接~

项目需求

增,删,查,改,上传,分页

10.Spring Boot 实战~Spring Boot总结 ( 增,删,查,改,上传,分页 )_第1张图片

项目准备

搭建项目结构

10.Spring Boot 实战~Spring Boot总结 ( 增,删,查,改,上传,分页 )_第2张图片

导入依赖


<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0modelVersion>

    
    

    <groupId>com.alvingroupId>
    <artifactId>test_frameworkartifactId>
    <version>1.0-SNAPSHOTversion>

    <dependencyManagement>
        
        <dependencies>
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-dependenciesartifactId>
                <version>2.3.0.RELEASEversion>
                <type>pomtype>
                <scope>importscope>
            dependency>
        dependencies>
    dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>com.github.pagehelpergroupId>
            <artifactId>pagehelper-spring-boot-starterartifactId>
            <version>1.2.13version>
        dependency>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-thymeleafartifactId>
        dependency>
        <dependency>
            <groupId>org.mybatis.spring.bootgroupId>
            <artifactId>mybatis-spring-boot-starterartifactId>
            <version>2.1.2version>
        dependency>
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
        dependency>
    dependencies>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.pluginsgroupId>
                    <artifactId>maven-compiler-pluginartifactId>
                    <configuration>
                        <parameters>trueparameters>
                    configuration>
                plugin>
                <plugin>
                    <groupId>org.springframework.bootgroupId>
                    <artifactId>spring-boot-maven-pluginartifactId>
                    <executions>
                        <execution>
                            <id>repackageid>
                            <goals>
                                <goal>repackagegoal>
                            goals>
                        execution>
                    executions>
                plugin>
            plugins>
        pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
            plugin>
        plugins>
    build>
project>

application.yml配置文件

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test_framework?serverTimezone=Asia/Shanghai
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver
  thymeleaf:
    prefix: classpath:/myviews/  # thymeleaf返回结果的视图前缀。默认 classpath:/templates/
    suffix: .html # thymeleaf返回结果视图后缀,默认 .html
mybatis:
  mapper-locations: classpath:/mybatisxml/**/*.xml

数据库

create database test_framework;

use test_framework;

drop table if exists tb_customer;

create table tb_customer(
  id integer not null auto_increment,
  name varchar(32) comment '姓名',
  gender varchar(8) comment '性别',
  age int(3) comment '年龄',
  img varchar(64) comment '头像文件路径及文件名',
  orig_img varchar(64) comment '客户上传的头像文件原始命名',
  primary key(id)
);

drop table if exists tb_phone;

create table tb_phone(
  id integer not null auto_increment,
  phone_no varchar(18) comment '联系方式',
  customer_id integer comment '客户主键',
  primary key (id)
);

INSERT INTO tb_customer VALUES (1, '李子明', '男', 20, '/imgs/1.jpg', '1.jpg');
INSERT INTO tb_customer VALUES (2, '赵天', '男', 24, '/imgs/2.jpg', '2.jpg');
INSERT INTO tb_customer VALUES (3, '王羽', '男', 18, '/imgs/3.jpg', '3.jpg');
INSERT INTO tb_customer VALUES (4, '赵珊', '女', 23, '/imgs/4.jpg', '4.jpg');
INSERT INTO tb_customer VALUES (5, '刘海信', '男', 66, '/imgs/7.jpg', '7.jpg');
INSERT INTO tb_customer VALUES (6, '陈天一', '女', 21, '/imgs/5.jpg', '5.jpg');
INSERT INTO tb_customer VALUES (8, '黄贵根', '男', 19, '/imgs/f4d1847c-16ea-413f-a3eb-fa7b2c2d1750.png', 'timg.png');

后台代码

CustomerController

package com.alvin.controller;

import com.alvin.pojo.Customer;
import com.alvin.pojo.Phone;
import com.alvin.service.CustomerService;
import com.alvin.service.PhoneService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import java.util.Map;


@Controller
public class CustomerController {
    @Autowired
    private CustomerService customerService;
    @Autowired
    private PhoneService phoneService;

    /**
     * 删除客户,需要先删除客户的所有联系方式。再删除客户。
     * @param id
     * @return
     */
    @RequestMapping("/removeCustomer")
    public String removeCustomer(Integer id){
        boolean isRemoved = customerService.removeCustomer(id);
        if(isRemoved){
            return "redirect:/";
        }
        // 删除失败
        return "redirect:/toError";
    }

    /**
     * 修改客户资料
     * @param customer 客户新数据
     * @param uploadImg 修改的头像
     * @return
     */
    @RequestMapping("/modifyCustomer")
    public String modifyConsumer(Customer customer, MultipartFile uploadImg){
        boolean isModified = customerService.modifyCustomer(customer, uploadImg);
        if(isModified) {
            return "redirect:/showCustomer?id=" + customer.getId();
        }
        return "redirect:/toError";
    }

    @RequestMapping("/toModifyCustomer")
    public String toModifyCustomer(Integer id, Model model){
        Customer customer = customerService.getCustomerById(id);
        model.addAttribute("customer", customer);
        return "modifyCustomer";
    }

    /**
     * 新增联系方式
     * @param phone
     * @return
     */
    @RequestMapping("/addPhone")
    public String addPhone(Phone phone){
        boolean isAdded = phoneService.addPhone(phone);

        if(isAdded) {
            // 新增成功后的返回
            return "redirect:/showCustomer?id=" + phone.getCustomerId();
        }

        // 新增失败
        return "redirect:/toError";
    }

    /**
     * 跳转到新增联系方式
     * @param customerId 客户主键
     * @return
     */
    @RequestMapping("/toAddPhone")
    public String toAddPhone(Integer customerId, Model model){
        model.addAttribute("customerId", customerId);
        return "addPhone";
    }

    /**
     * 根据主键查询客户。并显示
     * 查询客户,及客户的联系方式集合。
     * @param id
     * @return
     */
    @RequestMapping("/showCustomer")
    public String showCustomer(Integer id, Model model){

        Customer customer = customerService.getCustomerById(id);

        model.addAttribute("customer", customer);

        return "showCustomer";
    }

    /**
     * 新增客户
     * PostMapping = @RequestMapping(method=RequestMethod.POST)
     *
     * MultipartFile - 使用文件上传处理的时候,商业开发中推荐增加注解@RequestParam,描述请求参数命名。
     *   减少程序员反复比对页面和代码之间的映射。
     *
     * 幂等性操作 - 反复执行对结果无影响。如,查询。
     * 非幂等性操作 - 反复执行,对结果有影响。如:增、删、改。
     * @return
     */
    @PostMapping("/addCustomer")
    public String addCustomer(Customer customer, MultipartFile uploadImg){

        boolean isAdded = customerService.addCustomer(customer, uploadImg);

        if(isAdded){
            // 新增成功。跳转到入口,重定向。避免刷新重复提交表单。
            // 商业开发中,所有的非幂等性操作,返回视图必须重定向。
            return "redirect:/";
        }

        // 新增失败,跳转到错误提示
        return "redirect:/toError";
    }

    // 不能使用路径 /error。 spring-boot-starter-web中内置的系统路径。
    @RequestMapping("/toError")
    public String toError(){
        return "error";
    }

    // 跳转到新增客户页面
    @RequestMapping("/toAddCustomer")
    public String toAddCustomer(){
        return "addCustomer";
    }

    // 入口, 分页查询客户
    @RequestMapping(value = {"/", "/index", "/default", "/welcome"})
    public String toIndex(Model model,
                          @RequestParam(value = "page", defaultValue = "1") int page,
                          @RequestParam(value = "rows", defaultValue = "5") int rows){
        Map<String, Object> map = customerService.getCustomersByPage(page, rows);
        model.addAllAttributes(map);
        return "index";
    }
}

CustomerMapper接口

package com.alvin.mapper;

import com.alvin.pojo.Customer;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface CustomerMapper {
    List<Customer> selectCustomers();

    int selectCount();

    int insert(Customer customer);

    Customer selectById(Integer id);

    int update(Customer customer);

    int deleteCustomer(Integer id);
}

PhoneMapper

package com.alvin.mapper;

import com.alvin.pojo.Phone;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface PhoneMapper {
    int insert(Phone phone);

    int deleteByCustomer(Integer id);
}

Customer

package com.alvin.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.List;

/**
 * 企业开发规范中要求, 实体类型必须可序列化。必须私有化该私有的属性。必须为必要的属性提供getter和setter
 * 必须override方法hashCode和equals。必须提供至少一个无参构造方法。
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Customer implements Serializable {
    private Integer id;
    private String name;
    private String gender;
    private int age;
    private String img;
    private String origImg;
    private List<Phone> phoneList;
}

Phone

package com.alvin.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Phone implements Serializable {
    private Integer id;
    private String phoneNo;
    private String customerId;
}

CustomerServiceImpl

package com.alvin.service.impl;

import com.alvin.mapper.CustomerMapper;
import com.alvin.mapper.PhoneMapper;
import com.alvin.pojo.Customer;
import com.alvin.service.CustomerService;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.*;

@Service
public class CustomerServiceImpl implements CustomerService {
    @Autowired
    private CustomerMapper customerMapper;
    @Autowired
    private PhoneMapper phoneMapper;

    /**
     * 先删除客户的所有联系方式。再删除客户
     * @param id
     * @return
     */
    @Override
    @Transactional
    public boolean removeCustomer(Integer id) {
        // 删除联系方式
        phoneMapper.deleteByCustomer(id);
        int rows = customerMapper.deleteCustomer(id);
        if(rows != 1){
            throw new RuntimeException("删除客户失败");
        }
        return true;
    }

    /**
     * 修改客户数据
     * 判断上传的图片是否存在???
     * @param customer
     * @param uploadImg
     * @return
     */
    @Override
    @Transactional
    public boolean modifyCustomer(Customer customer, MultipartFile uploadImg) {
        String prefix = System.getProperty("user.dir") + File.separator + "src/main/resources/static/imgs/";
        try {
            // 判断上传的文件是否存在?
            int length = uploadImg.getInputStream().available();
            System.out.println("文件长度是:" + length + " 字节");
            if(length != 0){
                String origName = uploadImg.getOriginalFilename();
                // 更新了头像,需要重写头像数据, 查询原头像图片名,
                // 覆盖文件内容即可。 删除原头像图片,增加新的文件。
                Customer old = customerMapper.selectById(customer.getId());
                // 图片地址
                String img = prefix + old.getImg();
                File oldImg = new File(img);
                oldImg.delete();
                String tmpImg = UUID.randomUUID().toString() + origName.substring(origName.lastIndexOf("."));;
                String newImg = prefix + tmpImg;
                File newImgFile = new File(newImg);
                uploadImg.transferTo(newImgFile);

                // 把新的文件名称保存到客户对象中。
                customer.setImg("/imgs/"+tmpImg);
                customer.setOrigImg(origName);
            }

            int rows = customerMapper.update(customer);
            if(rows != 1){
                throw new RuntimeException("修改客户数据失败");
            }

        }catch (IOException e){
            e.printStackTrace();
        }

        return true;
    }

    /**
     * 主键查询客户
     * @param id
     * @return
     */
    @Override
    public Customer getCustomerById(Integer id) {
        return customerMapper.selectById(id);
    }

    /**
     * 新增客户。
     * 1、 保存数据到数据库
     * 2、 上传文件。 保存上传的文件到本地。
     *
     * Transactional - 控制事务
     *   propagation - 事务传播特性|传播行为,如何管理一个事务,如何在方法调用过程中管理一个事务。
     *     如: ma方法,要管理事务,如何控制?
     *     如: ma方法要管理事务,同时ma方法调用了mb方法,mb方法也要管理事务,如何控制?
     *     默认是required,必要事务。当前如果有事务,使用现有的,如果没有,创建新的。
     *     常用的supports,支持事务。当前如果有事务,使用现有的,如果没有,不创建事务。
     *   isolation - 事务隔离级别。 数据库事务有四大特性ACID。 spring事务管理中默认使用default。使用数据库隔离级别。
     *     原子性: 事务是原子的,不可分割的
     *     一致性: 数据一致的
     *     持久性: 数据是持久的
     *     隔离性: 多个事务之间,是隔离的。
     *       read_uncommitted - 读未提交,会有脏读现象。
     *       read_committed - 读已提交,会有不可重复读现象。oracle数据默认隔离级别
     *       repeatable_read - 可重复读,查询的时候,不提交事务,多次查询结果永久不变。开启事务,第一次查询
     *         保存结果到内存,后续未提交事务的所有查询,都直接返回内存结果。会有幻读现象。 是mysql的默认隔离级别。
     *       serializable - 串行化。数据库并行转串行。任何一个事务未提交之前,其他操作挂起阻塞。
     *   rollbackFor - 当什么类型的异常出现时,回滚事务。默认值是RuntimeException.class
     *
     * MyBatis默认事务管理行为是rollback还是commit?
     *   默认回滚。SqlSession的行为。在close的时候,如果发现有未完成的事务,自动回滚。
     *   未管理的事务,一概回滚,保证数据无错。
     *
     * Spring+MyBatis 默认事务管理行为是commit。
     *
     * @param customer
     * @param uploadImg
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, rollbackFor = {RuntimeException.class})
    public boolean addCustomer(Customer customer, MultipartFile uploadImg) {
        try {
            // 找到 resources/static/imgs 文件夹
            String origImg = uploadImg.getOriginalFilename();
            String tmpName = UUID.randomUUID().toString() + origImg.substring(origImg.lastIndexOf("."));
            /*
             * System 对象。 系统对象。其中保存当前启动的JVM相关的所有信息
             *  getProperties - 当前启动的JVM进程相关信息
             *  getEnv - 当前启动的JVM的虚拟机相关信息。
             */
            Properties properties = System.getProperties();
            for(Map.Entry entry : properties.entrySet()){
                System.out.println(entry.getKey() + " --- " + entry.getValue());
            }
            System.out.println("====================================");
            Map<String, String> env = System.getenv();
            for(Map.Entry<String, String> entry: env.entrySet()){
                System.out.println(entry.getKey() + " - " + entry.getValue());
            }
            /*for(String key : env.keySet()){
                System.out.println(key + " - " + env.get(key));
            }*/
            String dir = System.getProperty("user.dir") + File.separator + "src/main/resources/static/imgs/";
            File file = new File(dir, tmpName);
            System.out.println(file.getAbsolutePath());
            // 保存文件到本地。
            uploadImg.transferTo(file);

            // 保存客户数据到数据库
            customer.setImg("/imgs/"+tmpName);
            customer.setOrigImg(origImg);

            int rows = customerMapper.insert(customer);
            if(rows != 1){
                // 新增错误, 回滚
                throw new RuntimeException("新增客户失败");
            }

        }catch (Exception e){
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        return true;
    }

    @Override
    public Map<String, Object> getCustomersByPage(int page, int rows) {
        Map<String, Object> resultMap = new HashMap<>();
        // 使用PageHelper插件,实现分页逻辑。
        PageHelper.startPage(page, rows);
        List<Customer> customerList = customerMapper.selectCustomers();
        // 当前页面显示的内容
        resultMap.put("customerList", customerList);
        // 当前页码
        resultMap.put("currentPage", page);

        // 查询总计数据行数,计算总计页码
        int totalRows = customerMapper.selectCount();
        int totalPages = totalRows % rows == 0 ? totalRows/rows : (totalRows/rows + 1);

        // 总计页码
        resultMap.put("totalPages", totalPages);
        return resultMap;
    }
}

PhoneServiceImpl

package com.alvin.service.impl;

import com.alvin.mapper.PhoneMapper;
import com.alvin.pojo.Phone;
import com.alvin.service.PhoneService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class PhoneServiceImpl implements PhoneService {
    @Autowired
    private PhoneMapper phoneMapper;

    /**
     * 新增联系方式。 抛出异常,回滚事务。
     * @param phone
     * @return
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class})
    public boolean addPhone(Phone phone) {
        int rows = phoneMapper.insert(phone);
        if(rows != 1){
            // 新增失败,回滚事务
            throw new RuntimeException("新增联系方式失败");
        }
        return true;
    }
}

CustomerService接口

package com.alvin.service;

import java.util.Map;

import com.alvin.pojo.Customer;
import org.springframework.web.multipart.MultipartFile;

public interface CustomerService {
    Map<String, Object> getCustomersByPage(int page, int rows);

    boolean addCustomer(Customer customer, MultipartFile uploadImg);

    Customer getCustomerById(Integer id);

    boolean modifyCustomer(Customer customer, MultipartFile uploadImg);

    boolean removeCustomer(Integer id);
}

PhoneService接口

package com.alvin.service;

import com.alvin.pojo.Phone;

public interface PhoneService {
    boolean addPhone(Phone phone);
}

MyApplication启动类

package com.alvin;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

// 启动类约束。 不要写在default包下。 默认只扫描当前类所在包,及所有子孙包。
@SpringBootApplication
// basePackages属性,只为提高扫描效率。 默认扫描当前类所在包及所有子孙包。
@MapperScan(basePackages = {"com.alvin.mapper"})
public class MyApplication {
    public static void main(String[] args) {
        // 读取spring.factories文件中的启动类、配置类、初始化器,实现环境的创建。
        SpringApplication.run(MyApplication.class, args);
    }
}

Mybatis映射

CustomerMapper.xml




<mapper namespace="com.alvin.mapper.CustomerMapper">
    <resultMap id="customerMap" type="com.alvin.pojo.Customer">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="gender" property="gender"/>
        <result column="age" property="age"/>
        <result column="img" property="img"/>
        <result column="orig_img" property="origImg"/>
    resultMap>
    <resultMap id="customerPhoneListMap" type="com.alvin.pojo.Customer">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="gender" property="gender"/>
        <result column="age" property="age"/>
        <result column="img" property="img"/>
        <result column="orig_img" property="origImg"/>
        <collection property="phoneList" javaType="java.util.List"
          ofType="com.alvin.pojo.Phone">
            <id column="p_id" property="id"/>
            <result column="phone_no" property="phoneNo"/>
            <result column="customer_id" property="customerId"/>
        collection>
    resultMap>

    <delete id="deleteCustomer">
        delete from tb_customer
        <where>
            id = #{id}
        where>
    delete>

    
    <update id="update">
        update tb_customer
        <set>
            <trim suffixOverrides=",">
            <if test="name != null">
                name = #{name},
            if>
            <if test="age != 0">
                age = #{age},
            if>
            <if test="gender != null">
                gender = #{gender},
            if>
            <if test="img != null">
                img = #{img},
            if>
            <if test="origImg != null">
                orig_img = #{origImg},
            if>
            trim>
        set>
        <where>
            id = #{id}
        where>
    update>

    <select id="selectById" resultMap="customerPhoneListMap">
        select
          c.id, c.name, c.gender, c.age, c.img, c.orig_img,
          p.id as p_id, p.phone_no, p.customer_id
        from
          tb_customer c
            left join
          tb_phone p
            on c.id = p.customer_id
        <where>
            and c.id = #{id}
        where>
    select>
    <insert id="insert" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
        insert into tb_customer(id, name, gender, age, img, orig_img)
        values(default, #{name}, #{gender}, #{age}, #{img}, #{origImg})
    insert>
    <select id="selectCustomers" resultMap="customerMap">
        select id, name, gender, age, img, orig_img from tb_customer
    select>
    
    <select id="selectCount" resultType="_int">
        select count(id) from tb_customer
    select>
mapper>

PhoneMapper.xml



<mapper namespace="com.alvin.mapper.PhoneMapper">
    <insert id="insert" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
        insert into tb_phone(id, phone_no, customer_id)
        values(default, #{phoneNo}, #{customerId})
    insert>
    <delete id="deleteByCustomer">
        delete from tb_phone
        <where>
            customer_id = #{id}
        where>
    delete>
mapper>

前台

addCustomer.html


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>客户联系方式管理系统title>
head>
<body>
    <div style="width: 800px; margin: auto">
        <form action="/addCustomer" method="post" enctype="multipart/form-data">
            <div style="width: 500px; margin: auto; text-align: left">
                <label style="width: 200px; padding-right: 5px; text-align: right">姓名:label>
                <input type="text" name="name">
            div>
            <div style="width: 500px; margin: auto; text-align: left">
                <label style="width: 200px; padding-right: 5px; text-align: right">性别:label>
                <input type="radio" name="gender" value="">   
                <input type="radio" name="gender" value="">div>
            <div style="width: 500px; margin: auto; text-align: left">
                <label style="width: 200px; padding-right: 5px; text-align: right">年龄:label>
                <input type="text" name="age">
            div>
            <div style="width: 500px; margin: auto; text-align: left">
                <label style="width: 200px; padding-right: 5px; text-align: right">头像:label>
                <input type="file" name="uploadImg">
            div>
            <div style="width: 600px; text-align: center; margin: auto">
                <input type="submit" value="提交">     
                <input type="reset" value="重置">
            div>
        form>
    div>
body>
html>

addPhone.html


<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>客户联系方式管理系统title>
head>
<body>
    <div style="width: 800px; margin: auto; text-align: center">
        <form action="/addPhone" method="post">
            <input type="hidden" name="customerId" th:value="${customerId}">
            <div style="width: 400px; margin: auto; text-align: center">
                <label>电话:label>
                <input type="text" name="phoneNo">
            div>
            <div style="width: 800px; margin: auto; text-align: center">
                <input type="submit" value="提交">
            div>
        form>
    div>
body>
html>

error.html


<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>客户联系方式管理系统title>
head>
<body style="text-align: center; margin: auto">
    <h3>服务器忙,请稍后重试!<a href="/">返回首页a>h3>
body>
html>

index.html


<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>客户联系方式管理系统title>
head>
<body style="text-align: center">
    <h3>客户联系方式管理系统h3>
    <div style="width:800px; margin: auto; text-align: right; padding-right: 20px">
        <a th:href="@{/toAddCustomer}">新增客户a>
    div>
    
    <table style="text-align: center; margin: auto; width: 800px" border="1" cellspacing="0" cellpadding="0">
        <caption>客户列表caption>
        <thead>
        <tr>
            <th>序号th>
            <th>姓名th>
            <th>性别th>
            <th>年龄th>
            <th>头像th>
            <th>头像文件名th>
            <th>操作th>
        tr>
        thead>
        <tbody>
        <tr th:each="customer: ${customerList}">
            <th th:text="${customer.id}">th>
            <th th:text="${customer.name}">th>
            <th th:text="${customer.gender}">th>
            <th th:text="${customer.age}">th>
            <th>
                <img th:src="@{${customer.img}}" style="height:40px"/>
            th>
            <th th:text="${customer.origImg}">th>
            <th>
                <a th:href="@{/showCustomer(id=${customer.id})}">查看a>
                <a th:href="@{/removeCustomer(id=${customer.id})}">删除a>
            th>
        tr>
        <tr>
            <th colspan="7">
                <a th:if="${currentPage != 1}" th:href="@{/index(page=${currentPage-1})}">上一页a>
                <a th:if="${currentPage != totalPages}" th:href="@{/index(page=${currentPage+1})}">下一页a>
            th>
        tr>
        tbody>
    table>
body>
html>

modifyCustomer.html


<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
head>
<body>
    <div style="width:800px; margin: auto; text-align: center">
        <form action="/modifyCustomer" method="post" enctype="multipart/form-data">
            <input type="hidden" name="id" th:value="${customer.id}">
            <table cellspacing="0" cellpadding="0" border="1" style="width:100%">
                <tr>
                    <td>姓名td>
                    <td><input type="text" name="name" th:value="${customer.name}">td>
                tr>
                <tr>
                    <td>性别td>
                    <td>
                        <div th:if="${customer.gender == ''}">
                            <input type="radio" value="" name="gender" checked><input type="radio" value="" name="gender">div>
                        <div th:if="${customer.gender == ''}">
                            <input type="radio" value="" name="gender"><input type="radio" value="" name="gender" checked>div>
                    td>
                tr>
                <tr>
                    <td>年龄td>
                    <td><input type="text" name="age" th:value="${customer.age}">td>
                tr>
                <tr>
                    <td>头像td>
                    <td>
                        <img th:src="@{${customer.img}}" style="height: 50px">
                        <br>
                        <input type="file" name="uploadImg">
                    td>
                tr>
                <tr>
                    <td colspan="2">
                        <input type="submit" value="修改">   
                        <a th:href="@{/showCustomer(id=${customer.id})}">返回a>
                    td>
                tr>
            table>
        form>
    div>
body>
html>

showCustomer.html


<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>客户联系方式管理系统title>
head>
<body>
    <div style="width: 800px; margin: auto; text-align: right">
        <a th:href="@{/toModifyCustomer(id=${customer.id})}">修改客户a>
           
        <a th:href="@{/toAddPhone(customerId=${customer.id})}">新增联系方式a>
           
        <a th:href="@{/}">返回首页a>
    div>
    <div style="width: 800px; margin: auto; text-align: center">
        <table cellpadding="0" cellspacing="0" border="1" style="width:100%">
            <caption>客户详情caption>
            <tr>
                <td style="width:20%">客户信息td>
                <td>
                    <table cellpadding="0" cellspacing="0" border="1" style="width:100%">
                        <tr>
                            <td>姓名td>
                            <td th:text="${customer.name}">td>
                        tr>
                        <tr>
                            <td>性别td>
                            <td th:text="${customer.gender}">td>
                        tr>
                        <tr>
                            <td>年龄td>
                            <td th:text="${customer.age}">td>
                        tr>
                        <tr>
                            <td>头像td>
                            <td>
                                <img style="height: 50px" th:src="@{${customer.img}}">
                            td>
                        tr>
                    table>
                td>
            tr>
            <tr>
                <td style="width:20%">联系方式td>
                <td>
                    <table cellpadding="0" cellspacing="0" border="1" style="width:100%">
                        <tr th:if="${customer.phoneList.size() > 0}" th:each="phone:${customer.phoneList}">
                            <td>电话td>
                            <td th:text="${phone.phoneNo}">td>
                            <td>修改和删除td>
                        tr>
                    table>
                td>
            tr>
        table>
    div>
body>
html>

你可能感兴趣的:(Spring框架集)