mysql函数实现数据脱敏,隐藏业务字符-函数的使用

最近做了一个功能,是管理用户账户对接支付的一个模块,里面有一个是做提款账户的管理的功能,这个功能里面涉及到用户的银行卡号和手机号,根据需求为了保密性这里的银行卡号和手机号是不能在页面上展示的,需要后端来解决这个问题。因此我准备了两套方案来解决这个问题。
一、通过mysql的concat、left、right函数
先看下页面效果:

在这里插入图片描述所以这里只需要在MySQL中操作即可获取到加密后的数据:
account_name:卡名
account_no :卡号
account_type:卡的类型
sys_company_withdraw_account:提款账户的表名
-----------------------0-----------------------------
concat:拼接函数,concat(‘字符串1’,‘拼接参数’,‘字符串2’)
left:函数,left(‘字符串’,从左开始的截取长度)
right:函数,right(‘字符串’,从右边开始截取的长度)

select account_name,
       concat(left(account_no,4),'********',right(account_no,4))as accountNo,
       concat(left(mobile_no,4),'***',right(mobile_no,4)) as mobileNo,
       account_type
from sys_company_withdraw_account scwa
where scwa.del_flag=0;

效果如下:
在这里插入图片描述二、insert函数:
insert(a,n1,n2,str)的参数解析如下:
a:字段名.

n1:开始替换的位置.从1开始算起

n2:替换的长度.

str:替换后的字符串.
在这里插入图片描述select account_name, insert(account_no,5,4,'****')as accountNo, insert(mobile_no,4,4,'***') as mobileNo, account_type from sys_company_withdraw_account scwa where scwa.del_flag=0;
三、自定义函数:
这里要用到sqlyoung:两种打开函数的方式
1、点开对象,里面的函数,创建函数
在这里插入图片描述在这里插入图片描述
2、右击function,创建函数
在这里插入图片描述3、创建一个名为fun_hideMainCode的函数
会出一个函数的模板:

DELIMITER $$

CREATE
    /*[DEFINER = { user | CURRENT_USER }]*/
    FUNCTION `jycloud`.`fun_hide`()
    RETURNS TYPE
    /*LANGUAGE SQL
    | [NOT] DETERMINISTIC
    | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
    | SQL SECURITY { DEFINER | INVOKER }
    | COMMENT 'string'*/
    BEGIN

    END$$

DELIMITER ;

编写函数:

DELIMITER $$

USE `jycloud`$$

DROP FUNCTION IF EXISTS `fun_hideMainCode`$$

CREATE DEFINER=`root`@`%` FUNCTION `fun_hideMainCode`(`v_type` VARCHAR(20),`v_code` VARCHAR(100)) RETURNS VARCHAR(100) CHARSET utf8
BEGIN
	DECLARE result_code VARCHAR(100);
	DECLARE begin_code VARCHAR(50);
	DECLARE hide_code VARCHAR(50);
	DECLARE end_code VARCHAR(50);
	
	IF v_type = 'bank_card_account' THEN
		SET begin_code = LEFT(v_code, 4);
		SET hide_code = '*****';
		SET end_code = RIGHT(v_code, 4);
		SET result_code = CONCAT(begin_code, hide_code, end_code);
	ELSEIF v_type = 'phone_num' THEN
		SET begin_code = LEFT(v_code, 3);
		SET hide_code = '****';
		SET end_code = RIGHT(v_code, 4);
		SET result_code = CONCAT(begin_code, hide_code, end_code);
	ELSE
	  SET result_code = v_code;
	END IF;
	RETURN result_code;
END$$

DELIMITER ;

这里的
v_type = ‘bank_card_account’
v_type = ‘phone_num’
bank_card_account表示传进来的卡号字段
phone_num表示手机号字段。
4、在你的MySQL中引入此函数:

/*函数*/
select
       id,
       company_id,
       bank_code,
       bank_name,
       account_name,
       fun_hideMainCode('bank_card_account',account_no) AS account_no,
       account_type,
       fun_hideMainCode('phone_num',mobile_no) AS mobile_no,
       is_default
from sys_company_withdraw_account scwa
where scwa.del_flag=0;

'bank_card_account’表示需要替换的银行卡号字段,
account_no表示传进来的银行卡号的字段。
效果如下:
在这里插入图片描述在mybatis中使用直接把sql拷贝过去就可以了。
这里有个坑点,是本人亲自踩出来的坑。

