Mybatis拦截器 + jsqlparser 实现加解密(修改SQL)
Mybatis拦截器
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
jsqlparser
EncryptStatementVisitor encryptVisitor = new EncryptStatementVisitor();
Statement sqlStatement = CCJSqlParserUtil.parse(selectSql);
sqlStatement.accept(encryptVisitor);
表达式访问器
表达式访问器,包括(查询字段、where、join、having、任何运算)
from访问器
from访问器,获取select from和join的表
参数访问器
参数访问器,处理占位符嵌套加密函数
查询字段访问器
查询字段访问器,处理select查询字段的表达式
select访问器
select访问器,用于处理简单查询,嵌套子查询
statement访问器
insert、delete、update、select处理
实现效果
原始SQL
" select d.id as d_id, m.a, m.id as m_id, m.b"
+ " from ("
+ " select k.a, n.id, count(n.b) as b, (select count(*) from aaa) as c"
+ " from ccc k left join bbb n"
+ " on n.id = k.c_id "
+ " where n.ddd = (select id from bbb where id = ?)"
+ " group by k.a, n.id"
+ " having k.a = ? and n.id = ?"
+ " ) m"
+ " right join ddd d on m.id = d.m_id"
转换结果
" SELECT AES_DECRYPT(UNHEX(d.id),'${decryptKey}') AS d_id, m.a, m.id AS m_id, m.b"
+ " FROM ("
+ " SELECT AES_DECRYPT(UNHEX(k.a),'${decryptKey}') AS a, AES_DECRYPT(UNHEX(n.id),'${decryptKey}') AS id, count(AES_DECRYPT(UNHEX(n.b),'${decryptKey}')) AS b, (SELECT count(*) FROM aaa) AS c"
+ " FROM ccc k LEFT JOIN bbb n"
+ " ON AES_DECRYPT(UNHEX(n.id),'${decryptKey}') = k.c_id"
+ " WHERE AES_DECRYPT(UNHEX(n.ddd),'${decryptKey}') = (SELECT AES_DECRYPT(UNHEX(id),'${decryptKey}') AS id FROM bbb WHERE AES_DECRYPT(UNHEX(id),'${decryptKey}') = ?)"
+ " GROUP BY AES_DECRYPT(UNHEX(k.a),'${decryptKey}'), AES_DECRYPT(UNHEX(n.id),'${decryptKey}')"
+ " HAVING AES_DECRYPT(UNHEX(k.a),'${decryptKey}') = ? AND AES_DECRYPT(UNHEX(n.id),'${decryptKey}') = ?"
+ " ) m"
+ " RIGHT JOIN ddd d ON m.id = AES_DECRYPT(UNHEX(d.m_id),'${decryptKey}')"
加密字段配置
put("ccc", Arrays.asList("a", "b"));
put("bbb", Arrays.asList("id", "ddd", "b"));
put("ddd", Arrays.asList("m_id", "id"));
update、insert、delete
update、insert、delete也实现了,只是select最复杂
update、delete修改where条件
update、insert修改占位符’?’