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.要不然就出笑話了。
