org.onetwo.jpa.hibernate.HibernateJPAQueryProvideManager Maven / Gradle / Ivy
package org.onetwo.jpa.hibernate;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.sql.DataSource;
import org.hibernate.SQLQuery;
import org.hibernate.query.NativeQuery;
import org.onetwo.common.db.ParsedSqlContext;
import org.onetwo.common.db.dquery.DynamicMethod;
import org.onetwo.common.db.dquery.NamedQueryInvokeContext;
import org.onetwo.common.db.filequery.DbmNamedSqlFileManager;
import org.onetwo.common.db.filequery.func.SqlFunctionDialet;
import org.onetwo.common.db.filequery.postfunc.SqlParamterPostfixFunctions;
import org.onetwo.common.db.spi.CreateQueryCmd;
import org.onetwo.common.db.spi.FileNamedQueryFactory;
import org.onetwo.common.db.spi.NamedQueryInfoParser;
import org.onetwo.common.db.spi.QueryProvideManager;
import org.onetwo.common.db.spi.QueryWrapper;
import org.onetwo.common.db.spi.SqlParamterPostfixFunctionRegistry;
import org.onetwo.common.utils.Page;
import org.onetwo.dbm.annotation.DbmResultMapping;
import org.onetwo.dbm.core.spi.DbmInterceptor;
import org.onetwo.dbm.core.spi.DbmInterceptorChain;
import org.onetwo.dbm.jdbc.internal.DbmJdbcTemplate;
import org.onetwo.dbm.jdbc.spi.DbmJdbcOperations;
import org.onetwo.dbm.query.DbmFileQueryWrapperImpl;
import org.onetwo.dbm.query.DbmNamedFileQueryFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterUtils;
import com.google.common.collect.ImmutableList;
/**
* @author wayshall
*
*/
public class HibernateJPAQueryProvideManager implements QueryProvideManager, InitializingBean {
private DataSource dataSource;
// private NamedParameterJdbcOperations jdbcOperations;
private DbmJdbcTemplate jdbcOperations;
private SqlParamterPostfixFunctionRegistry sqlParamterPostfixFunctionRegistry = new SqlParamterPostfixFunctions();
private DbmNamedFileQueryFactory dbmNamedFileQueryFactory;
@PersistenceContext
private EntityManager entityManager;
private Collection interceptors = ImmutableList.of(new StripNullDbmInterceptor());
@Autowired
private List namedQueryInfoParsers;
public HibernateJPAQueryProvideManager(DataSource dataSource) {
super();
this.dataSource = dataSource;
// this.jdbcOperations = new NamedParameterJdbcTemplate(dataSource);
this.jdbcOperations = new DbmJdbcTemplate(dataSource);
/*DbmNamedSqlFileManager sqlFileManager = DbmNamedSqlFileManager.createNamedSqlFileManager(true);
dbmNamedFileQueryFactory = new HibernateNamedFileQueryFactory(sqlFileManager);*/
}
@Override
public void afterPropertiesSet() throws Exception {
DbmNamedSqlFileManager sqlFileManager = DbmNamedSqlFileManager.createNamedSqlFileManager(true);
sqlFileManager.setQueryInfoParsers(namedQueryInfoParsers);
dbmNamedFileQueryFactory = new HibernateNamedFileQueryFactory(sqlFileManager);
}
@Override
public Collection getRepositoryInterceptors() {
return interceptors;
}
@Override
public QueryWrapper createQuery(CreateQueryCmd createQueryCmd) {
if(createQueryCmd.isNativeSql()){
NativeQuery> sqlQuery = entityManager.createNativeQuery(createQueryCmd.getSql()).unwrap(NativeQuery.class);
// sqlQuery.getParameterMetadata().setOrdinalParametersZeroBased(true);
// sqlQuery.getParameterMetadata().setOrdinalParametersZeroBased(true);
HibernateDbmQueryWrapper wrapper = new HibernateDbmQueryWrapper(sqlQuery);
return wrapper;
}else{
throw new UnsupportedOperationException("Unsupported not native sql");
}
}
@Override
public FileNamedQueryFactory getFileNamedQueryManager() {
return dbmNamedFileQueryFactory;
}
@Override
public DbmJdbcOperations getJdbcOperations() {
return jdbcOperations;
}
@Override
public DataSource getDataSource() {
return dataSource;
}
@Override
public SqlParamterPostfixFunctionRegistry getSqlParamterPostfixFunctionRegistry() {
return sqlParamterPostfixFunctionRegistry;
}
@Override
public Optional getSqlFunctionDialet() {
return Optional.empty();
}
static class StripNullDbmInterceptor implements DbmInterceptor {
@Override
public Object intercept(DbmInterceptorChain chain) {
Object result = chain.invoke();
return stripNull(result);
}
/****
* 主要是解决hibernate下,TupleSubsetResultTransformer无法避免把返回null值不添加到结果集的问题
* @author wayshall
* @param datas
*/
private T stripNull(T datas){
if(datas instanceof Collection){
((Collection>)datas).removeIf(Objects::isNull);
}else if(datas instanceof Page){
Page> page = (Page>) datas;
page.getResult().removeIf(Objects::isNull);
}
return datas;
}
}
static class HibernateNamedFileQueryFactory extends DbmNamedFileQueryFactory {
public HibernateNamedFileQueryFactory(DbmNamedSqlFileManager sqlFileManager) {
super(sqlFileManager);
}
@Override
protected QueryWrapper newQueryWrapperInstance(boolean count, NamedQueryInvokeContext invokeContext) {
return new HiberanteFileQueryWrapperImpl(invokeContext, count);
}
}
static class HiberanteFileQueryWrapperImpl extends DbmFileQueryWrapperImpl {
public HiberanteFileQueryWrapperImpl(NamedQueryInvokeContext invokeContext, boolean count) {
super(invokeContext, count);
}
protected QueryWrapper createDataQueryIfNecessarry(){
if(dataQuery!=null){
return dataQuery;
}
ParsedSqlContext sqlAndValues = createParsedSqlContext();
QueryWrapper dataQuery = null;
if(sqlAndValues.isListValue()){
CreateQueryCmd createQueryCmd = new CreateQueryCmd(sqlAndValues.getParsedSql(), resultClass, info.isNativeSql());
dataQuery = createDataQuery(createQueryCmd);
doIndexParameters(dataQuery, sqlAndValues.asList());
}else{
Map params = processNamedParameters(sqlAndValues);
MapSqlParameterSource mps = new MapSqlParameterSource(params);
String sqlToUse = NamedParameterUtils.substituteNamedParameters(sqlAndValues.getParsedSql(), mps);
Object[] arrayParams = NamedParameterUtils.buildValueArray(NamedParameterUtils.parseSqlStatement(sqlAndValues.getParsedSql()), mps, null);
CreateQueryCmd createQueryCmd = new CreateQueryCmd(sqlToUse, resultClass, info.isNativeSql());
dataQuery = createDataQuery(createQueryCmd);
doIndexParameters(dataQuery, Arrays.asList(arrayParams));
setLimitResult(dataQuery);
}
this.dataQuery = dataQuery;
return dataQuery;
}
protected void doIndexParameters(QueryWrapper dataQuery, List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy