【问题标题】:How to obtain hibernate generated sql without aliases如何获取没有别名的hibernate生成的sql
【发布时间】:2020-01-15 12:32:40
【问题描述】:

我正在研究一个具有给定条件的函数,它返回 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);
       }
    }

得到:

    select this_.CAR_KEY as CAR_11_0_ from DATABASE.CAR this_

预期:

    select CAR_KEY from DATABASE.CAR

提前致谢

【问题讨论】:

  • 为什么这对你很重要?
  • 因为我需要将整个 SQL 传递给一个 JASPER 文件,然后打印报告而不是传递对象列表或其他东西

标签: java sql hibernate criteria


【解决方案1】:

声明字段“sql”的默认 Java 实现是您得到的那个,我认为没有一种简单的方法可以将其更改为您想要的方式。

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

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

结果将是:

从 DATABASE.CAR 中选择 CAR_KEY

【讨论】:

  • 我想用另一种方式(如果可能的话),不替换字符串,但感谢您的帮助
【解决方案2】:

在一般情况下,您不能删除休眠生成的别名。

假设我们有以下实体:

@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 文章进一步阐明了这个问题。

【讨论】:

  • 谢谢你的解释,我去看看!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多