1. 程式人生 > 其它 >SSM整合環境搭建(Axios非同步請求)

SSM整合環境搭建(Axios非同步請求)

SSM整合環境搭建(Axios非同步請求——前後端分離)以員工管理為例

一、maven聚合工程的搭建

1、建立父工程

2、刪除父工程中的src資料夾,右鍵工程名,新建子工程

重複上述步驟建立其他子工程,如若出現pom.xml 變灰 出現刪除線,請參考BUG- IDEA Maven pom.xml 變灰 出現刪除線

3、修改子工程employee_web,將其變成web工程

  3.1、選擇employee_web新增web

修改成功後如圖

  3.2、更改打包方式為war

二、maven的父工程做版本管理

  給相應的子工程新增依賴,以employee_common的pom.xml為例

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>employee-parent</
artifactId> <groupId>com.shangma.cn</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>employee_common</artifactId> <dependencies> <dependency> <
groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>com.aliyun</groupId> <artifactId>dysmsapi20170525</artifactId> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>com.aliyun.oss</groupId> <artifactId>aliyun-sdk-oss</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <scope>provided</scope> </dependency> </dependencies> </project>
View Code

新增依賴時,使用父工程管理依賴的版本

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.shangma.cn</groupId>
    <artifactId>employee_root</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>employee_common</module>
        <module>employee_entity</module>
        <module>employee_mapper</module>
        <module>employee_service</module>
        <module>employee_web</module>
    </modules>
    <properties>
        <lombok-version>1.18.12</lombok-version>
        <mybatis-version>3.5.4</mybatis-version>
        <mysql-version>5.1.47</mysql-version>
        <druid-version>1.1.22</druid-version>
        <spring-version>5.1.9.RELEASE</spring-version>
        <mybatis-spring-version>2.0.3</mybatis-spring-version>
        <log4j-version>1.2.17</log4j-version>
        <aspectjweaver-version>1.9.5</aspectjweaver-version>
        <jackson-databind-version>2.10.2</jackson-databind-version>
        <dysmsapi20170525-version>2.0.4</dysmsapi20170525-version>
        <spring-data-redis-version>2.1.3.RELEASE</spring-data-redis-version>
        <jedis-version>2.9.1</jedis-version>
        <slf4j-simple-version>1.7.30</slf4j-simple-version>
        <pagehelper-version>5.1.10</pagehelper-version>
        <aliyun-sdk-oss-version>3.10.2</aliyun-sdk-oss-version>
    </properties>
