一、继承MySQL5Dialect并注册自定义函数
public class CustomMysql5Dialect extends MySQL5InnoDBDialect {
public CustomMysql5Dialect() {
super();
registerFunction("bitand", new SQLFunctionTemplate(IntegerType.INSTANCE, "(?1 & ?2)"));
registerFunction("bitor", new SQLFunctionTemplate(IntegerType.INSTANCE, "(?1 | ?2)"));
registerFunction("bitxor", new SQLFunctionTemplate(IntegerType.INSTANCE, "(?1 ^ ?2)"));
}
}
二、使用自定义方言,这里是springboot方式集成,直接在配置文件中配置
spring:
datasource:
platform: mysql
#............
jpa:
database-platform: com.iqiping.adware.web.config.CustomMysql5Dialect
三、继承BasicFunctionExpression并覆盖render方法,将条件表达式渲染成功SQL。
public class BitOperationFunction extends BasicFunctionExpression<String>
implements Serializable {
public static final String FUNC_AND = "bitand"; //与
public static final String FUNC_OR = "bitor"; //或
public static final String FUNC_XOR = "bitxor"; //非
private final Expression value1;
private final Expression value2;
public BitOperationFunction(
final String function,
CriteriaBuilderImpl criteriaBuilder,
Expression value1,
Expression value2) {
super( criteriaBuilder, String.class, function);
this.value1 = value1;
this.value2 = value2;
}
public BitOperationFunction(
final String function,
CriteriaBuilderImpl criteriaBuilder,
Expression value1,
int value2) {
this(
function,
criteriaBuilder,
value1,
new LiteralExpression<Integer>( criteriaBuilder, value2 )
);
}
public BitOperationFunction(
final String function,
CriteriaBuilderImpl criteriaBuilder,
int value1,
int value2) {
this(
function,
criteriaBuilder,
new LiteralExpression<Integer>( criteriaBuilder, value1 ),
new LiteralExpression<Integer>( criteriaBuilder, value2 )
);
}
public Expression getValue1() {
return value1;
}
public Expression getValue2() {
return value2;
}
@Override
public void registerParameters(ParameterRegistry registry) {
Helper.possibleParameter( getValue1(), registry );
Helper.possibleParameter( getValue2(), registry );
}
public String render(RenderingContext renderingContext) {
renderingContext.getFunctionStack().push( this );
try {
final StringBuilder buffer = new StringBuilder();
buffer.append(getFunctionName())
.append("(")
.append( ( (Renderable) getValue1() ).render( renderingContext ) )
.append( ',' )
.append( ( (Renderable) getValue2() ).render( renderingContext ) )
.append( ')' );
return buffer.toString();
}
finally {
renderingContext.getFunctionStack().pop();
}
}
}
四、使用自定义函数表达式添加QBC查询条件
Pageable pageable = PageRequest.of(0, 10, Sort.by(Sort.Order.asc("id")));
org.springframework.data.domain.Page<AppStore> appStores = appStoreDao.findAll(new Specification<AppStore>() {
@Override
public Predicate toPredicate(Root<AppStore> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
List<Predicate> predicates = new ArrayList<Predicate>();
BitOperationFunction expression = new BitOperationFunction(BitOperationFunction.FUNC_OR,(CriteriaBuilderImpl)cb,root.get("position") , 1);
predicates.add(cb.equal(expression, 1));
return cb.and(predicates.toArray(new Predicate[predicates.size()]));
}
}, pageable);
开启后台打印SQL查看
Hibernate: select xxx from app_store appstore0_ where (appstore0_.position | 1)=1 order by appstore0_.id asc limit ?
可以参考自带FunctionExpression实现源码