2011-11-03 8 views
10

Ho un sistema di database legacy davvero brutto con cui ho bisogno di integrarmi. Essenzialmente sto facendo alcuni report di sola lettura sul sistema, e non voglio creare migliaia di entità che rappresentano ciascuna delle tabelle su cui sto lavorando. Invece, mi piacerebbe solo definire un'entità per ciascuno dei tipi di rapporto che generi (essenzialmente un'unione di un gruppo di colonne di tabelle diverse), e quindi lasciare che la mappa di ibernazione sia cattiva (molti uniti, molti sindacati) sql query a un elenco di tali entità.Entità di ibernazione senza tabelle sottostanti

La domanda è: posso creare un'entità che non ha una tabella sottostante e utilizzare un'istruzione sql per compilare un elenco di dette entità?

Grazie!

risposta

8

Facciamo questo genere di cose tutto il tempo - e qui è come lo facciamo:

  1. Definire un semplice oggetto di fagioli simile per rappresentare ogni fila di uscita nel rapporto:

    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. Definire un file di mapping Hibernate, 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. quindi eseguire la query e popolano le istanze:

    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

Ho cambiato questa risposta perché usa Hibernate e risponde meglio alla domanda originale. – idbentley

+0

Nella classe di mappatura di ibernazione, dovresti usare "nome" invece di "nome-entità" e ibernazione sarà in grado di creare gli oggetti risultato su di essa, senza il codice boilerplate per crearli manualmente. Sarebbe bello se questo potesse essere fatto solo con le annotazioni, ma non sono riuscito a trovare un modo. –

3

utilizzare una query Entity:

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 creare una vista nel database e mappa contro quella.

Ecco un tutorial di più utilizzando 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

Se siete liberi di scegliere in letargo o no, vi consiglio di dare un'occhiata a Spring JDBC. è più leggero di ibernazione e fa il lavoro giusto. Con le tue esigenze si adatterà perfettamente alla foto.

+0

grazie mille - questa sembra una soluzione molto migliore per le mie esigenze. – idbentley

Problemi correlati