在mybatis中,如果你用resulttype,这里查询的字段,as后面使用对象来接收的,必须as为数据库里面的字段。如果改成大写,可能查出来的数据里面没有这个字段。
在这里插入图片描述四、后台硬编码编写工具类,更改查询的字段:

 @Override
    public PageInfo getCount(SysCompanyWithdrawAccount account, Integer page, Integer size) {
        page = page == null ? 1 : page;
        size = size == null ? 10 : size;
        PageHelper.startPage(page, size);
        /*获取账户结果集*/
        List<SysCompanyWithdrawAccount> list=dao.getCount(account);
        for (SysCompanyWithdrawAccount sysCompanyWithdrawAccount:list){
            //获取卡号
            String accountNo=sysCompanyWithdrawAccount.getAccountNo();
            //获取手机号
            String mobileNo=sysCompanyWithdrawAccount.getMobileNo();
            //隐藏银行卡中间的字符串
            int length = accountNo.length();
            int beforeLength = 4;
            int afterLength = 4;
            //替换字符串,当前使用“*”
            String replaceSymbol = "*";
            StringBuffer sb = new StringBuffer();
            for(int i=0; i<length; i++) {
                if(i < beforeLength || i >= (length - afterLength)) {
                    sb.append(accountNo.charAt(i));
                } else {
                    //通过追加的方式
                    sb.append(replaceSymbol);
                }
            }
            //隐藏手机号中间位置字符,显示前三后三个字符
            int length1 = mobileNo.length();
            int beforeLength1 = 3;
            int afterLength1 = 3;
            //替换字符串,当前使用“*”
            String replaceSymbol1 = "*";
            StringBuffer sb1 = new StringBuffer();
            for(int i=0; i<length; i++) {
                if(i < beforeLength1 || i >= (length1 - afterLength1)) {
                    sb1.append(mobileNo.charAt(i));
                } else {
                    sb1.append(replaceSymbol1);
                }
            }
        }
        
        return new PageInfo<>(dao.getCount(account));
    }

这我将它编写成了一个工具类HideDataUtil:

import org.apache.commons.lang3.StringUtils;

public class HideDataUtil {
	/**
	 * 隐藏银行卡号中间的字符串(使用*号),显示前四后四
	 * @param cardNo
	 * @return
	 */
	public static String hideCardNo(String cardNo) {
		if(StringUtils.isBlank(cardNo)) {
			return cardNo;
		}
		int length = cardNo.length();
		int beforeLength = 4;
		int afterLength = 4;
		//替换字符串,当前使用“*”
		String replaceSymbol = "*";
		StringBuffer sb = new StringBuffer();
		for(int i=0; i<length; i++) {
			if(i < beforeLength || i >= (length - afterLength)) {
				sb.append(cardNo.charAt(i));
			} else {
				sb.append(replaceSymbol);
			}
		}
		
		return sb.toString();
	}
	/**
      隐藏手机号中间位置字符,显示前三后三个字符
	 * @param phoneNo
	 * @return
	 */
	public static String hidePhoneNo(String phoneNo) {
		if(StringUtils.isBlank(phoneNo)) {
			return phoneNo;
		}
		int length = phoneNo.length();
		int beforeLength = 3;
		int afterLength = 3;
		//替换字符串,当前使用“*”
		String replaceSymbol = "*";
		StringBuffer sb = new StringBuffer();
		for(int i=0; i<length; i++) {
			if(i < beforeLength || i >= (length - afterLength)) {
				sb.append(phoneNo.charAt(i));
			} else {
				sb.append(replaceSymbol);
			}
		}
		
		return sb.toString();
	}
}

测试一下:

public static void main(String[] args) {
        //$1 $2 表示正则表达式里面的第一个和第二个,也就是括号里面的内容
        System.out.println(StringUtils.replacePattern("12321120687","(\\d{3})\\d{4}(\\d{4})", "$1****$2"));
        System.out.println("12321120687".replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2"));
        System.out.println("1425665665525895689".replaceAll("(\\d{4})\\d{4}(\\d{4})\\d{4}(\\d{3})", "$1****$2****$3"));
    }

在这里拓展一下:MySQL优化里面,使用函数时,添加if else判断,在sql执行之后会将判断条件放在sql中,从而影响数据库的性能,因此一般不建议使用函数。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值