# Mybatis-Encrypt
**Repository Path**: 304079992/mybatis-encrypt
## Basic Information
- **Project Name**: Mybatis-Encrypt
- **Description**: 简单的密文字段检索方案实现组件
- **Primary Language**: Java
- **License**: MulanPSL-2.0
- **Default Branch**: master
- **Homepage**: https://gitee.com/aizuda/mybatis-encrypt
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 8
- **Created**: 2024-03-28
- **Last Updated**: 2024-03-28
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# Mybatis-Encrypt
## 前言
简单的密文字段检索方案实现组件。参考[淘宝开放平台-密文字段检索方案](https://open.taobao.com/docV3.htm?docId=106213&docType=1)。
这种方案用于对文本数据进行加密搜索。在加密过程中,文本数据首先被分解成单词,然后对每个单词进行加密。搜索时,搜索关键字也被分解成单词,并对每个单词进行加密。然后,加密的关键字与加密的单词进行比较,以确定是否匹配。
举个例子:
`18612345678` 使用 4 个字符为一组的加密方式,将会有 8 组数据:"1861"、 "8612"、 "6123"、 "1234"、 "2345"、 "3456"、 "4567"、 "5678"。如果需要检索手机尾号为 `5678` 的数据,则会将 `5678` 进行加密后通过 `phone like '%<5678加密字符串>%'` 语句进行查库。
我们都知道加密后长度会增长,增长的这部分长度存储就是我们要花费的额外成本,典型的使用成本来换取速度,密文增长的幅度随着算法不同而不同以 DES 举例,13800138000 加密前占 11 个字节,加密后的串 HE9T75xNx6c5yLmS5l4r6Q== 占 24 个字节,增长是 2.18 倍
这个方法虽然可以实现加密数据的模糊查询,**但是对模糊查询的字符长度是有要求的,以我上面举的例子模糊查询字符原文长度必须等于 4 个数字**,再短的长度不建议支持,因为分词组合会增多从而导致存储的成本增加,反而安全性降低。
## 开发环境
* jdk-1.8.0_341
* IntelliJ IDEA 2023.3.5
* Windows 11
## 打包编译
```bash
# 打包 - 跳过测试
mvn clean install -Dmaven.test.skip=true
# 打包
mvn clean install
# 发布
mvn deploy
```
## 项目结构
```
mybatis-encrypt
├── doc
│ └── sql
│ └── init.sql
├── mybatis-encrypt-core
│ └── src
│ └── main
│ └── java
│ └── com
│ └── aizuda
│ └── encrypt
│ ├── constant 常量
│ │ └── EncryptConstant.java
│ ├── entity 基础对象信息
│ │ ├── ColumnRule.java
│ │ ├── FieldInfo.java
│ │ └── TableRule.java
│ ├── enums
│ │ └── EncryptType.java 加解密方式枚举
│ ├── helper
│ │ ├── CryptoHelper.java 加解密助手
│ │ ├── DecryptToolKit.java 解密工具包(获取加密规则、表结构信息等)
│ │ └── RemoteConfigToolKit.java 远程配置读取工具包(以Apollo配置中心等方式读取加密规则)
│ ├── jsqlparse jsqlparse解析sql语句相关
│ │ ├── entity
│ │ │ ├── JSQLCryptExpression.java
│ │ │ └── JSQLTable.java
│ │ ├── helper
│ │ │ └── TablesNamesFinder.java
│ │ └── visitor
│ │ ├── ExpressionV.java
│ │ ├── FromItemV.java
│ │ ├── ItemsListV.java
│ │ └── VisitorHandle.java
│ ├── service
│ │ ├── impl
│ │ │ └── TransTableZenWithBuddhaImpl.java 二次加密的密码本(与佛论禅模式)
│ │ ├── ReadRemoteConfigService.java 接口 - 读取远程配置服务
│ │ └── TransTableService.java 接口 - 二次加密的密码本接口
│ └── util
│ ├── DecryptUtil.java 解密工具类
│ ├── EncryptUtil.java 加密工具类
│ ├── ParseSQLUtil.java SQL 解析工具类
│ └── RuleUtil.java 根据配置读取数据表加密规则的工具类
├── mybatis-encrypt-demo Demo演示项目
└── mybatis-encrypt-spring-boot-starter
└── src
└── main
├── java
│ └── com
│ └── aizuda
│ └── encrypt
│ ├── config 自动装载配置属性及对象
│ │ ├── EncryptAutoConfigure.java
│ │ └── EncryptProperties.java
│ ├── entity 加密规则相关对象信息
│ │ ├── EncryptedValuesParams.java
│ │ ├── EncryptInfo.java
│ │ └── EncryptRule.java
│ ├── handler 基础对象信息
│ │ ├── EncryptPreParameterRewriter.java 重写sql中的业务数据(核心)
│ │ └── JSQLStatementContext.java jsqlparse操作(核心)
│ ├── interceptor Mybatis 拦截器(核心)
│ │ ├── DecryptQueryInterceptor.java
│ │ ├── EncryptQueryInterceptor.java
│ │ └── EncryptSaveInterceptor.java
│ └── service
│ └── impl
│ └── ApolloReadRemoteConfigServiceImpl.java Apollo 配置读取实现(全反射操作)
└── resources
└── META-INF
├── spring
│ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports
└── spring.factories
```
## 快速开始
### 引入jar包
> 不要问为什么强依赖 `Hutool` 、 `MyBatis-Plus` 。
>
> 就是爱!
>
> 不用这两个的,下面可以不用看了!!!
- Maven:
```xml
com.aizuda
mybatis-encrypt
0.1
```
- Gradle:
```groovy
implementation group: 'com.aizuda', name: 'mybatis-encrypt', version: '0.1'
```
### 配置
```yaml
mybatis:
encrypt:
# 加密密钥
encrypt-key: xxxxxxxxxxxxxxxx
# 加密方式(aes、sm4)
encrypt-type: sm4
tables:
# 对 sys_user 下的 phone、user_name 进行加密
sys_user:
columns:
phone:
encryptor: true
split-char: 3
user_name:
encryptor: true
# sys_xxxx:
# columns:
# xxxx:
# encryptor: true
# split-char: 3
```
| 参数 | 默认值 | 说明 |
| :---: | :---: | :---: |
| mybatis.encrypt.encrypt-key | - | 密钥 |
| mybatis.encrypt.encrypt-type | - | 加密方式,参考[EncryptType](https://gitee.com/nn200433/mybatis-encrypt/blob/master/mybatis-encrypt-core/src/main/java/com/aizuda/encrypt/enums/EncryptType.java) |
| mybatis.encrypt.tables.<数据表名>.columns.<数据表字段名>.encryptor | - | 是否加密 |
| mybatis.encrypt.tables.<数据表名>.columns.<数据表字段名>.split-char | 4 | 分割长度(即多少个字符为一组加密) |
## 演示
> 完整示例参考 `mybatis-encrypt-demo` 模块
```java
@Test
public void encryptQuery() {
// final String userName = "苗子哥牛逼";
// User user = new User();
// user.setUserName(userName);
// user.setPhone("18612345678");
// user.setSex("男");
// userService.save(user);
// log.info("---> 数据加密保存成功:{}", user);
// 查询1
final List list = userService.lambdaQuery().like(User::getUserName, "苗子哥牛").list();
log.info("---> 查询结果1:{}", JSONUtil.toJsonStr(list));
// 查询2
final List list2 = userService.lambdaQuery().like(User::getUserName, "子哥牛逼").list();
log.info("---> 查询结果2:{}", JSONUtil.toJsonStr(list2));
// 查询3
final List list3 = userService.lambdaQuery().like(User::getPhone, "186").list();
log.info("---> 查询结果3:{}", JSONUtil.toJsonStr(list3));
// 查询4(长度不够报错!)
final List list4 = userService.lambdaQuery().like(User::getPhone, "18").list();
log.info("---> 查询结果4:{}", JSONUtil.toJsonStr(list4));
// 查询5(长度不够报错!)
final List list5 = userService.lambdaQuery().like(User::getUserName, "哥牛逼").list();
log.info("---> 查询结果5:{}", JSONUtil.toJsonStr(list5));
}
```

```
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.7.12)
2024-03-27 17:08:05.486 DEBUG 25200 --- [ main] com.aizuda.encrypt.EncryptTest : Running with Spring Boot v2.7.12, Spring v5.3.27
2024-03-27 17:08:05.487 INFO 25200 --- [ main] com.aizuda.encrypt.EncryptTest : No active profile set, falling back to 1 default profile: "default"
_ _ |_ _ _|_. ___ _ | _
| | |\/|_)(_| | |_\ |_)||_|_\
/ |
3.5.5
2024-03-27 17:08:13.870 DEBUG 25200 --- [ main] com.aizuda.encrypt.util.RuleUtil : ---> [读取配置] sys_user.phone.splitChar = 3
2024-03-27 17:08:13.911 DEBUG 25200 --- [ main] com.aizuda.encrypt.util.RuleUtil : ---> [读取配置] sys_user.phone.encryptor = true
2024-03-27 17:08:13.922 DEBUG 25200 --- [ main] .e.s.i.ApolloReadRemoteConfigServiceImpl : ---> [读取配置] 构造结果:{sys_user=TableRule(columns={phone=ColumnRule(encryptor=true, splitChar=3)})}
2024-03-27 17:08:13.924 DEBUG 25200 --- [ main] com.aizuda.encrypt.util.RuleUtil : ---> [读取配置] sys_user.phone.encryptor = true
2024-03-27 17:08:13.926 DEBUG 25200 --- [ main] com.aizuda.encrypt.util.RuleUtil : ---> [读取配置] sys_user.phone.splitChar = 3
2024-03-27 17:08:13.927 DEBUG 25200 --- [ main] com.aizuda.encrypt.util.RuleUtil : ---> [读取配置] sys_user.user_name.encryptor = true
2024-03-27 17:08:13.929 DEBUG 25200 --- [ main] c.aizuda.encrypt.helper.DecryptToolKit : ---> [读取配置] 构造结果:{sys_user=TableRule(columns={phone=ColumnRule(encryptor=true, splitChar=3), user_name=ColumnRule(encryptor=true, splitChar=4)})}
2024-03-27 17:08:15.030 INFO 25200 --- [ main] com.aizuda.encrypt.EncryptTest : Started EncryptTest in 12.169 seconds (JVM running for 16.207)
2024-03-27 17:08:18.370 INFO 25200 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2024-03-27 17:08:19.245 INFO 25200 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2024-03-27 17:08:19.630 DEBUG 25200 --- [ main] c.a.e.j.helper.TablesNamesFinder : ---> [Mybatis SQL 拦截器] -------------------- 解析表名 开始 --------------------
2024-03-27 17:08:19.631 DEBUG 25200 --- [ main] c.a.e.j.helper.TablesNamesFinder : ---> [Mybatis SQL 拦截器] 待解析的sql = SELECT id, user_name, phone, sex FROM sys_user WHERE (user_name LIKE ?)
2024-03-27 17:08:19.726 DEBUG 25200 --- [ main] c.a.e.j.helper.TablesNamesFinder : ---> [Mybatis SQL 拦截器] 解析到的表名 = [{"tableName":"sys_user","aliasName":"sys_user"}]
2024-03-27 17:08:19.727 DEBUG 25200 --- [ main] c.a.e.j.helper.TablesNamesFinder : ---> [Mybatis SQL 拦截器] -------------------- 解析表名 结束 --------------------
2024-03-27 17:08:19.729 DEBUG 25200 --- [ main] c.a.e.handler.JSQLStatementContext : ---> [Mybatis SQL 拦截器] -------------------- 解析表达式 开始 --------------------
2024-03-27 17:08:19.730 DEBUG 25200 --- [ main] c.a.e.handler.JSQLStatementContext : ---> [Mybatis SQL 拦截器] 待解析的sql = SELECT id, user_name, phone, sex FROM sys_user WHERE (user_name LIKE ?)
2024-03-27 17:08:19.739 WARN 25200 --- [ main] c.a.e.jsqlparse.visitor.VisitorHandle : ---> [Mybatis SQL 拦截器] 解析查询条件 『 user_name LIKE ? 』,字段 user_name 未设置归属表别名,默认使用 t 做为字段归属表的别名...
2024-03-27 17:08:19.740 DEBUG 25200 --- [ main] c.a.e.jsqlparse.visitor.VisitorHandle : ---> [Mybatis SQL 拦截器] 解析查询条件 『 user_name LIKE ? 』 | 下标 = 1 , 字段名 = user_name , 归属表 = null
2024-03-27 17:08:19.741 DEBUG 25200 --- [ main] c.a.e.handler.JSQLStatementContext : ---> [Mybatis SQL 拦截器] -------------------- 解析表达式 结束 --------------------
2024-03-27 17:08:19.744 DEBUG 25200 --- [ main] c.a.e.i.EncryptQueryInterceptor : ---> [Mybatis 查询拦截器] query 待处理 sql = SELECT id,user_name,phone,sex FROM sys_user WHERE (user_name LIKE ?)
2024-03-27 17:08:22.461 DEBUG 25200 --- [ main] com.aizuda.encrypt.util.EncryptUtil : ---> [数据加密] 苗子哥牛 | cc8829e5fdaaa9b5df68dcfe1e134b42 | 32
2024-03-27 17:08:22.465 DEBUG 25200 --- [ main] c.a.e.i.EncryptQueryInterceptor : ---> [Mybatis SQL 加密拦截] 表名 = sys_user , 字段 = user_name , 加密前 = 苗子哥牛 , 加密后 = 夜夜漫漫婆都帝陀吉爍殿殿殿都悉陀爍吉跋漫爍夜吉帝苦帝苦娑耶悉耶婆
2024-03-27 17:08:22.469 DEBUG 25200 --- [ main] c.a.e.mapper.UserMapper.selectList : ==> Preparing: SELECT id,user_name,phone,sex FROM sys_user WHERE (user_name LIKE ?)
2024-03-27 17:08:22.569 DEBUG 25200 --- [ main] c.a.e.mapper.UserMapper.selectList : ==> Parameters: %夜夜漫漫婆都帝陀吉爍殿殿殿都悉陀爍吉跋漫爍夜吉帝苦帝苦娑耶悉耶婆%(String)
2024-03-27 17:08:22.856 DEBUG 25200 --- [ main] c.a.e.mapper.UserMapper.selectList : <== Total: 1
2024-03-27 17:08:22.920 INFO 25200 --- [ main] com.aizuda.encrypt.EncryptTest : ---> 查询结果1:[{"id":"37213cfe82be80c67ba8923b54849463","userName":"苗子哥牛逼","phone":"18612345678","sex":"男"}]
2024-03-27 17:08:22.932 DEBUG 25200 --- [ main] c.a.e.handler.JSQLStatementContext : ---> [Mybatis SQL 拦截器] -------------------- 解析表达式 开始 --------------------
2024-03-27 17:08:22.933 DEBUG 25200 --- [ main] c.a.e.handler.JSQLStatementContext : ---> [Mybatis SQL 拦截器] 待解析的sql = SELECT id, user_name, phone, sex FROM sys_user WHERE (user_name LIKE ?)
2024-03-27 17:08:22.933 WARN 25200 --- [ main] c.a.e.jsqlparse.visitor.VisitorHandle : ---> [Mybatis SQL 拦截器] 解析查询条件 『 user_name LIKE ? 』,字段 user_name 未设置归属表别名,默认使用 t 做为字段归属表的别名...
2024-03-27 17:08:22.933 DEBUG 25200 --- [ main] c.a.e.jsqlparse.visitor.VisitorHandle : ---> [Mybatis SQL 拦截器] 解析查询条件 『 user_name LIKE ? 』 | 下标 = 1 , 字段名 = user_name , 归属表 = null
2024-03-27 17:08:22.934 DEBUG 25200 --- [ main] c.a.e.handler.JSQLStatementContext : ---> [Mybatis SQL 拦截器] -------------------- 解析表达式 结束 --------------------
2024-03-27 17:08:22.934 DEBUG 25200 --- [ main] c.a.e.i.EncryptQueryInterceptor : ---> [Mybatis 查询拦截器] query 待处理 sql = SELECT id,user_name,phone,sex FROM sys_user WHERE (user_name LIKE ?)
2024-03-27 17:08:22.940 DEBUG 25200 --- [ main] com.aizuda.encrypt.util.EncryptUtil : ---> [数据加密] 子哥牛逼 | 15287971bd0b8ed3202d1aa2222e6668 | 32
2024-03-27 17:08:22.941 DEBUG 25200 --- [ main] c.a.e.i.EncryptQueryInterceptor : ---> [Mybatis SQL 加密拦截] 表名 = sys_user , 字段 = user_name , 加密前 = 子哥牛逼 , 加密后 = 苦陀婆漫多都多苦悉爍滅悉漫帝爍娑婆滅婆爍苦殿殿婆婆婆婆帝跋跋跋漫
2024-03-27 17:08:22.942 DEBUG 25200 --- [ main] c.a.e.mapper.UserMapper.selectList : ==> Preparing: SELECT id,user_name,phone,sex FROM sys_user WHERE (user_name LIKE ?)
2024-03-27 17:08:22.944 DEBUG 25200 --- [ main] c.a.e.mapper.UserMapper.selectList : ==> Parameters: %苦陀婆漫多都多苦悉爍滅悉漫帝爍娑婆滅婆爍苦殿殿婆婆婆婆帝跋跋跋漫%(String)
2024-03-27 17:08:22.948 DEBUG 25200 --- [ main] c.a.e.mapper.UserMapper.selectList : <== Total: 1
2024-03-27 17:08:22.951 INFO 25200 --- [ main] com.aizuda.encrypt.EncryptTest : ---> 查询结果2:[{"id":"37213cfe82be80c67ba8923b54849463","userName":"苗子哥牛逼","phone":"18612345678","sex":"男"}]
2024-03-27 17:08:22.967 DEBUG 25200 --- [ main] c.a.e.j.helper.TablesNamesFinder : ---> [Mybatis SQL 拦截器] -------------------- 解析表名 开始 --------------------
2024-03-27 17:08:22.967 DEBUG 25200 --- [ main] c.a.e.j.helper.TablesNamesFinder : ---> [Mybatis SQL 拦截器] 待解析的sql = SELECT id, user_name, phone, sex FROM sys_user WHERE (phone LIKE ?)
2024-03-27 17:08:22.968 DEBUG 25200 --- [ main] c.a.e.j.helper.TablesNamesFinder : ---> [Mybatis SQL 拦截器] 解析到的表名 = [{"tableName":"sys_user","aliasName":"sys_user"}]
2024-03-27 17:08:22.969 DEBUG 25200 --- [ main] c.a.e.j.helper.TablesNamesFinder : ---> [Mybatis SQL 拦截器] -------------------- 解析表名 结束 --------------------
2024-03-27 17:08:22.969 DEBUG 25200 --- [ main] c.a.e.handler.JSQLStatementContext : ---> [Mybatis SQL 拦截器] -------------------- 解析表达式 开始 --------------------
2024-03-27 17:08:22.970 DEBUG 25200 --- [ main] c.a.e.handler.JSQLStatementContext : ---> [Mybatis SQL 拦截器] 待解析的sql = SELECT id, user_name, phone, sex FROM sys_user WHERE (phone LIKE ?)
2024-03-27 17:08:22.970 WARN 25200 --- [ main] c.a.e.jsqlparse.visitor.VisitorHandle : ---> [Mybatis SQL 拦截器] 解析查询条件 『 phone LIKE ? 』,字段 phone 未设置归属表别名,默认使用 t 做为字段归属表的别名...
2024-03-27 17:08:22.970 DEBUG 25200 --- [ main] c.a.e.jsqlparse.visitor.VisitorHandle : ---> [Mybatis SQL 拦截器] 解析查询条件 『 phone LIKE ? 』 | 下标 = 1 , 字段名 = phone , 归属表 = null
2024-03-27 17:08:22.970 DEBUG 25200 --- [ main] c.a.e.handler.JSQLStatementContext : ---> [Mybatis SQL 拦截器] -------------------- 解析表达式 结束 --------------------
2024-03-27 17:08:22.971 DEBUG 25200 --- [ main] c.a.e.i.EncryptQueryInterceptor : ---> [Mybatis 查询拦截器] query 待处理 sql = SELECT id,user_name,phone,sex FROM sys_user WHERE (phone LIKE ?)
2024-03-27 17:08:22.974 DEBUG 25200 --- [ main] com.aizuda.encrypt.util.EncryptUtil : ---> [数据加密] 186 | 367732b439d3ec62145a272911450f91 | 32
2024-03-27 17:08:22.974 DEBUG 25200 --- [ main] c.a.e.i.EncryptQueryInterceptor : ---> [Mybatis SQL 加密拦截] 表名 = sys_user , 字段 = phone , 加密前 = 186 , 加密后 = 娑跋多多娑婆悉耶娑都爍娑帝夜跋婆苦耶陀殿婆多婆都苦苦耶陀滅吉都苦
2024-03-27 17:08:22.975 DEBUG 25200 --- [ main] c.a.e.mapper.UserMapper.selectList : ==> Preparing: SELECT id,user_name,phone,sex FROM sys_user WHERE (phone LIKE ?)
2024-03-27 17:08:22.976 DEBUG 25200 --- [ main] c.a.e.mapper.UserMapper.selectList : ==> Parameters: %娑跋多多娑婆悉耶娑都爍娑帝夜跋婆苦耶陀殿婆多婆都苦苦耶陀滅吉都苦%(String)
2024-03-27 17:08:22.979 DEBUG 25200 --- [ main] c.a.e.mapper.UserMapper.selectList : <== Total: 1
2024-03-27 17:08:22.983 INFO 25200 --- [ main] com.aizuda.encrypt.EncryptTest : ---> 查询结果3:[{"id":"37213cfe82be80c67ba8923b54849463","userName":"苗子哥牛逼","phone":"18612345678","sex":"男"}]
2024-03-27 17:08:22.997 DEBUG 25200 --- [ main] c.a.e.handler.JSQLStatementContext : ---> [Mybatis SQL 拦截器] -------------------- 解析表达式 开始 --------------------
2024-03-27 17:08:22.997 DEBUG 25200 --- [ main] c.a.e.handler.JSQLStatementContext : ---> [Mybatis SQL 拦截器] 待解析的sql = SELECT id, user_name, phone, sex FROM sys_user WHERE (phone LIKE ?)
2024-03-27 17:08:22.997 WARN 25200 --- [ main] c.a.e.jsqlparse.visitor.VisitorHandle : ---> [Mybatis SQL 拦截器] 解析查询条件 『 phone LIKE ? 』,字段 phone 未设置归属表别名,默认使用 t 做为字段归属表的别名...
2024-03-27 17:08:22.998 DEBUG 25200 --- [ main] c.a.e.jsqlparse.visitor.VisitorHandle : ---> [Mybatis SQL 拦截器] 解析查询条件 『 phone LIKE ? 』 | 下标 = 1 , 字段名 = phone , 归属表 = null
2024-03-27 17:08:22.998 DEBUG 25200 --- [ main] c.a.e.handler.JSQLStatementContext : ---> [Mybatis SQL 拦截器] -------------------- 解析表达式 结束 --------------------
2024-03-27 17:08:22.998 DEBUG 25200 --- [ main] c.a.e.i.EncryptQueryInterceptor : ---> [Mybatis 查询拦截器] query 待处理 sql = SELECT id,user_name,phone,sex FROM sys_user WHERE (phone LIKE ?)
2024-03-27 17:08:23.013 ERROR 25200 --- [ main] c.a.e.i.EncryptQueryInterceptor : ---> [Mybatis 查询拦截器] 拦截出现异常...,原因:查询条件 sys_user.phone 的数据需要等于3!
java.lang.RuntimeException: 查询条件 sys_user.phone 的数据需要等于3!
2024-03-27 17:08:23.015 DEBUG 25200 --- [ main] c.a.e.mapper.UserMapper.selectList : ==> Preparing: SELECT id,user_name,phone,sex FROM sys_user WHERE (phone LIKE ?)
2024-03-27 17:08:23.017 DEBUG 25200 --- [ main] c.a.e.mapper.UserMapper.selectList : ==> Parameters: %18%(String)
2024-03-27 17:08:23.020 DEBUG 25200 --- [ main] c.a.e.mapper.UserMapper.selectList : <== Total: 0
2024-03-27 17:08:23.020 INFO 25200 --- [ main] com.aizuda.encrypt.EncryptTest : ---> 查询结果4:[]
2024-03-27 17:08:23.036 DEBUG 25200 --- [ main] c.a.e.handler.JSQLStatementContext : ---> [Mybatis SQL 拦截器] -------------------- 解析表达式 开始 --------------------
2024-03-27 17:08:23.036 DEBUG 25200 --- [ main] c.a.e.handler.JSQLStatementContext : ---> [Mybatis SQL 拦截器] 待解析的sql = SELECT id, user_name, phone, sex FROM sys_user WHERE (user_name LIKE ?)
2024-03-27 17:08:23.036 WARN 25200 --- [ main] c.a.e.jsqlparse.visitor.VisitorHandle : ---> [Mybatis SQL 拦截器] 解析查询条件 『 user_name LIKE ? 』,字段 user_name 未设置归属表别名,默认使用 t 做为字段归属表的别名...
2024-03-27 17:08:23.036 DEBUG 25200 --- [ main] c.a.e.jsqlparse.visitor.VisitorHandle : ---> [Mybatis SQL 拦截器] 解析查询条件 『 user_name LIKE ? 』 | 下标 = 1 , 字段名 = user_name , 归属表 = null
2024-03-27 17:08:23.036 DEBUG 25200 --- [ main] c.a.e.handler.JSQLStatementContext : ---> [Mybatis SQL 拦截器] -------------------- 解析表达式 结束 --------------------
2024-03-27 17:08:23.037 DEBUG 25200 --- [ main] c.a.e.i.EncryptQueryInterceptor : ---> [Mybatis 查询拦截器] query 待处理 sql = SELECT id,user_name,phone,sex FROM sys_user WHERE (user_name LIKE ?)
2024-03-27 17:08:23.041 ERROR 25200 --- [ main] c.a.e.i.EncryptQueryInterceptor : ---> [Mybatis 查询拦截器] 拦截出现异常...,原因:查询条件 sys_user.user_name 的数据需要等于4!
java.lang.RuntimeException: 查询条件 sys_user.user_name 的数据需要等于4!
2024-03-27 17:08:23.043 DEBUG 25200 --- [ main] c.a.e.mapper.UserMapper.selectList : ==> Preparing: SELECT id,user_name,phone,sex FROM sys_user WHERE (user_name LIKE ?)
2024-03-27 17:08:23.047 DEBUG 25200 --- [ main] c.a.e.mapper.UserMapper.selectList : ==> Parameters: %哥牛逼%(String)
2024-03-27 17:08:23.050 DEBUG 25200 --- [ main] c.a.e.mapper.UserMapper.selectList : <== Total: 0
2024-03-27 17:08:23.051 INFO 25200 --- [ main] com.aizuda.encrypt.EncryptTest : ---> 查询结果5:[]
2024-03-27 17:08:23.091 INFO 25200 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
2024-03-27 17:08:23.127 INFO 25200 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
```
## 附注
该项目得益于 [Mybatis数据字段加密插件](https://gitee.com/doubleFli/mybatis-encrypt-plugins) 提供的思路。
## 特别鸣谢
### 项目
> 感谢以下的项目,排名不分先后
* [Hutool](https://hutool.cn) Hutool是一个Java工具包,让Java语言也可以“甜甜的”。
* [MyBatis-Plus](https://baomidou.com/) MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
* [Mybatis数据字段加密插件](https://gitee.com/doubleFli/mybatis-encrypt-plugins) 支持Mybatis数据字段加密新增、更新、查询的插件。