Prenotazione dell'indipendenza del database utilizzando Spring JPA

2

Stiamo pianificando di utilizzare Spring Boot con JPA per il nostro prossimo progetto e mi chiedo quanta flessibilità dia il JPA in realtà. Se inizia sviluppando utilizzando un server PostgreSQL auto-ospitato e in seguito vuoi cambiare in Amazon RDS PostgreSQL o < strong> SQL Server , incontreremo un sacco di problemi? Sulla carta, JPA dovrebbe servire come livello di astrazione, ma se iniziamo a utilizzare tipi di dati, viste, funzioni / stored procedure specifici del database, perdiamo rapidamente la capacità di cambiare.

In generale, qual è la migliore pratica? Utilizzare solo JPA anche se ciò comporta perdite di prestazioni o difficoltà nella programmazione di database con plSQL o T-SQL e se è necessario il cambio di piattaforma, è necessario che riscriva tali funzioni.

Un altro problema sono i tipi di dati. PostgreSQL, ad esempio, può essere esteso con ltree e fornisce una buona base per strutture di dati gerarchiche, ma per utilizzarlo è necessario estendere JPA per utilizzare il tipo di dati ltree o risolvere ogni interazione con le funzioni.

    
posta appl3r 20.07.2017 - 11:08
fonte

2 risposte

3

If we start developing using a self-hosted PostgreSQL server and later want to change to Amazon RDS PostgreSQL or SQL Server, will we run into lots of problems?

Non proprio. Di recente abbiamo eseguito la migrazione da Oracle 11g a SQLServer di Azure e ci è bastato modificare alcune proprietà di Spring.

spring.datasource.url=jdbc:sqlserver://<host>:<port>;databaseName=<DB>
spring.datasource.username=<user>
spring.datasource.password=<pass>
spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.jpa.database-platform=my.project.persistence.CustomSQLServer2012Dialect

Abbiamo dovuto esaminare anche alcuni mapping. Ad esempio, abbiamo dovuto modificare @Column(name = "READ") di @Column(name = "[READ]") . Immagino che READ sia una parola riservata.

Guarda le proprietà prestando attenzione a spring.jpa.database-platform=my.project.persistence.CustomSQLServer2012Dialect .

Spring Data JPA ci consente di implementare i nostri dialetti estendere quelli forniti da Hibernate. Di solito vogliamo sfruttare le funzioni integrate e le funzionalità del server DB. Pensa a queste funzioni di data o stringa che operano a livello di database e semplificano la vita.

Guarda come possiamo incorporare queste funzioni in JPA

public class PrestigeSQLServer2012Dialect extends SQLServer2012Dialect {

    /**
     * Default constructor
     */
    public PrestigeSQLServer2012Dialect() {
        super();
        registerFunction("convertStringToDate",
                new SQLFunctionTemplate(StandardBasicTypes.DATE, "CONVERT(DATETIME,?1,?2)"));

        // Current SQLServer Date's end of month day (without time)
        registerFunction("endOfCurrentMonth", new SQLFunctionTemplate(StandardBasicTypes.DATE, "EOMONTH(GETDATE())"));

        // Current SQLServer Date's end of month. Add or Remove
        registerFunction("endOfCurrentMonthAdd",
                new SQLFunctionTemplate(StandardBasicTypes.DATE, "EOMONTH(GETDATE(),?1)"));

        // Date's end of month
        registerFunction("endOfMonth", new SQLFunctionTemplate(StandardBasicTypes.DATE, "EOMONTH(?1)"));

    }}

Più tardi possiamo usare queste funzioni con le query JPA

@Query("select kpi from KPIAccounts kpi where kpi.created between endOfCurrentMonthAdd(:months * -1) and endOfCurrentMonth()")
    Iterable<KPIAccounts> findKPIByMonthRangeBackforward(@Param("months") int months);

Troverai che Spring Data JPA è molto sofisticato e flessibile.

Generally what is the best practice? Use only JPA even if It means performance loss or dive hard into database programming with pl SQL or T-SQL and if platform change is needed, rewrites of those functions needs to happen.

Dipende totalmente dalle tue esigenze ed esigenze . Come ho commentato, di solito vogliamo approfittare di tutte le possibili funzionalità del server DB. Se ti trovi a dover supportare pienamente queste funzioni e creare query complesse, probabilmente JPA non ti aiuterà. Al contrario, genererà un sovraccarico non necessario. Gli ORM di solito non si adattano bene al primo dominio dei dati. In tal caso, i mapper di riga come JDBCTemplate o < a href="http://www.mybatis.org/mybatis-3/"> myBatis sono alternative migliori.

Le prestazioni potrebbero essere una preoccupazione in più da prendere in considerazione perché gli ORM di solito hanno prestazioni inferiori rispetto ai mappatori.

Se mi venisse chiesto, non inserirò l'attività nel DB. Non l'ho fatto durante l'ultimo decennio e neanche io ne avevo bisogno. Inserire la logica nel DB collega il business alle funzionalità del DB e limitare il modo in cui il nostro sistema si evolve. Un altro svantaggio indesiderato è il blocco del fornitore.

Trovo queste strategie per farci perdere la coesione. Un'altra preoccupazione potrebbe essere testare. Trovo difficile effettuare il test delle unità delle procedure T-SQL o pl / SQL.

Another problem is the data types. PostgreSQL, for example, can be extended with ltree and it provides a good foundation for hierarchical data structures, but to use it, one need to extend JPA to use the ltree data type or solve every interaction with functions.

Come ho già detto sopra, se si scopre che il progetto dipende in gran parte dalle funzionalità e dalle capacità del server DB, probabilmente gli ORM non sono lo strumento adatto a voi. Tuttavia, riguardo a questa domanda (tipi di dati), ho trovato diversi riferimenti su come mappare ltree strutture con JPA.

Suppongo che la domanda qui sia Dovremmo implementare gli ORM?

L'unica risposta possibile è dipende dai tuoi bisogni e requisiti . Prima di prendere una decisione, investi tempo nella ricerca e nell'implementazione di prove di prova. Prendi confidenza con i vari framework e trova quello più adatto alle tue esigenze. Non implementare i framework solo perché tutti gli altri lo fanno. Di solito è un argomento mediocre che porta a soluzioni mediocri.

    
risposta data 20.07.2017 - 14:28
fonte
0

In una buona giornata avrai a disposizione un numero sufficiente di test per eseguire la build contro qualsiasi nuovo potenziale database / ambiente per scoprire se funziona come previsto. Ci sono alcuni buoni articoli su come creare e testare con i dati di Spring.

Penso che la sua pratica abbastanza comune si basi su un database H2 in memoria ed esegua test di base contro questo, ma avrebbe anche un'istanza del mio database di destinazione in esecuzione su un server CI con test più approfonditi da testare contro il mondo reale distribuzione.

Per trarre vantaggio da specifiche funzionalità del database come l'alberello PostgreSQL che hai menzionato, sarebbe possibile costruire solo usando tipi di dati standard e magari migliorando il tuo modello per database specifici? Controlla anche se Spring data / JDBC ha il supporto per queste funzionalità e come il database stesso le implementa.

    
risposta data 20.07.2017 - 12:44
fonte

Leggi altre domande sui tag