2011-11-03 15 views
10

Tengo un sistema de base de datos heredado realmente feo con el que necesito integrar. Esencialmente estoy haciendo informes de solo lectura en el sistema, y ​​no quiero configurar mil entidades que representen cada una de las tablas en las que estoy trabajando. En cambio, me gustaría simplemente definir una Entidad para cada uno de los tipos de informes que genero (esencialmente una unión de un grupo de columnas de diferentes tablas), y luego dejar hibernar el mapa de lo desagradable (muchos se unieron, muchos se unieron) consulta sql a una lista de tales entidades.Entidades Hibernate sin tablas subyacentes

La pregunta es: ¿puedo crear una entidad que no tenga una tabla subyacente y usar una declaración SQL para completar una lista de dichas entidades?

Gracias!

Respuesta

8

hacemos ese tipo de cosas todo el tiempo - y aquí es cómo lo hacemos:

  1. Definir un simple objeto bean-como para representar cada fila de salida en su informe:

    public class CityStateRevenueReport { 
    
        private String mId; 
        private String mState; 
        private String mCity; 
        private Double mRevenue; 
    
        public String getId() { return mId; } 
        public void setId(String i) { mId = i; } 
        public String getState() { return mState; } 
        public void setState(String s) { mState = s; } 
        public String getCity() { return mCity; } 
        public void setCity(String c) { mCity = c; } 
        public Double getReveneue() { return mRevenue; } 
        public void setRevneue(Double d) { mRevenue = d; } 
    } 
    
  2. Definir un archivo de asignación de hibernación, CityStateRevneueReport.hbm.xml:

    <?xml version="1.0" ?> 
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd&quot;> 
    <hibernate-mapping> 
        <class entity-name="CityStateRevenueReport"> 
         <id name="Id" type="java.lang.String" column="report_id"> 
          <generator class="sequence" /> 
         </id> 
         <property name="city" type="string" column="city" /> 
         <property name="state" type="string" column="state" /> 
         <property name="revenue" type="double" column="revenue" /> 
        </class> 
        <sql-query name="runReport"> 
         <![CDATA[ 
         SELECT {r.*} FROM 
          (select some_id_value as report_id, 
            state_abbreviation as state, 
            city_name as city, 
            dollar_amount as revenue 
           from -- tables, joins, other SQL insanity 
          ) r 
         ]]> 
         <return alias="r" class="CityStateRevenueReport" /> 
        </sql-query> 
    </hibernate-mapping> 
    
  3. A continuación, ejecute la consulta y poblar casos:

    public List<CityStateRevenueReport> runReport() { 
    
        List<CityStateRevenueReport> reports = 
              new ArrayList<CityStateRevenueReport>(); 
        List<HashMap> maps = session.getNamedQuery("runReport").list() 
        for (HashMap map : results) { 
         CityStateRevenueReport report = new CityStateRevenueReport(); 
         report.setState(map.get("state")); 
         report.setCity(map.get("city")); 
         report.setRevenue(Double.parseDouble(map.get("revenue")); 
         reports.add(report); 
        } 
        return reports; 
    } 
    
+0

Cambié a esta respuesta porque usa Hibernate y responde mejor a la pregunta original. – idbentley

+0

En la clase de asignación de hibernación, debe usar "nombre" en lugar de "nombre de entidad" e hibernación podrá crear los objetos de resultado por sí mismo, sin el código repetitivo para crearlos manualmente. Sería bueno si esto se pudiera hacer solo con anotaciones, pero no pude encontrar la manera. –

3

utilizar una consulta Entidad:

http://docs.jboss.org/hibernate/core/3.3/reference/en/html/querysql.html#d0e13696

sess.createSQLQuery("SELECT ID, NAME, BIRTHDATE FROM CATS").addEntity(Cat.class); 

o crear una vista en la base de datos y mapa en contra.

Aquí hay un tutorial más largo usando addEntity:

http://timezra.blogspot.com/2009/05/mapping-hibernate-entities-to-views.html

private Collection<AuthorAggregate> findByFirstName() { 
    return sessionFactory.getCurrentSession() // 
      .createSQLQuery(AUTHORS_BY_FIRST_NAME) // 
      .addEntity(AuthorAggregate.class) // 
      .list(); 
} 
2

Si usted es libre de elegir hibernación o no, le sugiero que tome un vistazo a Spring JDBC. es más liviano que hibernar y hace bien el trabajo. Con sus requisitos se adaptará muy bien a la imagen.

+0

muchas gracias - esto parece una solución mucho mejor para mis necesidades. – idbentley

Cuestiones relacionadas