# mybatis-crypto
**Repository Path**: xiaojf/mybatis-crypto
## Basic Information
- **Project Name**: mybatis-crypto
- **Description**: mybatis 注解方式实现数据的加解密
- **Primary Language**: Java
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 4
- **Created**: 2023-04-13
- **Last Updated**: 2024-03-04
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# mybatis-crypto
使用注解方式实现Mybatis框架数据的加解密  
目前仅支持使用了TkMapper和MyBatis Plus框架的项目  
示例项目:[https://gitee.com/liujing_yanghui/mybatis-crypto-sample](https://gitee.com/liujing_yanghui/mybatis-crypto-sample)
## 安装
### 基于Tk MyBatis框架
#### maven
```
    
      top.liujingyanghui
      tk-mybatis-crypto
      last-version
    
```
#### gradle
```
    implementation 'top.liujingyanghui:tk-mybatis-crypto:last-version'
```
### 基于MyBatis Plus框架
#### maven
```
    
      top.liujingyanghui
      mybatis-plus-crypto
      last-version
    
```
#### gradle
```
    implementation 'top.liujingyanghui:mybatis-plus-crypto:last-version'
```
## 如何使用
#### 使用前注意事项
1. 所有加密的实体必须实现Serializable接口
#### 一、创建加解密规则
```java
/**
 * 手机号加解密
 *
 * @author : wdh
 * @since : 2022/5/23 16:15
 */
public class PhoneCryptoRule extends AbstractCryptoRule {
    private final String KEY = "0123456789ABHAEQ";
    private final AES AES = SecureUtil.aes(KEY.getBytes());
    /**
     * 数据加密
     */
    public String encrypt(String content) {
        try {
            return AES.encryptHex(content);
        } catch (Exception e) {
            return content;
        }
    }
    /**
     * 数据解密
     */
    public String decrypt(String content) {
        try {
            return AES.decryptStr(content);
        } catch (Exception e) {
            return content;
        }
    }
}
```
#### 二、实体类和属性加注解
在需要加解密的实体上加@CryptoClass和@CryptoString注解
```java
    @Data
    @CryptoClass    // 标识这个实体中有属性需要加解密
    @EqualsAndHashCode(callSuper = true)
    public class User extends BaseEntity { // BaseEntity中已经实现Serializable,这里就不需要实现了
    
        private String name;
    
        // 标识这个属性需要加解密,设置加解密的规则为手机号
        @CryptoString(rule = PhoneCryptoRule.class, mode = CryptoMode.ALL)
        private String phone;
    
        // 标识这个属性需要加解密,设置加解密的规则为身份证号
        @CryptoString(rule = IdNumCryptoRule.class, mode = CryptoMode.ALL)
        private String idNum;
    }
```
#### 三、Tk MyBatis框架加解密的使用
* 增
```java
    public void insert() {
        User user = new User();
        user.setPhone("13312345678");
        user.setIdNum("520520520520520520");
        user.setName("mybatis");
        userMapper.insert(user);
    }
```
* 查询与更新
```java
    public void queryAndUpdate() {
        // example 会根据实体的注解加密后去查询
        Example example = new Example(User.class);
        example.createCriteria().andEqualTo("phone", "13333333333");
        // 查询出来的数据是根据注解解密后的数据
        User user = userMapper.selectOneByExample(example); 
        user.setPhone("13333333340");
        // 操作时手机号会根据注解自动加密
        userMapper.updateByPrimaryKey(user);
    }
```
#### 四、MyBatis Plus框架加解密的使用
从1.1.0版本开始支持使用MP框架内置方法进行加解密;  
1.1.0以下版本需使用以下增强方法进行加解密:
```java
     LambdaQueryWrapperX wrapper = WrapperX.lambdaQuery(User.class);
     
     QueryWrapperX wrapper = WrapperX.query(User.class);
     
     LambdaUpdateWrapperX wrapper = WrapperX.lambdaUpdate(User.class);
     
     UpdateWrapperX wrapper = WrapperX.update(User.class);
```
* 增
```java
    public void insert() {
        User user = new User();
        user.setPhone("13312345678");
        user.setIdNum("520520520520520520");
        user.setName("mybatis");
        userMapper.insert(user);
    }
```
* 查询与更新
```java
    public void queryAndUpdate() {
        // 1.1.0及以上版本
        LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(User.class);
        // 1.1.0以下版本
        LambdaQueryWrapperX wrapper = WrapperX.lambdaQuery(User.class); 
        
        wrapper.eq(User::getPhone,"13333333333");
        // 查询出来的数据为解密后数据
        User user = userMapper.selectOne(wrapper);
        user.setIdNum("520520520520520");
        // 更新时会根据注解去加密更新
        userMapper.updateById(user); 
    }
```
#### 五、mapper接口中方法加解密的使用
```java
public interface UserMapper extends Mapper {
    // 入参和出参都为Map情况,标识入参和出参中key为phone的属性使用PhoneCryptoRule规则去加解密
    @CryptoKey(key = "phone", rule = PhoneCryptoRule.class)
    List