天天看點

mybatis攔截器(一)

實作一個對sql指定字段進行加密解密的處理,使用mybatis的攔截器,完全使用spring boot實作,沒有使用xml去配置攔截器

mybatis核心對象

從MyBatis代碼實作的角度來看,MyBatis的主要的核心部件有以下幾個:

  • SqlSession            作為MyBatis工作的主要頂層API,表示和資料庫互動的會話,完成必要資料庫增删改查功能
  • Executor              MyBatis執行器,是MyBatis 排程的核心,負責SQL語句的生成和查詢緩存的維護
  • StatementHandler   封裝了JDBC Statement操作,負責對JDBC statement 的操作,如設定參數、将Statement結果集轉換成List集合。
  • ParameterHandler   負責對使用者傳遞的參數轉換成JDBC Statement 所需要的參數,
  • ResultSetHandler    負責将JDBC傳回的ResultSet結果集對象轉換成List類型的集合;
  • TypeHandler          負責java資料類型和jdbc資料類型之間的映射和轉換
  • MappedStatement   MappedStatement維護了一條<select|update|delete|insert>節點的封裝, 
  • SqlSource            負責根據使用者傳遞的parameterObject,動态地生成SQL語句,将資訊封裝到BoundSql對象中,并傳回
  • BoundSql             表示動态生成的SQL語句以及相應的參數資訊
  • Configuration        MyBatis所有的配置資訊都維持在Configuration對象之中。
mybatis攔截器(一)
mybatis攔截器(一)

 對于攔截器Mybatis為我們提供了一個Interceptor接口,通過實作該接口就可以定義我們自己的攔截器。我們先來看一下這個接口的定義:

package org.apache.ibatis.plugin;
 
import java.util.Properties;
 
public interface Interceptor {
 
  Object intercept(Invocation invocation) throws Throwable;
 
  Object plugin(Object target);
 
  void setProperties(Properties properties);
 
}
 org.apache.ibatis.plugin;
 
import java.util.Properties;
 
public interface Interceptor {
 
  Object intercept(Invocation invocation) throws Throwable;
 
  Object plugin(Object target);
 
  void setProperties(Properties properties);
 
}
           

  對于plugin方法而言,其實Mybatis已經為我們提供了一個實作。Mybatis中有一個叫做Plugin的類,裡面有一個靜态方法wrap(Object target,Interceptor interceptor),通過該方法可以決定要傳回的對象是目标對象還是對應的代理

對于實作自己的Interceptor而言有兩個很重要的注解,一個是@Intercepts,其值是一個@Signature數組。@Intercepts用于表明目前的對象是一個Interceptor,而@Signature則表明要攔截的接口、方法以及對應的參數類型

pom依賴:

<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.hf</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>mybatisplugin</name>
    <description>mybatis攔截器使用</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- mysql驅動包 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.17</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.9</version>
        </dependency>

        <!--mybatis依賴-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.56</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>


    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
           

自定義兩個注解,用來限定加密解密處理的,分别作用在類和字段上面

package com.hf.demo.annotation;

import java.lang.annotation.*;

/**
 * @Description: 需要加解密的類注解
 * @Date: 2019/6/26
 * @Author: wm yu
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Inherited
@Documented
public @interface EncryptDecryptClass {
}
           
package com.hf.demo.annotation;

import java.lang.annotation.*;

/**
 * @Description: 加密字段注解
 * @Date: 2019/6/26
 * @Author: wm yu
 */
@Documented
@Inherited
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface EncryptDecryptField {
}
           

貼出application.yml的配置:

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://localhost:3306/mogu_blog?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true
      username: root
      password: root
      initialize: true
