實作一個對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為我們提供了一個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;
}
}
項目完整截圖:
測試如下:
根據自己的業務邏輯進行處理
攔截器