<!--    版本控制-->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok-version}</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>${mybatis-version}</version>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql-version}</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>${druid-version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
                <version>${spring-version}</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis-spring</artifactId>
                <version>${mybatis-spring-version}</version>
            </dependency>
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>${log4j-version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${spring-version}</version>
            </dependency>
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>${aspectjweaver-version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aop</artifactId>
                <version>${spring-version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>${spring-version}</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
                <version>${jackson-databind-version}</version>
            </dependency>
            <dependency>
                <groupId>com.aliyun</groupId>
                <artifactId>dysmsapi20170525</artifactId>
                <version>${dysmsapi20170525-version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.data</groupId>
                <artifactId>spring-data-redis</artifactId>
                <version>${spring-data-redis-version}</version>
            </dependency>
            <dependency>
                <groupId>redis.clients</groupId>
                <artifactId>jedis</artifactId>
                <version>${jedis-version}</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-simple</artifactId>
                <version>${slf4j-simple-version}</version>
            </dependency>
            <dependency>
                <groupId>com.github.pagehelper</groupId>
                <artifactId>pagehelper</artifactId>
                <version>${pagehelper-version}</version>
            </dependency>
            <dependency>
                <groupId>com.aliyun.oss</groupId>
                <artifactId>aliyun-sdk-oss</artifactId>
                <version>${aliyun-sdk-oss-version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>
View Code

三、maven的配置類加註解的方式進行SSM整合

在Mapper層和Service層配置Spring,在web層配置Spring MVC和web.xml

1、MpperConfig類(spring)

1.1、載入外部配置檔案(沒寫)

1.2、配置資料來源

1.3、配置SQLSessionFactoryBean

1.4、配置MapperScanConfiguar

package com.shangma.cn.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.github.pagehelper.PageInterceptor;
import org.apache.ibatis.logging.log4j.Log4jImpl;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MapperConfig {



    /**
     * 配置資料來源
     * @return
     */
    @Bean
    public DruidDataSource dataSource(){
        DruidDataSource dataSource =new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/mavenssm");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        return dataSource;
    }

    /**
     * 配置SQLSessionFactory,載入mybatis配置檔案
     * @return
     */
    @Bean
    public SqlSessionFactoryBean sessionFactory(){
        SqlSessionFactoryBean sessionFactory=new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource());

        return sessionFactory;
    }

    /**
     * 配置mapper掃描
     * @return
     */
    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer(){
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        mapperScannerConfigurer.setBasePackage("com.shangma.cn.mapper");
        return mapperScannerConfigurer;
    }

}
View Code

2、ServiceConfig類(spring)

2.1、配置包掃描

2.2、配置事務管理器

2.3、配置事務驅動

package com.shangma.cn.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

/**
 * @author: JAVASM
 * @className: ServiceConfig
 * @description:
 * @date: 2021/6/14 13:03
 * @version: 0.1
 * @since: jdk1.8
 */
@Configuration
@ComponentScan(basePackages = {"com.shangma.cn.service"})//包掃描
@EnableTransactionManagement//開啟事務註解驅動
public class ServiceConfig {

    @Autowired
    private DruidDataSource dataSource;

    /**
     * 事務管理器
     * @return
     */
    @Bean
    public DataSourceTransactionManager transactionManager(){
        DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
        transactionManager.setDataSource(dataSource);
        return transactionManager;
    }

}
View Code

3、WebConfig類(spring mvc)

3.1、配置包掃描

3.2、配置mvc的註解驅動

package com.shangma.cn.config;

import com.shangma.cn.interceptor.LoginInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import redis.clients.jedis.JedisPoolConfig;

/**
 * @author: JAVASM
 * @className: WebConfig
 * @description:
 * @date: 2021/6/14 13:04
 * @version: 0.1
 * @since: jdk1.8
 */
@ComponentScan(basePackages = {"com.shangma.cn.controller", "com.shangma.cn.exception"})
@EnableWebMvc//開啟MVC註解驅動
@Configuration//加入容器
public class WebConfig implements WebMvcConfigurer {


}
View Code

4、MyWebApplnitalizer類(web.xml)

4.1、載入spring的配置類

4.2、載入spring mvc的配置類

4.3、設定開啟檔案上傳

4.4、設定Filter解決亂碼問題(沒寫)

package com.shangma.cn;

import com.shangma.cn.config.MapperConfig;
import com.shangma.cn.config.ServiceConfig;
import com.shangma.cn.config.WebConfig;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.filter.DelegatingFilterProxy;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;

import javax.servlet.Filter;
import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletRegistration;

/**
 * @author: JAVASM
 * @className: MyWebAppInitializer
 * @description:
 * @date: 2021/6/14 19:16
 * @version: 0.1
 * @since: jdk1.8
 */
public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    /**
     * 載入父容器的配置類
     * @return
     */
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{MapperConfig.class, ServiceConfig.class};
    }

    /**
     * 載入子容器的配置類
     * @return
     */
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{WebConfig.class};
    }

    /**
     * 表示設定DispatcherServlet路徑
     * @return
     */
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    /**
     * 檔案上傳
     * @param registration
     */
    @Override
    protected void customizeRegistration(ServletRegistration.Dynamic registration) {
        registration.setMultipartConfig(new MultipartConfigElement(""));
    }


}
View Code

四、逆向工程生成和mybatis的日誌列印

  使用逆向工程,能夠一鍵生成entity層和mapper層的程式碼,CV大法到相應的位置

  因為使用的是配置類的方式進行SSM的整合,所以沒有了配置檔案,因此在配置SQLSessionFactoryBean時並沒有對mybatis的日誌列印進行設定

配置檔案在配置類中都有對應的寫法,匯入log4j的配置檔案,修改後的MpperConfig類如下:

package com.shangma.cn.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.github.pagehelper.PageInterceptor;
import org.apache.ibatis.logging.log4j.Log4jImpl;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author: JAVASM
 * @className: MapperConfig
 * @description:
 * @date: 2021/6/14 13:02
 * @version: 0.1
 * @since: jdk1.8
 */
@Configuration
public class MapperConfig {

    /**
     * 配置資料來源
     * @return
     */
    @Bean
    public DruidDataSource dataSource(){
        DruidDataSource dataSource =new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/mavenssm");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        return dataSource;
    }

    /**
     * 配置SQLSessionFactory,載入mybatis配置檔案
     * @return
     */
    @Bean
    public SqlSessionFactoryBean sessionFactory(){
        SqlSessionFactoryBean sessionFactory=new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource());
        //設定mybatis的日誌
        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        configuration.setLogImpl(Log4jImpl.class);
        sessionFactory.setConfiguration(configuration);

        return sessionFactory;
    }

    /**
     * 配置mapper掃描
     * @return
     */
    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer(){
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        mapperScannerConfigurer.setBasePackage("com.shangma.cn.mapper");
        return mapperScannerConfigurer;
    }

}
View Code

五、傳送手機驗證碼

package com.shangma.cn.controller;

import com.shangma.cn.common.AxiosResult;
import com.shangma.cn.common.AxiosStatus;
import com.shangma.cn.entity.Employee;
import com.shangma.cn.exception.MyLoginException;
import com.shangma.cn.factory.AsyncFactory;
import com.shangma.cn.pool.AsyncManager;
import com.shangma.cn.service.EmployeeService;
import com.shangma.cn.utils.RandomCodeUtil;
import com.shangma.cn.utils.SmsUtil;
import com.shangma.cn.utils.UploadUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpSession;
import javax.servlet.http.Part;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author: JAVASM
 * @className: CommonController
 * @description:
 * @date: 2021/6/14 19:15
 * @version: 0.1
 * @since: jdk1.8
 */
@RestController
@RequestMapping("common")
public class CommonController {

    @Autowired
    private EmployeeService employeeService;

    @RequestMapping("getCode/{phone}")
    public String getCode(@PathVariable String phone){
        System.out.println(phone);
        Employee employee = employeeService.findByPhone(phone);
        System.out.println(employee);
        if (employee==null) {
            return "NOT_Employee";
        }
        //生成驗證碼
        String code = RandomCodeUtil.munCode();
        //傳送簡訊,單獨的Java不能實現傳送手機驗證碼
        //所以需要依賴於第三方的SDK,本案例使用的是阿里雲所提供的服務
                SmsUtil.sendSms(phone,code);
        return "success";
    }
}
View Code

六、使用非同步執行緒池傳送手機驗證碼

  傳送簡訊是一個很耗時間的操作,非常容易造成執行緒的阻塞,所以我們可以把傳送這個操作發到子執行緒中,並且傳送驗證碼這個操作過程複雜

需要 一定的程式碼量,而且耦合度高、使用的次數多,所以我們可以使用工廠模式降低程式碼的重複和解耦。

  還有就是返回給前端的值,一般都會返回json形式的字串,並且在前端用於條件判斷的多是數字(狀態碼),因此,我們先設定好返回值類,定義好返回值(列舉類)

定義狀態碼

View Code

定義返回值類

package com.shangma.cn.common;

import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;

@Data
public class AxiosResult<T> {

    private int status;
    private String message;
    private T data;

    /**
     * 私有化建構函式
     */
    private AxiosResult() {

    }

    /**
     * 返回狀態碼不帶資料
     * @param <T>
     * @return
     */
    public static <T> AxiosResult<T> success() {
        return setData(AxiosStatus.OK, null);
    }

    /**
     * 返回狀態碼帶資料
     * @param t
     * @param <T>
     * @return
     */
    public static <T> AxiosResult<T> success(T t) {
        return setData(AxiosStatus.OK, t);
    }

    /**
     * 返回別的型別的狀態碼不帶資料
     * @param axiosStatus
     * @param <T>
     * @return
     */
    public static <T> AxiosResult<T> success(AxiosStatus axiosStatus) {
        return setData(axiosStatus, null);
    }

    /**
     * 返回別的型別的狀態碼帶資料
     * @param axiosStatus
     * @param t
     * @param <T>
     * @return
     */
    public static <T> AxiosResult<T> success(AxiosStatus axiosStatus, T t) {
        return setData(axiosStatus, t);
    }

    public static <T> AxiosResult<T> error() {
        return setData(AxiosStatus.ERROR, null);
    }

    public static <T> AxiosResult<T> error(AxiosStatus axiosStatus) {
        return setData(axiosStatus, null);
    }

    public static <T> AxiosResult<T> error(AxiosStatus axiosStatus, T t) {
        return setData(axiosStatus, t);
    }

    public static <T> AxiosResult<T> setData(AxiosStatus axiosStatus, T t) {
        AxiosResult<T> tAxiosResult = new AxiosResult<>();
        tAxiosResult.setStatus(axiosStatus.getStatus());
        tAxiosResult.setMessage(axiosStatus.getMessage());
        tAxiosResult.setData(t);
        return tAxiosResult;
    }
}
View Code

執行緒池

package com.shangma.cn.pool;

import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 使用單例模式設計非同步執行緒池
 */
public class AsyncManager {

    private static ScheduledThreadPoolExecutor scheduledThreadPoolExecutor;

    private static AsyncManager asyncManager;

    private AsyncManager (){
        scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(50);
    }

    /**
     * 建立單例物件
     * @return
     */
    public static AsyncManager getInstance(){
        if (asyncManager==null) {
            return new AsyncManager();
        }
        return asyncManager;
    }


    /**
     * 使用執行緒池執行內容
     * 這種執行沒有延遲時間
     *
     * @param runnable
     */
    public void execute(Runnable runnable) {
        scheduledThreadPoolExecutor.execute(runnable);
    }

    /**
     * 使用執行緒執行程式碼
     * schedule方法可以延遲一段時間後再去執行Runnable中的程式碼
     * @param runnable 要執行的程式碼
     * @param seconds 延遲的時間
     */
    public void schedule(Runnable runnable,long seconds){
        scheduledThreadPoolExecutor.schedule(runnable,seconds, TimeUnit.SECONDS);
    }

    /**
     * 關閉執行緒池
     */
    public void release(){
        scheduledThreadPoolExecutor.shutdownNow();
    }
}
View Code

工廠類

package com.shangma.cn.factory;

import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.teaopenapi.models.Config;
import com.shangma.cn.utils.SmsUtil;
import lombok.extern.log4j.Log4j;

import java.io.IOException;
import java.util.Properties;

/**
 * 非同步工廠(使用工廠模式完成功能)
 * 1、傳送手機驗證碼
 */
@Log4j
public class AsyncFactory {

    private static Properties properties;

    static {
        //載入配置檔案
        try {
            properties = new Properties();
            properties.load(SmsUtil.class.getClassLoader().getResourceAsStream("aliyun.properties"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     *
     * @param phone
     * @param code
     * @return
     */
    public static Runnable sendPhoneCode(String phone, String code){
        Config config = new Config()
                // 您的AccessKey ID
                .setAccessKeyId(properties.getProperty("aliyun.accessKeyId"))
                // 您的AccessKey Secret
                .setAccessKeySecret(properties.getProperty("aliyun.accessKeySecret"));
        // 訪問的域名
        config.endpoint = properties.getProperty("aliyun.endpoint");
        try {
            Client client = new Client(config);
            SendSmsRequest sendSmsRequest = new SendSmsRequest()
                    .setPhoneNumbers(phone)
                    .setSignName(properties.getProperty("aliyun.signName"))
                    .setTemplateCode(properties.getProperty("aliyun.templateCode"))
                    .setTemplateParam("{\"code\":" + code + "}");
            // 複製程式碼執行請自行列印 API 的返回值
            Runnable runnable = ()->{
                //當前執行緒名
                System.out.println("當前執行緒為:"+Thread.currentThread().getName());
                try {
                    client.sendSms(sendSmsRequest);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            };
            return runnable;
        } catch (Exception e) {
            log.error(phone + "+手機驗證碼傳送失敗:" + e.getMessage());
            e.printStackTrace();
        }
        return ()->{};
    }

}
View Code

修改後的傳送手機驗證碼

    @RequestMapping("getCode/{phone}")
    public AxiosResult<Void> getCode(@PathVariable String phone){
        System.out.println(phone);
        Employee employee = employeeService.findByPhone(phone);
        System.out.println(employee);
        if (employee==null) {
            return AxiosResult.error();
        }
        //生成驗證碼
        String code = String.valueOf((int) (Math.random() * (999999 - 100000 + 1) + 100000));
        //傳送簡訊,放入子執行緒中
        AsyncManager.getInstance().schedule(AsyncFactory.sendPhoneCode(phone,code),2L);
        return AxiosResult.success();
    }
View Code

七、SpringDataRedis的使用

  在進行登入驗證的時候,我們不僅需要從前端傳遞過來的驗證碼,還需要我們自己生成的驗證碼進行對照,對於驗證碼我們不可能永久儲存,若是放到MySQL中,不僅是存取麻煩,還有對資料庫的大量操作會造成資料庫的崩潰,這時就需要用到對臨時資料的儲存Redis資料庫。

  在spring mvc中對Redis的操作有兩種,使用RedisTemplate操作Redis和使用StringRedisTemplate操作Redis,這兩種無論是哪一種都需要Redis工廠的支援。

在WebConfig類中配置

package com.shangma.cn.config;

import com.shangma.cn.interceptor.LoginInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import redis.clients.jedis.JedisPoolConfig;


@ComponentScan(basePackages = {"com.shangma.cn.controller", "com.shangma.cn.exception"})
@EnableWebMvc//開啟MVC註解驅動
@Configuration//加入容器
public class WebConfig implements WebMvcConfigurer {

    /**
     * Redis工廠
     * 如果是本機,可以什麼都不配置
     * @return
     */
    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
        return jedisConnectionFactory;
    }

    /**
     * 使用RedisTemplate操作Redis
     * @return
     */
//    @Bean
//    public RedisTemplate redisTemplate(){
//        RedisTemplate redisTemplate = new RedisTemplate();
//        redisTemplate.setConnectionFactory(redisConnectionFactory());
//        return redisTemplate;
//    }

    /**
     * 使用StringRedisTemplate操作Redis
     * @return
     */
    @Bean
    public StringRedisTemplate stringRedisTemplate() {
        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
        stringRedisTemplate.setConnectionFactory(redisConnectionFactory());
        return stringRedisTemplate;
    }

}
View Code

登入驗證

//在傳送驗證碼方法中新增
//在生成驗證碼之後   
//生成驗證碼,存入Redis,設定2分鐘自動銷燬
   stringRedisTemplate.opsForValue().set(phone,code,2, TimeUnit.MINUTES);

    /**
     * 登入驗證
     * @param map
     * @param session
     * @return
     */
    @RequestMapping("doLogin")
    public AxiosResult<Void> doLogin(@RequestBody Map<String,String>map, HttpSession session){
        System.out.println(map);
        String phone = map.get("phone");
        String code = map.get("code");
        String s = stringRedisTemplate.opsForValue().get(phone);
        if (s.equals(code)) {
            Employee employee = employeeService.findByPhone(phone);
            //將登陸資訊放入session
            session.setAttribute("user",employee);
            //清除
            stringRedisTemplate.delete(phone);
            System.out.println(AxiosResult.success().getData());
            return AxiosResult.success();
        }
         return AxiosResult.error();
    }
View Code

八、Redis的連線池

在WebConfig類中配製

package com.shangma.cn.config;

import com.shangma.cn.interceptor.LoginInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import redis.clients.jedis.JedisPoolConfig;

/**
 * @author: JAVASM
 * @className: WebConfig
 * @description:
 * @date: 2021/6/14 13:04
 * @version: 0.1
 * @since: jdk1.8
 */
@ComponentScan(basePackages = {"com.shangma.cn.controller", "com.shangma.cn.exception"})
@EnableWebMvc//開啟MVC註解驅動
@Configuration//加入容器
public class WebConfig implements WebMvcConfigurer {

    /**
     * jedis執行緒池
     * @return
     */
    @Bean
    public JedisPoolConfig jedisPoolConfig(){
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(50);
        jedisPoolConfig.setMaxIdle(50);
        return jedisPoolConfig;
    }

    /**
     * Redis工廠
     * 如果是本機,可以什麼都不配置
     * @return
     */
    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(jedisPoolConfig());
        return jedisConnectionFactory;
    }

    /**
     * 使用RedisTemplate操作Redis
     * @return
     */
//    @Bean
//    public RedisTemplate redisTemplate(){
//        RedisTemplate redisTemplate = new RedisTemplate();
//        redisTemplate.setConnectionFactory(redisConnectionFactory());
//        return redisTemplate;
//    }

    /**
     * 使用StringRedisTemplate操作Redis
     * @return
     */
    @Bean
    public StringRedisTemplate stringRedisTemplate() {
        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
        stringRedisTemplate.setConnectionFactory(redisConnectionFactory());
        return stringRedisTemplate;
    }


}
View Code

九、使用異常處理的方式來解決不滿足條件的問題

  異常可以阻止程式的執行,我們通過自定異常,在捕捉處理這個異常,就能達到解決不滿足條件時程式的執行問題

定義異常

package com.shangma.cn.exception;

import com.shangma.cn.common.AxiosStatus;
import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class MyLoginException extends RuntimeException{

    private AxiosStatus axiosStatus;

}
View Code

捕捉處理異常

package com.shangma.cn.exception;

import com.shangma.cn.common.AxiosResult;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;


@RestControllerAdvice
public class MyHandler {

    @ExceptionHandler(MyLoginException.class)
    public AxiosResult<Void> myHandler(MyLoginException e){
        return AxiosResult.error(e.getAxiosStatus());
    }
}
View Code

完整版的登入

package com.shangma.cn.controller;

import com.shangma.cn.common.AxiosResult;
import com.shangma.cn.common.AxiosStatus;
import com.shangma.cn.entity.Employee;
import com.shangma.cn.exception.MyLoginException;
import com.shangma.cn.factory.AsyncFactory;
import com.shangma.cn.pool.AsyncManager;
import com.shangma.cn.service.EmployeeService;
import com.shangma.cn.utils.RandomCodeUtil;
import com.shangma.cn.utils.SmsUtil;
import com.shangma.cn.utils.UploadUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpSession;
import javax.servlet.http.Part;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author: JAVASM
 * @className: CommonController
 * @description:
 * @date: 2021/6/14 19:15
 * @version: 0.1
 * @since: jdk1.8
 */
@RestController
@RequestMapping("common")
public class CommonController {

    @Autowired
    private EmployeeService employeeService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 傳送驗證碼
     * @param phone
     * @return
     */
    @RequestMapping("getCode/{phone}")
    public AxiosResult<Void> getCode(@PathVariable String phone){
        System.out.println(phone);
        Employee employee = employeeService.findByPhone(phone);
        System.out.println(employee);
        if (employee==null) {
            throw new MyLoginException(AxiosStatus.PHONE_NOT_FOUND);
        }
        //生成驗證碼,存入Redis,設定2分鐘自動銷燬
        String code = RandomCodeUtil.munCode();
        stringRedisTemplate.opsForValue().set(phone,code,2, TimeUnit.MINUTES);
        //傳送簡訊,放入子執行緒中
        AsyncManager.getInstance().schedule(AsyncFactory.sendPhoneCode(phone,code),2L);
        return AxiosResult.success();
    }

    /**
     * 登入驗證
     * @param map
     * @param session
     * @return
     */
    @RequestMapping("doLogin")
    public AxiosResult<Void> doLogin(@RequestBody Map<String,String>map, HttpSession session){
        System.out.println(map);
        String phone = map.get("phone");
        String code = map.get("code");
        String s = stringRedisTemplate.opsForValue().get(phone);
        if (s.equals(code)) {
            Employee employee = employeeService.findByPhone(phone);
            //將登陸資訊放入session
            session.setAttribute("user",employee);
            //清除
            stringRedisTemplate.delete(phone);
            System.out.println(AxiosResult.success().getData());
            return AxiosResult.success();
        }
        throw new MyLoginException(AxiosStatus.CODE_CHECK_ERROR);
    }
}
View Code

十、手動列印日誌

  在專案釋出後沒有控制檯讓我們檢視BUG,此時我們就需要記錄程式的報錯資訊

  一般我們使用log4j來記錄錯誤資訊

先匯入lombok的jar,在需要記錄日誌的類上加上@Log4j就可以直接使用了

例如

                try {
                    client.sendSms(sendSmsRequest);
                } catch (Exception e) {
                    e.printStackTrace();
                    log.error(phone + "+手機驗證碼傳送失敗:" + e.getMessage());
                }

十一、跨域問題的解決以及登入攔截的實現

  參考前後端分離實現登陸攔截

十二、分頁查詢以及日期時區問題的解決

前端部分頁面

                    <div class="box-body">
                        <table id="example2" class="table table-bordered table-hover">
                            <thead>
                            <tr>
                                <th><input type="checkbox" @change="chooseAll"/>全選</th>
                                <th>id</th>
                                <th>頭像</th>
                                <th>姓名</th>
                                <th>手機號</th>
                                <th>工資</th>
                                <th>地址</th>
                                <th>入職時間</th>
                                <th>操作</th>
                            </tr>
                            </thead>
                            <tbody ref="table_Body">
                            <tr v-for="(item,index) in tableData" :key="index">
                                <td><input type="checkbox" class="check_td"
                                           @click="chooseDeleteItem(item.employeeId,$event)"></td>
                                <td class="id_td">{{item.employeeId}}</td>
                                <td><img :src="item.employeeAvatar" width="35px" height="35px"></td>
                                <td>{{item.employeeName}}</td>
                                <td>{{item.employeePhone}}</td>
                                <td>{{item.employeeSalary}}</td>
                                <td>{{item.employeeAddress}}</td>
                                <td>{{item.employeeTime}}</td>
                                <td>
                                    <button class="btn btn-sm  btn-info" @click="findById(item.employeeId)"
                                            data-toggle="modal" data-target="#editDialog">
                                        編輯
                                    </button>
                                    <button class="btn btn-sm  btn-warning" @click="doDeleteBtn(item.employeeId)"
                                            data-toggle="modal" data-target="#delModal">
                                        刪除
                                    </button>
                                </td>
                            </tr>
                            </tbody>

                        </table>
                    </div>
View Code

前端部分JS程式碼

let vue = new Vue({
    el: "#app",
    data: {
        tableData: [],
        currentPage: 1,
        pageSize: 5,
        total: 0,
        imgUrl: '',
        formData: {},
        deleteIds: []
    },
    created() {
        this.findPage();
    },
    methods: {
        //查詢全部
        findAll() {
            myaxios.get(`employee/findAll`).then(response => {
                let {data} = response;
                this.tableData = data;
            })
        },
        //分頁查詢
        findPage() {
            myaxios.get(`employee/findPage?currentPage=${this.currentPage}&pageSize=${this.pageSize}`).then(response => {
                let {total, list} = response;
                this.total = total;
                this.tableData = list;
            })
        },
        //分頁回掉函式
        pageChange(page) {
            this.currentPage = page;
            var elementsByClassName = this.$refs.table_Body.getElementsByClassName("check_td");
            for (let i = 0; i < elementsByClassName.length; i++) {
                elementsByClassName[i].checked=false;
            }
            this.findPage();
        }
}
View Code

後臺

Service層

    @Override
    public List<Employee> findAll() {
        List<Employee> employees = employeeMapper.selectByExample(null);
        return employees;
    }

    @Override
    public PageBean<Employee> findPage() {
        List<Employee> employees = employeeMapper.selectByExample(null);
        PageInfo<Employee> pageInfo = new PageInfo<>(employees);
        return PageBean.init(pageInfo.getTotal(),employees);
    }
View Code

Controller層

    /**
     * 查詢全部
     *
     * @return
     */
    @GetMapping("findAll")
    public AxiosResult<List<Employee>> findAll() {
        List<Employee> all = employeeService.findAll();
        return AxiosResult.success(all);
    }

    /**
     * 分頁查詢
     *
     * @param currentPage 當前頁
     * @param pageSize    每一頁大小
     * @return
     */
    @GetMapping("findPage")
    public AxiosResult<PageBean<Employee>> findPage(int currentPage, int pageSize) {
        //開啟分頁
        PageHelper.startPage(currentPage, pageSize);
        PageBean<Employee> all = employeeService.findPage();
        return AxiosResult.success(all);
    }
View Code

這裡我們查詢後,會發現時間會和資料庫中的不同,這是因為資料庫的DateTime型別沒有時區(time zone)資訊,因此,存入的是本地時間,並且丟掉了時區資訊。如果你把資料庫伺服器的時區改了,或者把應用伺服器的時區改了,讀出來的日期和時間就是錯誤的。所以這裡我們要上設定時區,

在實體類相應的時間屬性上加上註解

@JsonFormat(pattern = "yyyy-MM-dd",timezone = "CMT+8")

因為是maven工程,在依賴了相關Jackson的jar後,會自動幫我們依賴

十三、檔案上傳——使用阿里雲物件儲存

前端部分JS程式碼

        //選擇圖片上傳
        chooseAvatar(e) {
            let file = e.target.files[0];
            let formData = new FormData();
            formData.append("avatar", file);
            myaxios.post("common/upload/", formData, {headers: {"Content-Type": "multipart/form-data"}})
                .then(response => {
                    // console.log(response)
                    this.imgUrl = response;
                    this.formData.employeeAvatar = response;
                })
        }
View Code

工具類(需要依賴阿里雲相關jar)

package com.shangma.cn.utils;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
 * @author: JAVASM
 * @className: UploadUtil
 * @description:
 * @date: 2021/6/15 21:34
 * @version: 0.1
 * @since: jdk1.8
 */
public class UploadUtil {

    private static Properties properties;

    static {
        //載入配置檔案
        try {
            properties = new Properties();
            properties.load(SmsUtil.class.getClassLoader().getResourceAsStream("aliyun-oss.properties"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 檔案上傳
     * @param fileName 檔名
     * @param in 流
     * @return
     */
    public static String upload(String fileName, InputStream in) {
        String endpoint = properties.getProperty("aliyun-oss.endpoint");
        String accessKeyId = properties.getProperty("aliyun-oss.accessKeyId");
        String accessKeySecret = properties.getProperty("aliyun-oss.accessKeySecret");
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        //第一引數: 表示bucket名稱
        //第二個引數: 檔名稱 攜帶字尾
        ossClient.putObject(properties.getProperty("aliyun-oss.bucketName"), fileName, in);
        ossClient.shutdown();
        String url = properties.getProperty("aliyun-oss.imgUrl") + fileName;
        return url;
    }
}
View Code

Controller層

    /**
     * 上傳檔案
     * @param avatar
     * @return
     * @throws IOException
     */
    @RequestMapping("upload")
    public AxiosResult<String> upload(@RequestPart Part avatar) throws IOException {
        //重新命名
        // TODO: 2021/6/15 不能上傳檔案
        System.out.println(avatar);
        String fileName = System.nanoTime() + "." + StringUtils.getFilenameExtension(avatar.getSubmittedFileName());
        String url = UploadUtil.upload(fileName, avatar.getInputStream());
        return AxiosResult.success(url);
    }
View Code

十四、新增員工資訊

前端頁面

                    <div class="box-header">
                        <div class="form-group form-inline">
                            <div class="btn-group">
                                <button type="button" class="btn  btn-danger" title="新建" @click="formData={},imgUrl=''"
                                        data-toggle="modal"
                                        data-target="#editDialog">新建
                                </button>
                                <button type="button" class="btn  btn-success"
                                        data-toggle="modal"
                                        data-target="#delModal">批量刪除
                                </button>
                                <button type="button" class="btn  btn-primary">匯入</button>
                                <button type="button" class="btn  btn-info">匯出</button>
                            </div>
                        </div>
                    </div>





模態框
    <!--新建 編輯彈框-->
    <div class="modal fade" id="editDialog">
        <div class="modal-dialog modal-lg edit-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h4 class="modal-title">員工操作</h4>
                    <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="card-body">
                        <div class="form-group row">
                            <label class="col-sm-2 col-form-label">員工姓名:</label>
                            <div class="col-sm-10">
                                <input type="text" v-model="formData.employeeName" class="form-control"
                                       placeholder="請輸入員工姓名">
                            </div>
                        </div>
                        <div class=" form-group row">
                            <label class="col-sm-2 col-form-label">員工手機:</label>
                            <div class="col-sm-10">
                                <input type="text" v-model="formData.employeePhone" class="form-control"
                                       placeholder="請輸入員工手機"/>
                            </div>
                        </div>

                        <div class=" form-group row">
                            <label class="col-sm-2 col-form-label">員工工資:</label>
                            <div class="col-sm-10">
                                <input type="text" v-model="formData.employeeSalary" class="form-control"
                                       placeholder="請輸入員工工資"/>
                            </div>
                        </div>


                        <div class=" form-group row">
                            <label class="col-sm-2 col-form-label">員工地址:</label>
                            <div class="col-sm-10">
                                <input type="text" v-model="formData.employeeAddress" class="form-control"
                                       placeholder="請輸入員工地址"/>
                            </div>
                        </div>


                        <div class=" form-group row">
                            <label class="col-sm-2 col-form-label">入職時間:</label>
                            <div class="col-sm-10">
                                <input id="date" v-model="formData.employeeTime" type="date" class="form-control"/>
                            </div>
                        </div>
                        <div class=" form-group row">
                            <label class="col-sm-2 col-form-label">員工頭像</label>
                            <div class="col-sm-10">
                                <label class="btn btn-primary">
                                    <input type="file" @change="chooseAvatar" style="display:none;" id="avater">
                                    上傳圖片
                                </label>
                                <img :src="imgUrl" alt="" width="100px" height="100px"
                                     style="border: 1px solid #ccc; margin-left: 100px">
                            </div>
                        </div>
                    </div>

                </div>
                <div class="modal-footer ">
                    <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
                    <button type="button" class="btn btn-success" @click="addOrEdit" data-dismiss="modal">確定</button>
                </div>
            </div>
        </div>
    </div>
View Code

前端JS

        //新增或修改確認按鈕
        addOrEdit() {

            if (this.formData.employeeId) {
                //修改
            } else {
                //新增
                //如果沒有圖片,新增預設圖片
                this.formData.employeePassword='123456';
                if (this.formData.employeeAvatar) {
                    myaxios.post(`employee/addEmployee/`, this.formData)
                        .then(response => {
                            this.findPage();
                        });
                } else {
                    this.formData.employeeAvatar = 'https://shangmasanshiqi.oss-cn-beijing.aliyuncs.com/282285958269457.gif';
                    myaxios.post(`employee/addEmployee/`, this.formData)
                        .then(response => {
                            this.findPage();
                        });
                }
            }
        }
View Code

Service

    @Override
    public void addEmployee(Employee employee) {
        employeeMapper.insert(employee);
    }

Controller

    /**
     * 新增
     * @param employee
     * @return
     */
    @PostMapping("addEmployee")
    public AxiosResult<Void> addEmployee(@RequestBody Employee employee) {
        employeeService.addEmployee(employee);
        return AxiosResult.success();
    }

十五、改造前端Axios以及解決返回值的問題

自定義Axios,可以解決重複寫基本路徑、設定是否攜帶cookie,設定請求時間,設定攔截器(請求之前攔截,返回值響應攔截),

let myaxios = axios.create({
    //設定基礎路徑
    baseURL:'http://localhost:8080/',
    //設定攜帶cookie
    withCredentials:true,
    //設定請求時間
    timeout:5000
});

// 請求之前攔截
myaxios.interceptors.request.use(function (config) {
    // config.baseURL='http://localhost:8080/';
    return config;
}, function (error) {
    return Promise.reject(error);
});

// 響應攔截器
myaxios.interceptors.response.use(function (response) {
    console.log(response);
    let{status,massage,data}=response.data;
    if (status==2000){
        //console.log(data)
        return data;
    }
    if (status==4004){
        alert("登入過期,請重新登入")
        location.replace("./login.html");
    }
    else {
        console.log(massage);
        //阻止程式碼向下執行
        return Promise.reject(false);
    }
}, function (error) {
    return Promise.reject(error);
});
View Code

當我們給前端返回資料的時候,data有可能是null,這就有可能在前端產生錯誤,因此,我們需要在返回資料時進行一次判斷,返回不為空的值

我們在返回值進行json序列化的時候,只序列化有資料的,在返回值類AxiosResult上加@JsonInclude(JsonInclude.Include.NON_NULL)就可以進行過濾。

十六、修改員工資訊

前端頁面同查詢和新增

前端JS

        //新增或修改確認按鈕
        addOrEdit() {

            if (this.formData.employeeId) {
                //修改
                myaxios.put(`employee/updateEmployee/`, this.formData).then(() => {
                    this.findPage();
                })
            } else {
                //新增
                //如果沒有圖片,新增預設圖片
                this.formData.employeePassword='123456';
                if (this.formData.employeeAvatar) {
                    myaxios.post(`employee/addEmployee/`, this.formData)
                        .then(response => {
                            this.findPage();
                        });
                } else {
                    this.formData.employeeAvatar = 'https://shangmasanshiqi.oss-cn-beijing.aliyuncs.com/282285958269457.gif';
                    myaxios.post(`employee/addEmployee/`, this.formData)
                        .then(response => {
                            this.findPage();
                        });
                }
            }
        },
        //修改按鈕點選事件
        findById(id) {
            myaxios.get(`employee/findById/${id}`).then(response => {
                this.formData = response;
                //沒有圖片新增預設圖片,
                if (response.employeeAvatar) {
                    this.imgUrl = response.employeeAvatar;
                } else {
                    this.imgUrl = 'https://shangmasanshiqi.oss-cn-beijing.aliyuncs.com/282285958269457.gif';
                    this.formData.employeeAvatar = 'https://shangmasanshiqi.oss-cn-beijing.aliyuncs.com/282285958269457.gif';
                }
            })
        }
View Code

Service

    @Override
    public Employee findById(Integer id) {
        Employee employee = employeeMapper.selectByPrimaryKey(id);
        return employee;
    }

    @Override
    public void update(Employee employee) {
        employeeMapper.updateByPrimaryKey(employee);
    }
View Code

Controller

    /**
     * 根據id查詢資訊
     * @param id
     * @return
     */
    @GetMapping("findById/{id}")
    public AxiosResult<Employee> findById(@PathVariable Integer id) {
        Employee employee = employeeService.findById(id);
        return AxiosResult.success(employee);
    }

    /**
     * 修改
     * @param employee
     * @return
     */
    @RequestMapping("updateEmployee")
    public AxiosResult<Void> updateEmployee(@RequestBody Employee employee){
        employeeService.update(employee);
        return AxiosResult.success();
    }
View Code

十七、刪除和批量刪除員工資訊

前端頁面同修改,多了一個模態框

    <!--刪除彈框-->
    <div class="modal fade" id="delModal">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h4 class="modal-title">溫馨提示</h4>
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
                <div class="modal-body">
                    你確定要刪除嗎?
                </div>
                <div class="modal-footer ">
                    <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
                    <button type="button" @click="delBtn" class="btn btn-success delSure" data-dismiss="modal">確定
                    </button>
                </div>
            </div>

        </div>

    </div>
View Code

前端JS

        //獲取刪除元素
        chooseDeleteItem(id, e) {
            if (e.target.checked) {
                this.deleteIds.push(id);
            } else {
                this.deleteIds.splice(this.deleteIds.findIndex(item => item == id, 1))
            }
        },
        //點選刪除按鈕
        doDeleteBtn(id) {
            //獲取checkbox的值
            var elementsByClassName = this.$refs.table_Body.getElementsByClassName("check_td");
            for (let i = 0; i < elementsByClassName.length; i++) {
                elementsByClassName[i].checked=false;
            }
            this.deleteIds=[];
            this.deleteIds.push(id);
        },
        //刪除確認按鈕
        delBtn(){
            myaxios.delete(`employee/deleteByIds/${this.deleteIds}`).then(()=>{
                console.log(this.tableData.length)
                if (this.tableData.length==1){
                    if (this.currentPage>1){
                        this.currentPage=this.currentPage-1
                    }
                }
                this.findPage()
            })
        },
        //全選
        chooseAll(e){
            if (e.target.checked) {
                var elementsByClassName = this.$refs.table_Body.getElementsByClassName("check_td");
                for (let i = 0; i < elementsByClassName.length; i++) {
                    elementsByClassName[i].checked=true;
                }
                //清空陣列
                this.deleteIds=[];
                //新增到陣列
                var elementsByClassName1 = this.$refs.table_Body.getElementsByClassName("id_td");
                for (let i = 0; i < elementsByClassName1.length; i++) {
                    this.deleteIds.push(elementsByClassName1[i].outerText);
                }
                console.log(this.deleteIds)
            } else {
                var elementsByClassName = this.$refs.table_Body.getElementsByClassName("check_td");
                for (let i = 0; i < elementsByClassName.length; i++) {
                    elementsByClassName[i].checked=false;
                }
                //清空陣列
                this.deleteIds=[];
            }
        }
View Code

Service

    @Override
    public void deleteByIds(List<Integer> ids) {
        EmployeeExample employeeExample = new EmployeeExample();
        EmployeeExample.Criteria criteria = employeeExample.createCriteria();
        criteria.andEmployeeIdIn(ids);
        employeeMapper.deleteByExample(employeeExample);
    }

Controller

    @DeleteMapping("deleteByIds/{ids}")
    public AxiosResult<Void> deleteByIds(@PathVariable List<Integer> ids){
        employeeService.deleteByIds(ids);
        return AxiosResult.success();
    }

十八、匯出和匯入表格