## 該配置節點為獨立的節點,有很多同學容易将這個配置放在spring的節點下,導緻配置無法被識别
mybatis:
  mapper-locations: classpath:mapper/*.xml  #注意:一定要對應mapper映射xml檔案的所在路徑
  type-aliases-package: com.hf.demo.entity  # 注意:對應實體類的路徑
   #mybatis.configuration.map-underscore-to-camel-case=true開啟駝峰命名識别
  configuration:
    map-underscore-to-camel-case: true
server:
  port: 9090


logging:
  level:
    com.hf.demo.mapper: debug

           

啟動類:

package com.hf.demo;

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


@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@MapperScan("com.hf.demo.mapper")
public class MybatispluginApplication {

    public static void main(String[] args) {
        SpringApplication.run(MybatispluginApplication.class, args);
    }

}
           

下面是重點(mybatis攔截器的使用):  因為沒有自定義攔截器的配置,所有就沒有寫配置類,直接使用@Component來注冊了

建立sql入參攔截:  

package com.hf.demo.interceptor;

import com.alibaba.fastjson.JSON;
import com.hf.demo.annotation.EncryptDecryptClass;
import com.hf.demo.utils.EncryptDecryptUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.plugin.*;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.sql.PreparedStatement;
import java.util.Objects;
import java.util.Properties;

/**
 * @Description: 攔截mybatis參數攔截器
 * @Date: 2019/6/26
 * @Auther: wm yu
 */

/**
 * @Signature我們定義了該Interceptor将攔截Executor接口中參數類型為MappedStatement、Object、RowBounds和ResultHandler的query方法
 */
@Slf4j
@Intercepts({ @Signature(type = ParameterHandler.class, method = "setParameters", args = PreparedStatement.class) })  //注意參數PreparedStatement别導錯包了,這個包是java,jdk中的
//@ConditionalOnProperty(value = "domain.encrypt", havingValue = "true")
@Component
public class ParammeterInterceptor implements Interceptor {  //引入mybatis org.apache.ibatis.plugin下的攔截器
    @Override
    public Object intercept(Invocation invocation) throws Throwable {

        log.info("開始啟用mybatis攔截器,攔截ParamInterceptor ......");
      //攔截 ParameterHandler 的 setParameters 方法 動态設定參數
        if(invocation.getTarget() instanceof ParameterHandler){
            ParameterHandler parameterHandler =  (ParameterHandler)invocation.getTarget();
            PreparedStatement  ps = (PreparedStatement) invocation.getArgs()[0];
            //反射擷取參數對象
            Field field = parameterHandler.getClass().getDeclaredField("parameterObject");
            if(!field.isAccessible()){
                field.setAccessible(true);
            }
            //參數值
            Object parameterObject = field.get(parameterHandler);
            log.info("請求的參數是{}", JSON.toJSONString(parameterObject));
            if (Objects.nonNull(parameterObject)){
                //參數類型
                Class<?> parameterObjectClass = parameterObject.getClass();
                EncryptDecryptClass encryptDecryptClass = AnnotationUtils.findAnnotation(parameterObjectClass, EncryptDecryptClass.class);
                if (Objects.nonNull(encryptDecryptClass)){
                    //資料加密
                    final Object encrypt = EncryptDecryptUtil.encrypt(parameterObject);
                }
            }
        }
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object o) {
        return Plugin.wrap(o, this);
    }

    @Override
    public void setProperties(Properties properties) {

    }
}
           

sql傳回值的攔截:

package com.hf.demo.interceptor;


import com.alibaba.fastjson.JSON;
import com.hf.demo.annotation.EncryptDecryptClass;
import com.hf.demo.utils.EncryptDecryptUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.plugin.*;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.sql.Statement;   //導包别導入錯誤了
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Properties;

/**
 * @class_name: ResultInterceptor
 * @description:
 * @author: wm_yu
 * @create: 2019/06/29
 **/
@Intercepts({@Signature(type = ResultSetHandler.class, method = "handleResultSets", args={Statement.class})})
@Slf4j
@Component
public class ResultInterceptor implements Interceptor {



    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        log.info("mybatis攔截查詢出來的傳回值....");
        Object result = invocation.proceed();
        log.info("傳回的result{}", JSON.toJSONString(result));
        if(Objects.isNull(result)){
            return null;
        }
        if(result instanceof ArrayList){
           List<Object> list = new ArrayList<>();
            //結果集為list
            ArrayList resultList = (ArrayList) result;
            if(!CollectionUtils.isEmpty(resultList)){
                resultList.stream().forEach(var -> {
                    list.add(needDecrypt(var));

                });
            }
           return list;
        }else{
            //結果集為單個對象
            Object o = needDecrypt(result);
            return o;
        }
    }

    @Override
    public Object plugin(Object o) {
        return Plugin.wrap(o,this);
    }


    @Override
    public void setProperties(Properties properties) {

    }

    private Object needDecrypt(Object object){
        if(Objects.isNull(object)){
            return null;
        }
        Class<?> clzz = object.getClass();
        Object reslut = null;
        EncryptDecryptClass encryptDecryptClass = AnnotationUtils.findAnnotation(clzz, EncryptDecryptClass.class);
        if(Objects.nonNull(encryptDecryptClass)){
            reslut = EncryptDecryptUtil.decrypt(object);
        }
        return reslut;
    }


}
           

