mysql 实现类似oracle函数bitand功能
oracle中位运算函数bitand中在mysql的实现是 &运算符,我司使用的JPA要在oracle和mysql中自由切换,所以使用统一的位运算操作方法
mysql实现bitand函数的功能,我们有两种解决方案:
1. 在mysql中,自定义函数bitand,
CREATE DEFINER=`root`@`%` FUNCTION `bitand`(num1 decimal(65,0),num2 decimal(65,0)) RETURNS decimal(65,0) BEGIN DECLARE result decimal(65,0); select num1&num2 into result; RETURN result; END
2.sql拦截,在StatementInspector中把生成sql中的bitand转换成&运算。
这个方法也有多种实现,比如用正则替换法,把bitand(4,2)>0 替换成4&2>0,也可以。
还有就是用使用jsqlparser库,对sql进行分析,这个bitand函数只用在where条件中,所以,就可以这样写:
/** * mysql处理 把bitand函数 替换成&运算 * * @param sql * @return */ private String getMysqlSql(String sql) { try { Statement statement = CCJSqlParserUtil.parse(sql); if (statement instanceof Select) { SelectBody selectBody = ((Select) statement).getSelectBody(); PlainSelect plainSelect = (PlainSelect) selectBody; FromItem fromItem = plainSelect.getFromItem(); Expression where = plainSelect.getWhere(); if (where != null) { where.accept(new ExpressionDeXParser()); } return statement.toString(); } } catch (JSQLParserException e) { e.printStackTrace(); } return sql; }
类ExpressionDeXParser的代码如下:
public class ExpressionDeXParser extends ExpressionDeParser { @Override public void visit(GreaterThan greaterThan) { super.visit(greaterThan); Expression leftExpression = greaterThan.getLeftExpression(); Function function = (Function) leftExpression; if ("BITAND".equals(function.getName().toUpperCase())) { ExpressionList parameters = function.getParameters(); BitwiseAnd bitwiseAnd = new BitwiseAnd(); bitwiseAnd.setLeftExpression(parameters.getExpressions().get(0)); bitwiseAnd.setRightExpression(parameters.getExpressions().get(1)); greaterThan.setLeftExpression(bitwiseAnd); } } }
这注意第二种方法需求判断当前使用的数据库是否为mysql.要不然就出笑话了。