代码之家  ›  专栏  ›  技术社区  ›  Oleksandr Samsonov

如何使用Hibernate转换平面结果集

  •  3
  • Oleksandr Samsonov  · 技术社区  · 8 年前

    是否可以将SQL的结果映射到非平面对象?

    List<Customer> customers = hibernateSession().createCriteria(CustomerDetailsView.class)
                    .add(Restrictions.in("userName", userName))
                    .setProjection(buildProjection())
                    .setResultTransformer(Transformers.aliasToBean(Customer.class))
                    .list();
    

    在我的情况下 客户详细信息视图 具有扁平结构。但我需要将它映射到这样的对象:

    public class Customer {
        private String userName;
        private String title;
        private String firstName;
        private String lastName;
        private String type;
        private String companyName;
        private AddressDetails addressDetails;
    }
    

    public class AddressDetails {
        private String countryCode;
        private String addressLine1;
        private String zipOrPostCode;
        private String city;
        private String countryDivisionName;
        private String countryDivisionCode;
        private String countryDivisionTypeCode;
        private String residentialAddress;
    }
    
    1 回复  |  直到 8 年前
        1
  •  4
  •   v.ladynev    6 年前

    是的,这是可能的。您可以使用自定义变压器: FluentHibernateResultTransformer .

    您可以复制粘贴代码,或通过Maven添加jar: fluent-hibernate-core .

    你需要使用 Criteria 具有 Projections 。请不要忘记指定投影别名( userName , addressDetails.countryCode )

    Criteria criteria = session.createCriteria(Customer.class);
    criteria.createAlias("addressDetails", "addressDetails", JoinType.LEFT_OUTER_JOIN);
    
    criteria.setProjection(Projections.projectionList()
            .add(Projections.property("userName").as("userName"))
            .add(Projections.property("addressDetails.countryCode")
            .as("addressDetails.countryCode")));
    
    List<Customer> customers = criteria.setResultTransformer(
            new FluentHibernateResultTransformer(Customer.class)).list();
    

    与HQL一起使用

    它不可能与HQL一起使用,因为Hibernate不允许HQL中的嵌套别名

    select addressDetails.countryCode as addressDetails.countryCode

    这将是一个错误 地址详细信息.国家代码 别名

    与本机SQL一起使用

    该转换器可用于具有嵌套投影的本地SQL(与HQL相反)。 在这种情况下,需要使用带引号的别名:

    String sql = "select c.f_user_name as userName, d.f_country_code as \"addressDetails.countryCode\" "
            + "from customers c left outer join address_details d on c.fk_details = d.f_pid";
    
    List<Customer> customers = session.createSQLQuery(sql)
            .setResultTransformer(new FluentHibernateResultTransformer(Customer.class))
            .list();