简体   繁体   English

如何转义 Hibernate 的 HQL 中的保留字

[英]How to escape reserved words in Hibernate's HQL

I use the following query to get a java.util.Map with indexes id , text and object :我使用以下查询获取java.util.Map索引idtextobject

Query q = mySession.createQuery(
    "SELECT u.id AS id, u.name AS text, u AS object FROM User u")
    .setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);

... but object seems to be a reserved word. ...但是object似乎是一个保留字。 For example obj is OK.例如obj就可以了。 What is the current way to escape an alias in HQL the way MySQL uses backtick escapes?当前在 HQL 中转义别名的方式是 MySQL 使用反引号转义的方式是什么?

Using backtick gives the following error:使用反引号会出现以下错误:

Exception in thread "main" org.hibernate.QueryException: unexpected char: 
'`' [SELECT u.id AS id, u.name AS text, u AS `object` FROM User u]

You could achieve it by a workaround using your custom "alias to map" transformer, so your code would change to something like this 您可以通过使用自定义“别名映射”转换器的解决方法来实现它,因此您的代码将更改为此类型

Query q = mySession.createQuery(
    "SELECT u.id AS id, u.name AS text, u AS obj FROM User u")
    .setResultTransformer(
        AliasToMapTransformer.renameAlias("obj", "object").build()
    );

And then using this class: 然后使用这个类:

public class AliasToMapTransformer extends BasicTransformerAdapter {

    private Map<String, String> renameAliasMap;


    public AliasToMapTransformer(Map<String, String> renameAliasMap) {
        this.renameAliasMap = (renameAliasMap == null) ? Collections.<String, String>emptyMap() : renameAliasMap;
    }


    @Override
    public Object transformTuple(Object[] tuple, String[] aliases) {
        Map<String, Object> result = new HashMap<String, Object>(tuple.length);
        for (int i = 0; i < tuple.length; i++) {
            String alias = aliases[i];
            if (alias != null) {
                String newAlias = renameAliasMap.get(alias);

                result.put((newAlias != null) ? newAlias : alias, tuple[i]);
            }
        }
        return result;
    }


    public static Builder renameAlias(String alias, String newAlias) {
        return new Builder().renameAlias(alias, newAlias);
    }


    public static class Builder {

        private Map<String, String> aliasConversionMap = new HashMap<String, String>();


        public Builder renameAlias(String alias, String newAlias) {
            aliasConversionMap.put(alias, newAlias);
            return this;
        }


        public AliasToMapTransformer build() {
            return new AliasToMapTransformer(aliasConversionMap);
        }
    }
}

On a related topic, escaping a reserved word in a column name is as easy as prepending with a table alias. 在相关主题上,转义列名中的保留字就像使用表别名前置一样简单。 No backticks, square brackets, etc. Simply replace 没有反引号,方括号等。只需更换

select where from mytable

by: 通过:

select t.where from mytable t

(note: i'm NOT saying it's a good idea to have "where" as column name ;-) (注意:我不是说将“where”作为列名称是个好主意;-)

the back tics concept works in hibernate.. unfortunately this only works if you've done annotation config... 后面的抽搐概念在hibernate中起作用..不幸的是,这只有在你完成注释配置时才有效...

you can try to do this in a different way (without annotations). 您可以尝试以不同的方式执行此操作(无需注释)。

Query q = session.createQuery("select new User (u.id, u.name, u.object) from User u").list();

here you need to create a constructor in use which accepts an id, name, object elements & in that order. 在这里,您需要创建一个使用中的构造函数,该构造函数接受id,name,object元素并按此顺序。

Do backticks not work on aliases? 反引号不能用于别名吗? The Hibernate documentation says to use them for fields. Hibernate文档说它们将它们用于字段。

Other questions: 其他问题:

  • Is another value possible? 另一个价值可能吗?
  • Why a map (it also contains the original value) and not a List? 为什么地图(它也包含原始值)而不是List? Id and Name could be retrieved from the original Object. 可以从原始对象中检索Id和Name。

Ok, i'm really late on this question but since the above solutions didn't work for me i thought i'd post the solution that did.好吧,我真的迟到了这个问题,但由于上述解决方案对我不起作用,我想我会发布解决方案。

Our issue was a field named "row".我们的问题是一个名为“行”的字段。 The solution depending on xml or annotation would be:取决于 xml 或注释的解决方案是:

@Column(name="`row`")
private String row;
<property name="row" column="`row`" access="field" not-null="true"/>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM