如何获取没有别名的休眠生成的sql

问题描述 投票:2回答:2

我正在使用具有给定条件的函数,该函数返回sql,但是我使用条件别名获取sql。因此,有什么方法可以保留数据库中的原始列名,而不是用别名替换吗?

功能:

    public String getReportSQL(Criteria criteria) {
        try {
            CriteriaImpl c = (CriteriaImpl) criteria;
            SessionImpl s = (SessionImpl)c.getSession();
            SessionFactoryImplementor factory = (SessionFactoryImplementor)s.getSessionFactory();
            String[] implementors = factory.getImplementors( c.getEntityOrClassName() );
            CriteriaLoader loader = new CriteriaLoader((OuterJoinLoadable)factory.getEntityPersister(implementors[0]),
                    factory, c, implementors[0], s.getLoadQueryInfluencers());

            Field f = OuterJoinLoader.class.getDeclaredField("sql");
            f.setAccessible(true);
            return (String) f.get(loader);
       } catch(Exception e){
           throw new RuntimeException(e);
       }
    }

Got:

    select this_.CAR_KEY as CAR_11_0_ from DATABASE.CAR this_

预期:

    select CAR_KEY from DATABASE.CAR

提前感谢

java sql hibernate criteria
2个回答
1
投票

已声明字段“ sql”的默认Java实现就是您所获得的,我认为没有一种简单的方法可以将其更改为所需的方式。

我的建议是解析您收到的字符串。

return ((String) f.get(loader)).replaceAll("this_.", "").replaceAll("this_", "").replaceAll("( as \\w)\\w+", "")

结果将是:

从DATABASE.CAR中选择CAR_KEY


1
投票

在一般情况下,您无法删除由休眠生成的别名。

想象我们有以下实体:

@Entity
@Table(name = "TEST_MESSAGE")
public class Message
{
   @Id
   @Column(name = "MSG_ID")
   private Long id;

   @Column(name = "MSG_TEXT")
   private String text;

   @ManyToOne
   @JoinColumn(name="MSG_PARENT_ID")
   private Message parent;

   ...
}

和以下条件查询:

   CriteriaBuilder builder = session.getCriteriaBuilder();
   CriteriaQuery<Tuple> criteria = builder.createQuery(Tuple.class);
   Root<Message> root = criteria.from(Message.class);

   Path<Long> id = root.get("id");
   Path<Message> parent = root.get("parent");

   criteria.multiselect(id, parent);
   criteria.where( builder.equal( root.get("id"), 2) );
   List<Tuple> tuples = session.createQuery( criteria ).getResultList();

   ...

Hibernate将为其生成以下SQL:

select
   message0_.MSG_ID as col_0_0_,
   message0_.MSG_PARENT_ID as col_1_0_,
   message1_.MSG_ID as MSG_ID1_0_,
   message1_.MSG_PARENT_ID as MSG_PARENT_ID3_0_,
   message1_.MSG_TEXT as MSG_TEXT2_0_ 
from TEST_MESSAGE message0_ 
inner join TEST_MESSAGE message1_ on message0_.MSG_PARENT_ID = message1_.MSG_ID 
where message0_.MSG_ID = 2

如您所见,如果我们仅删除所有别名(message0_message1_,...),则查询将无效。 This文章进一步阐明了这个问题。

© www.soinside.com 2019 - 2024. All rights reserved.