【问题标题】:how to return Map<Key, Value> with HQL如何使用 HQL 返回 Map<Key, Value>
【发布时间】:2011-12-14 04:08:20
【问题描述】:

我有一张桌子

权限

  • 身份证
  • 姓名
  • 描述

我现在在做什么 是进行一个返回权限对象的查询,然后以编程方式将值放入映射中

1- 但我想知道是否可以制作 HQL(或本地 sql,如果不可能)来选择 permission_idpermission_name 并在地图中返回它们.

2- 是否可以以一对多的关系返回地图,而不是跟随列表或集合

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinTable(name = "perm_cat_map", joinColumns = { @JoinColumn(name = "perm_cat_id") }, inverseJoinColumns = { @JoinColumn(name = "permission_id") })
    private List<Permission> permissions = new ArrayList<Permission>(0);

是否有可能有类似的东西:

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
        @JoinTable(name = "perm_cat_map", joinColumns = { @JoinColumn(name = "perm_cat_id") }, inverseJoinColumns = { @JoinColumn(name = "permission_id") })
        private Map<String,String> permissions = new ArrayList<String,String>(0);

这两个字符串分别是permission_idpermission_name

【问题讨论】:

    标签: hibernate hql hibernate-mapping


    【解决方案1】:

    在 JPA 2.0(最新版本的 Hibernate 支持)中,您可以使用 @ElementCollection 注释映射基元集合。

    有关此类映射的一些示例,请参阅the hibernate collections docs

    如果您实际上并未以这种方式对其进行映射,而是想使用 HQL 或 Criteria 查询创建映射,则可以创建 ResultTransformer 以从返回的结果集中创建映射。

    从 Xavi 的回答来看,我猜 HQL 中也支持在不使用转换器的情况下创建地图。

    【讨论】:

    • 我更新了我的第二个问题,请您给我一些建议。
    【解决方案2】:
    String sqlQuery="select userId,name,dob from user"
    

    将查询传递给以下方法。

    public List<Map<String,Object>> getDataListBySQL(final String sql, final Long adId){
    
        List<Map<String,Object>> list=(List<Map<String,Object>>)getHibernateTemplate().executeFind(new HibernateCallback() {
            public Object doInHibernate(Session session) throws HibernateException,SQLException {
                Query query=session.createSQLQuery(sql);
                query.setParameter("adId", adId);               
                return query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list();
            }
        }); 
        return list;
    }
    
    Iterate this list in this way-
    for(int i=0;i<list.size();i++){
    
            Map<String,Object> map=list.get(i);
    
            System.out.println(map.get("userId"));
            System.out.println(map.get("name"));
        }
    

    【讨论】:

      【解决方案3】:

      试试这样,

      Session session = sessionFactory.getCurrentSession();
      String HQL_QUERY = "select new map(user.id as id, user.firstName as fullName) from User user";        
      List<Map<String,String>> usersList = session.createQuery(HQL_QUERY).list(); 
      

      【讨论】:

        【解决方案4】:
        1. 使用 HQL 中的 select new map 语法来获取 Map 中每一行的结果。请看以下解决该问题的问题:How to fetch hibernate query result as associative array of list or hashmap。 例如,以下 HQL:select new map(perm.id as pid, perm.name as pname) from Permission perm 将返回 ListMaps,每个都有键“pid”和“pname”。

        2. 无法将关联映射到Map&lt;String, String&gt;。可以将 Map 的键映射到关联中带有 @MapKeyColumn 注释的列。请参阅这个问题,它也解决了这个问题,例如:JPA 2.0 Hibernate @OneToMany + @MapKeyJoinColumnHere 是另一个例子。

        @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) @JoinTable(name = "perm_cat_map", joinColumns = { @JoinColumn(name = "perm_cat_id") }, inverseJoinColumns = { @JoinColumn(name = "permission_id") }) @MapKeyColumn(name="permission_id") private Map<String, Permission> permissions = new HashMap<String,Permission>(0);

        【讨论】:

        • 方法的返回类型是什么?您对问题 2 有何看法?
        • 考虑到select new map HQL 语句的返回是一个映射列表,每个结果一个,其中键是别名,值是列值。如果您想获得地图,@DonRoby 关于ResultTransformer 的建议可能更符合您想要实现的目标。
        • 问题,在您上面的示例中,地图中字符串的值是多少?
        • 我将在单独的问题中问第二个问题。
        • @fresh_dev 无法将关联映射到 Map。您可以使用其中一列的类型作为键。如果是非映射实体,可以使用@MapKeyColumn。如果是映射实体,则必须使用@MapKeyJoinColumn。字符串的值将是Permission 实体中的permission_id 字段。
        【解决方案5】:

        1- 但我想知道是否可以制作 HQL(或原生 sql 如果不可能)选择permission_id、permission_name 和 在地图中返回它们。

        可以使用 Resulttransformer

        String queryString="select id, name from Permission ";
        List<List<Object>> permission= session.createQuery(queryString)
              .setResultTransformer(Transformers.TO_LIST).list();
        //now you just expect two columns 
        HashMap<Integer,String> map= new HashMap<Integer,String>();
        for(List<Object> x: permission){ 
             map.put((Integer)x.get(0),(String)x.get(1))
        }
        

        【讨论】:

          猜你喜欢
          • 2015-10-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-03-22
          • 1970-01-01
          • 2014-10-24
          相关资源
          最近更新 更多