将Oracle前导提示添加到HQL查询

时间:2017-06-20 10:16:55

标签: java oracle hibernate oracle11g hql

我想在我的hql查询中添加Leading提示但是,这个提示将像这个领先(别名),在hibernate中我不知道sql中的别名是什么,我该怎么做?

 String hql="select s.id from " + StoreHouseInventoryItem.class.getName() + "s ,"+ Storehouse.class.getName() +" ss "

我想在此查询中添加前导提示,我不知道这两个表的hibernate别名,并且需要别名。

hibernate将生成如下的sql:

select storeHouse0_.id  from app_item storeHouse0_ 
, app_str storeHouse1_

2 个答案:

答案 0 :(得分:0)

字符串连接是一个非常严重的问题,可能导致SQL Injection attacks

因此,因为您需要改变实体类型,所以需要使用Criteria API,它允许您使用org.hibernate.comment Query Hint传递SQL提示,如下所示:

CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery criteriaQuery = criteriaBuilder.createQuery();
Root employee = criteriaQuery.from(StoreHouseInventoryItem.class);
Root address = criteriaQuery.from(Storehouse.class);
criteriaQuery.multiselect(employee, address);
Query query = entityManager
    .createQuery( criteriaQuery)
    .unwrap( org.hibernate.query.Query.class )
    .setComment( "leading(storehouseinventoryitem0_, storehouse1_)" );
List<Object[]> result = query.getResultList();

您还必须启用SQL级提示:

<property
    name="hibernate.use_sql_comments"
    value="true"
/>

更新

至于知道别名,你只需运行查询并找出Hibernate为每个实体分配的别名,然后你应该在Oracle提示中使用它们。

答案 1 :(得分:0)

我做了以下工作,对我有用:

  1. 创建了一个拦截器类

    public class HibernateEntityInterceptor extends EmptyInterceptor {
    
        private static final String HINT_START = "'$HINT-";
        private static final String HINT_END = "-$HINT',";
        private static final String ORACLE_HINT_START = "/*+ ";
        private static final String ORACLE_HINT_END = " */ ";
    
        @Override
        public String onPrepareStatement(String sql) {
    
            if (sql.contains(HINT_START)) {
                String hintText = StringUtils.substringBetween(sql, HINT_START, HINT_END);
                sql = StringUtils.replace(sql, HINT_START + hintText + HINT_END, ORACLE_HINT_START + hintText + ORACLE_HINT_END);
            }
            return sql;
        }
    
        public static String hint(String hint, boolean isEnabled) {
            return isEnabled ? HINT_START + hint + HINT_END : "";
        }
    }
    
  2. 在HQL中使用了它,如下所示。在这里,我正在使用“ HASH_SJ” oracle提示。

    String hql = "select " + HibernateEntityInterceptor.hint("HASH_SJ", true) + " 1 from tableEntityA";
    
  3. 注册了拦截器

    jpaProperties.setProperty("hibernate.ejb.interceptor", "com.abc.HibernateEntityInterceptor");