依賴的工具類:

package com.hf.demo.utils;

import com.hf.demo.annotation.EncryptDecryptField;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Objects;

/**
 * @Description: 加密解密資料處理
 * @Date: 2019/6/26
 * @Auther: wm yu
 */
public class EncryptDecryptUtil {

    private final static Logger log = LoggerFactory.getLogger(EncryptDecryptUtil.class);

    /**
     * 資料加密處理
     * @param parameterObject  mybatis的入參資料
     * @param <T>
     * @return
     * @throws IllegalAccessException
     */
    public static <T> T encrypt(T parameterObject) throws IllegalAccessException{
        if(null == parameterObject){
            return null;
        }
        Class<?> clzz = parameterObject.getClass();
        Field[] fields = FieldReflectUtil.getAllFields(clzz);
        Arrays.stream(fields).filter(field -> null != field
                && !Modifier.isStatic(field.getModifiers())
                && !Modifier.isFinal(field.getModifiers())
                && !Modifier.isAbstract(field.getModifiers())
                && field.isAnnotationPresent(EncryptDecryptField.class)).forEach(var -> {
                    log.info("字段開始進行加密處理{}",var.getName());
                    if(!var.isAccessible()){
                        var.setAccessible(true);
                    }

            try {
                Object o = var.get(parameterObject);
                if(o instanceof String){
                //加密處理
                var.set(parameterObject,Md5Util.encode((String) o));
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }

        });
        return parameterObject;
    }

    /**
     * 資料脫敏處理
     * @param result  mybatis的傳回值資料
     * @param <T>
     * @return
     * @throws IllegalAccessException
     */
    public static <T> T decrypt(T result){
        log.info("開始脫敏處理.....");
        if(Objects.isNull(result)){
            return null;
        }
        //擷取字段的注解
        Field[] fields = FieldReflectUtil.getAllFields(result.getClass());
        //處理資料
        Arrays.stream(fields).filter(field -> null != field
                && !Modifier.isAbstract(field.getModifiers())
                && !Modifier.isStatic(field.getModifiers())
                && !Modifier.isFinal(field.getModifiers())
                && field.isAnnotationPresent(EncryptDecryptField.class)).forEach(var -> {
            if(!var.isAccessible()){
                var.setAccessible(true);
            }
            //擷取原資料
            try {
                Object o = var.get(result);
                if(o instanceof String){
                    String value = (String) o;
                    if(value.length() >= 4){
                       value = new StringBuilder().append(value.substring(0,2)).append(value.substring(2,value.length() - 2)
                               .replaceAll(".","*"))
                               .append(value.substring(value.length() - 2,value.length())).toString();
                        log.info("value的值{}",value);
                       var.set(result,value);
                    }
                }
            } catch (IllegalAccessException e) {
                log.error("不能通過反射擷取到資料{}",var.getName(),e);
            }
        });

        return result;
    }


}
           
package com.hf.demo.utils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @Description: 反射擷取字段,支援繼承獲超類的字段
 * @Date: 2019/5/16
 * @Auther: wm yu
 */
public class FieldReflectUtil {

    public static Field[] getAllFields(Class<?> clzz){
        if(null == clzz){
            return null;
        }
        List<Field> resultList = new ArrayList<>();
        while(null != clzz){
            resultList.addAll(new ArrayList<>(Arrays.asList(clzz.getDeclaredFields())));
            //是否有繼承類
            clzz = clzz.getSuperclass();
        }
        Field[] resultArr = new Field[resultList.size()];
        return  resultList.toArray(resultArr);
    }
}
           
package com.hf.demo.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.security.MessageDigest;

/**
 * @Description:
 * @Date: 2019/6/27
 * @Auther: wm yu
 */
public class Md5Util {

    private static final Logger log = LoggerFactory.getLogger(Md5Util.class);

    private static final String SALT = "hello";


    public static String encode(String password) {
        password = password + SALT;
        MessageDigest md5 = null;
        try {
            md5 = MessageDigest.getInstance("MD5");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        char[] charArray = password.toCharArray();
        byte[] byteArray = new byte[charArray.length];

        for (int i = 0; i < charArray.length; i++){
            byteArray[i] = (byte) charArray[i];
        }
        byte[] md5Bytes = md5.digest(byteArray);
        StringBuffer hexValue = new StringBuffer();
        for (int i = 0; i < md5Bytes.length; i++) {
            int val = ((int) md5Bytes[i]) & 0xff;
            if (val < 16) {
                hexValue.append("0");
            }

            hexValue.append(Integer.toHexString(val));
        }
        return hexValue.toString();
    }




    public static void main(String[] args) {
        System.out.println(encode("admin"));
    }

}
           

mapper接口:

package com.hf.demo.mapper;

import com.hf.demo.entity.Admin;
import dto.AdminDto;

import java.util.List;

/**
 * @Description:
 * @Date: 2019/6/26
 * @Auther: wm yu
 */
public interface AdminMapper {

    Admin findById(String uid);

    List<Admin> findByCondition(AdminDto dto);
}
           

mapper對于的xml配置:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hf.demo.mapper.AdminMapper">
    <resultMap id="BaseResultMap" type="com.hf.demo.entity.Admin" >
        <!--
          WARNING - @mbg.generated
        -->
        <id column="uid" property="uid" jdbcType="VARCHAR" />
        <result column="user_name" property="userName" jdbcType="VARCHAR" />
        <result column="pass_word" property="passWord" jdbcType="VARCHAR" />
        <result column="gender" property="gender" jdbcType="VARCHAR" />
        <result column="avatar" property="avatar" jdbcType="VARCHAR" />
        <result column="email" property="email" jdbcType="VARCHAR" />
        <result column="birthday" property="birthday" jdbcType="DATE" />
        <result column="mobile" property="mobile" jdbcType="VARCHAR" />
        <result column="valid_code" property="validCode" jdbcType="VARCHAR" />
        <result column="summary" property="summary" jdbcType="VARCHAR" />
        <result column="login_count" property="loginCount" jdbcType="INTEGER" />
        <result column="last_login_time" property="lastLoginTime" jdbcType="TIMESTAMP" />
        <result column="last_login_ip" property="lastLoginIp" jdbcType="VARCHAR" />
        <result column="status" property="status" jdbcType="BIT" />
        <result column="create_time" property="createTime" jdbcType="TIMESTAMP" />
        <result column="update_time" property="updateTime" jdbcType="TIMESTAMP" />
        <result column="nick_name" property="nickName" jdbcType="VARCHAR" />
        <result column="qq_number" property="qqNumber" jdbcType="VARCHAR" />
        <result column="we_chat" property="weChat" jdbcType="VARCHAR" />
        <result column="occupation" property="occupation" jdbcType="VARCHAR" />
        <result column="token" property="token" jdbcType="VARCHAR" />
    </resultMap>


    <sql id="Base_Column_List" >
        <!--
          WARNING - @mbg.generated
        -->
        uid, user_name, pass_word, gender, avatar, email, birthday, mobile, valid_code, summary,
        login_count, last_login_time, last_login_ip, status, create_time, update_time, nick_name,
        qq_number, we_chat, occupation,token
    </sql>



    <select id="findById" resultType="com.hf.demo.entity.Admin" parameterType="string">
        SELECT <include refid="Base_Column_List"/> from t_admin where uid = #{uid}
    </select>



    <select id="findByCondition" resultMap="BaseResultMap" parameterType="dto.AdminDto">
        SELECT <include refid="Base_Column_List"/> from t_admin
        <where>
            <if test="uid != null and uid != ''">
               and  uid = #{uid}
            </if>
            <if test="userName != null and userName != ''">
               and user_name = #{userName}
            </if>
            <if test="passWord != null and passWord != ''">
                and  pass_word = #{passWord}
            </if>
            <if test="gender != null">
                and  gender = #{gender}
            </if>
            <if test="avatar != null and avatar != ''">
                and avatar = #{avatar}
            </if>
            <if test="email != null and email != ''">
                and  email = #{email}
            </if>
            <if test="startBirthday != null">
                and birthday <![CDATA[>=]]> #{startBirthday}
            </if>
            <if test="endBirthday != null">
                and birthday <![CDATA[<=]]> #{endBirthday}
            </if>

            <if test="mobile != null and mobile != ''">
                and mobile = #{mobile}
            </if>
            <if test="validCode != null and validCode != ''">
                and valid_code = #{validCode}
            </if>
            <if test="summary != null and summary != ''">
                and summary like concat('%',#{summary},'%')
            </if>
            <if test="loginCount != null">
               and login_count = #{loginCount}
            </if>
            <if test="startLastLoginTime != null">
                and last_login_time <![CDATA[>=]]> #{startLastLoginTime}
            </if>
            <if test="endLastLoginTime != null">
                and last_login_time <![CDATA[<=]]> #{endLastLoginTime}
            </if>
            <if test="loginCount != null">
               and login_count = #{loginCount}
            </if>
            <if test="lastLoginIp != null and lastLoginIp != ''">
               and last_login_ip = #{lastLoginIp}
            </if>
            <if test="status != null">
                and status = #{status}
            </if>
            <if test="startCreateTime != null">
                and create_time <![CDATA[>=]]> #{startCreateTime}
            </if>
            <if test="endCreateTime != null">
                and create_time <![CDATA[<=]]> #{endCreateTime}
            </if>
            <if test="startUpdateTime != null">
                and update_time <![CDATA[>=]]> #{startUpdateTime}
            </if>
            <if test="endUpdateTime != null">
                and update_time <![CDATA[<=]]> #{endUpdateTime}
            </if>
            <if test="nickName != null and nickName != ''">
                and nick_name = #{nickName}
            </if>
            <if test="qqNumber != null and qqNumber != ''">
                and qq_number = #{qqNumber}
            </if>
            <if test="weChat != null and weChat != ''">
                and we_chat = #{weChat}
            </if>
            <if test="occupation != null and occupation != ''">
                and occupation = #{occupation}
            </if>
            <if test="token != null and token != ''">
                and token = #{token}
            </if>
        </where>

    </select>
</mapper>
           

實體類:  含有自定義的注解

package com.hf.demo.entity;

import com.hf.demo.annotation.EncryptDecryptClass;
import com.hf.demo.annotation.EncryptDecryptField;
import lombok.Data;
import lombok.ToString;

import java.util.Date;

@ToString
@Data
@EncryptDecryptClass
public class Admin {
    /**
     * 唯一uid
     */
    private String uid;

    /**
     * 使用者名
     */
    private String userName;

    /**
     * 密碼
     */
    private String passWord;

    /**
     * 性别(1:男2:女)
     */
    private Integer gender;

    /**
     * 個人頭像
     */
    private String avatar;

    /**
     * 郵箱
     */
    private String email;

    /**
     * 出生年月日
     */
    private Date birthday;

    /**
     * 手機
     */
    @EncryptDecryptField
    private String mobile;

    /**
     * 郵箱驗證碼
     */
    private String validCode;

    /**
     * 自我簡介最多150字
     */
    private String summary;

    /**
     * 登入次數
     */
    private Integer loginCount;

    /**
     * 最後登入時間
     */
    private Date lastLoginTime;

    /**
     * 最後登入IP
     */
    private String lastLoginIp;

    /**
     * 狀态
     */
    private Integer status;

    /**
     * 建立時間
     */
    private Date createTime;

    /**
     * 更新時間
     */
    private Date updateTime;

    /**
     * 昵稱
     */
    private String nickName;

    /**
     * QQ号
     */
    private String qqNumber;

    /**
     * 微信号
     */
    private String weChat;

    /**
     * 職業
     */
    private String occupation;

    /**
     * token
     */
    private String token;


}
           
package dto;

import com.hf.demo.annotation.EncryptDecryptClass;
import com.hf.demo.annotation.EncryptDecryptField;
import lombok.Data;
import lombok.ToString;

import java.io.Serializable;
import java.util.Date;

/**
 * @Description:
 * @Date: 2019/6/27
 * @Auther: wm yu
 */
@Data
@ToString
@EncryptDecryptClass
public class AdminDto implements Serializable {
    private static final long serialVersionUID = 4770366136041080457L;

    /**
     * 唯一uid
     */
    private String uid;

    /**
     * 使用者名
     */
    private String userName;

    /**
     * 密碼
     */
    @EncryptDecryptField
    private String passWord;

    /**
     * 性别(1:男2:女)
     */
    private Integer gender;

    /**
     * 個人頭像
     */
    private String avatar;

    /**
     * 郵箱
     */
    private String email;

    /**
     * 出生年月日
     */
    private Date birthday;

    private Date startBirthday;

    private Date endBirthday;


    /**
     * 手機
     */
    private String mobile;

    /**
     * 郵箱驗證碼
     */
    private String validCode;

    /**
     * 自我簡介最多150字
     */
    private String summary;

    /**
     * 登入次數
     */
    private Integer loginCount;

    /**
     * 最後登入時間
     */
    private Date lastLoginTime;

    private Date startLastLoginTime;

    private Date endLastLoginTime;



    /**
     * 最後登入IP
     */
    private String lastLoginIp;

    /**
     * 狀态
     */
    private Integer status;

    /**
     * 建立時間
     */
    private Date createTime;

    private Date startCreateTime;

    private Date endCreateTime;

    /**
     * 更新時間
     */
    private Date updateTime;

    private Date startUpdateTime;

    private Date endUpdateTime;

    /**
     * 昵稱
     */
    private String nickName;

    /**
     * QQ号
     */
    private String qqNumber;

    /**
     * 微信号
     */
    private String weChat;

    /**
     * 職業
     */
    private String occupation;

    /**
     * token
     */
    private String token;

}
           

測試邏輯類:

controller:

package com.hf.demo.controller;

import com.hf.demo.entity.Admin;
import com.hf.demo.service.AdminService;
import dto.AdminDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @Description:
 * @Date: 2019/6/26
 * @Auther: wm yu
 */
@RestController
@RequestMapping("/api/admin")
public class AdminController {

    @Autowired
    private AdminService adminService;

    @GetMapping("/{id}")
       public Admin getAdminById(@PathVariable String id){
       return adminService.getAdminById(id);
       }


    @PostMapping("/findByCondition")
    public List<Admin> findByCondition(@RequestBody AdminDto dto){
        return adminService.findByCondition(dto);
    }


}
           

service:

package com.hf.demo.service;

import com.hf.demo.entity.Admin;
import dto.AdminDto;

import java.util.List;

/**
 * @Description:
 * @Date: 2019/6/26
 * @Auther: wm yu
 */
public interface AdminService {
    Admin getAdminById(String id);

    List<Admin> findByCondition(AdminDto dto);
}
           
package com.hf.demo.service.impl;

import com.hf.demo.entity.Admin;
import com.hf.demo.mapper.AdminMapper;
import com.hf.demo.service.AdminService;
import dto.AdminDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @Description:
 * @Date: 2019/6/26
 * @Auther: wm yu
 */
@Service
public class AdminServiceImpl implements AdminService {

    @Autowired
    private AdminMapper adminMapper;

    @Override
    public Admin getAdminById(String id) {
        Admin admin = adminMapper.findById(id);
        return admin;
    }


    @Override
    public List<Admin> findByCondition(AdminDto dto) {
        List<Admin> list = adminMapper.findByCondition(dto);
        return list;
    }
}
           

項目完整截圖:

mybatis攔截器(一)

測試如下:

mybatis攔截器(一)
mybatis攔截器(一)

根據自己的業務邏輯進行處理

攔截器

繼續閱讀