Musim Semi DAO vs Musim Semi ORM vs Musim Semi JDBC

103

Saya sedang mempelajari teknologi akses data yang didukung oleh Spring, dan saya perhatikan bahwa itu menyebutkan beberapa opsi dan saya tidak yakin tentang perbedaan di antara mereka:

Seperti yang saya pahami, Spring JDBC menyediakan template untuk mengurangi kode boilerplate untuk mengakses database melalui cara lama yang biasa - Anda menulis kueri SQL Anda sendiri.

Spring-ORM menyediakan templat yang disederhanakan untuk mengakses database melalui teknologi ORM, seperti Hibernate, My (i) Batis, dll.

Spring-DAO sesuai situs web Spring:

Dukungan Data Access Object (DAO) di Spring ditujukan untuk memudahkan bekerja dengan teknologi akses data seperti JDBC, Hibernate atau JDO dengan cara yang konsisten

Saya agak jelas tentang ORM vs JDBC karena ditujukan untuk berbagai cara mengakses DB. Tapi Spring-DAO benar-benar membingungkan!

Adakah yang bisa menjelaskan apa sebenarnya perbedaan di antara ketiganya? Mana yang lebih disukai dalam skenario mana?

Juga, ada proyek lain yang Spring-DATAjuga tersedia ( http://projects.spring.io/spring-data/ ) Sekarang, apakah ini semacam proyek induk untuk semua teknisi akses data yang didukung oleh Spring atau itu hanya nama baru untuk Spring -DAO?

Menepuk
sumber

Jawaban:

162

Berikut adalah pengantar untuk setiap teknologi yang disebutkan.

Musim Semi-DAO

Spring-DAO bukanlah modul pegas dalam arti yang sebenarnya, melainkan konvensi yang harus mendikte Anda untuk menulis DAO, dan menulisnya dengan baik. Dengan demikian, ini tidak menyediakan antarmuka atau implementasi atau template untuk mengakses data Anda. Saat menulis DAO, Anda harus menambahkan catatan @Repositorysehingga pengecualian yang terkait dengan teknologi yang mendasarinya (JDBC, Hibernate, JPA, dll.) Secara konsisten diterjemahkan ke dalam DataAccessExceptionsubkelas yang sesuai .

Sebagai contoh, misalkan Anda sekarang menggunakan Hibernate, dan lapisan layanan Anda menangkapnya HibernateExceptionuntuk bereaksi. Jika Anda mengubah ke JPA, antarmuka DAO Anda tidak boleh berubah, dan lapisan layanan akan tetap dikompilasi dengan blok yang menangkap HibernateException, tetapi Anda tidak akan pernah memasukkan blok ini karena DAO Anda sekarang melemparkan JPA PersistenceException. Dengan menggunakan @RepositoryDAO Anda, pengecualian yang ditautkan ke teknologi yang mendasari diterjemahkan ke Spring DataAccessException; lapisan layanan Anda menangkap pengecualian ini dan jika Anda memutuskan untuk mengubah teknologi persistensi, Spring yang sama DataAccessExceptionsakan tetap dilemparkan karena spring telah menerjemahkan pengecualian asli.

Namun perlu dicatat bahwa ini memiliki penggunaan terbatas karena alasan berikut:

  1. Biasanya Anda tidak akan menangkap pengecualian persistensi, karena penyedia mungkin telah membatalkan transaksi (bergantung pada subtipe pengecualian persisnya), dan karenanya Anda tidak boleh melanjutkan eksekusi dengan jalur alternatif.
  2. Hierarki pengecualian biasanya lebih kaya di penyedia Anda daripada yang disediakan Spring, dan tidak ada pemetaan pasti dari satu penyedia ke penyedia lainnya. Mengandalkan ini berbahaya. Namun @Repository, sebaiknya beri anotasi pada DAO Anda dengan , karena kacang akan ditambahkan secara otomatis oleh prosedur pemindaian. Lebih lanjut, Spring dapat menambahkan fitur berguna lainnya ke anotasi.

Musim Semi-JDBC

Spring-JDBC menyediakan kelas JdbcTemplate, yang menghapus kode pipa dan membantu Anda berkonsentrasi pada kueri dan parameter SQL. Anda hanya perlu mengkonfigurasinya dengan a DataSource, dan Anda kemudian dapat menulis kode seperti ini:

int nbRows = jdbcTemplate.queryForObject("select count(1) from person", Integer.class);

Person p = jdbcTemplate.queryForObject("select first, last from person where id=?", 
             rs -> new Person(rs.getString(1), rs.getString(2)), 
             134561351656L);

Spring-JDBC juga menyediakan JdbcDaoSupport, yang dapat Anda kembangkan untuk mengembangkan DAO Anda. Ini pada dasarnya mendefinisikan 2 properti: Sumber Data dan JdbcTemplate yang keduanya dapat digunakan untuk mengimplementasikan metode DAO. Ini juga menyediakan penerjemah pengecualian dari pengecualian SQL ke dataAccessExceptions musim semi.

Jika Anda berencana menggunakan jdbc biasa, ini adalah modul yang perlu Anda gunakan.

Spring-ORM

Spring-ORM adalah modul payung yang mencakup banyak teknologi persistensi, yaitu JPA, JDO, Hibernate, dan iBatis. Untuk setiap teknologi ini, Spring menyediakan kelas integrasi sehingga setiap teknologi dapat digunakan mengikuti prinsip konfigurasi Spring, dan terintegrasi dengan lancar dengan manajemen transaksi Spring.

Untuk setiap teknologi, konfigurasi pada dasarnya terdiri dari menginjeksi DataSourcekacang ke dalam sejenis kacang SessionFactoryatau EntityManagerFactorydll. Untuk JDBC murni, tidak diperlukan kelas integrasi seperti itu (selain JdbcTemplate), karena JDBC hanya mengandalkan DataSource.

Jika Anda berencana menggunakan ORM seperti JPA atau Hibernate, Anda tidak memerlukan spring-jdbc, tetapi hanya modul ini.

Spring-Data

Spring-Data adalah proyek payung yang menyediakan API umum untuk menentukan cara mengakses data (anotasi DAO +) dengan cara yang lebih umum, mencakup sumber data SQL dan NOSQL.

Ide awalnya adalah untuk menyediakan teknologi sehingga pengembang menulis antarmuka untuk DAO (metode finder) dan kelas entitas dengan cara agnostik teknologi dan, berdasarkan konfigurasi saja (penjelasan tentang DAO & entitas + konfigurasi pegas, baik itu xml- atau berbasis java), memutuskan teknologi implementasi, baik itu JPA (SQL) atau redis, hadoop, dll. (NOSQL).

Jika Anda mengikuti konvensi penamaan yang ditentukan oleh spring untuk nama metode finder, Anda bahkan tidak perlu menyediakan string kueri yang sesuai dengan metode finder untuk kasus yang paling sederhana. Untuk situasi lain, Anda harus menyediakan string kueri di dalam anotasi pada metode finder.

Saat konteks aplikasi dimuat, pegas menyediakan proxy untuk antarmuka DAO, yang berisi semua kode boilerplate yang terkait dengan teknologi akses data, dan memanggil kueri yang dikonfigurasi.

Spring-Data berkonsentrasi pada teknologi non-SQL, tetapi masih menyediakan modul untuk JPA (satu-satunya teknologi SQL).

Apa berikutnya

Mengetahui semua ini, Anda sekarang harus memutuskan apa yang akan dipilih. Kabar baiknya di sini adalah Anda tidak perlu membuat pilihan akhir yang pasti untuk teknologi tersebut. Di sinilah sebenarnya kekuatan Spring berada: sebagai pengembang, Anda berkonsentrasi pada bisnis saat Anda menulis kode, dan jika Anda melakukannya dengan baik, mengubah teknologi yang mendasarinya adalah detail implementasi atau konfigurasi.

  1. Tentukan model data dengan kelas POJO untuk entitas, dan dapatkan / setel metode untuk mewakili atribut entitas dan hubungan dengan entitas lain. Anda pasti perlu membuat anotasi kelas entitas dan bidang berdasarkan teknologi, tetapi untuk saat ini, POJO sudah cukup untuk memulai. Konsentrasi saja pada kebutuhan bisnis untuk saat ini.
  2. Tentukan antarmuka untuk DAO Anda. 1 DAO mencakup tepat 1 entitas, tetapi Anda pasti tidak memerlukan DAO untuk masing-masing entitas, karena Anda harus dapat memuat entitas tambahan dengan menavigasi hubungan. Tentukan metode finder mengikuti konvensi penamaan yang ketat.
  3. Berdasarkan ini, orang lain bisa mulai mengerjakan lapisan layanan, dengan tiruan untuk DAO Anda.
  4. Anda mempelajari berbagai teknologi persistensi (sql, no-sql) untuk menemukan yang paling sesuai dengan kebutuhan Anda, dan memilih salah satunya. Berdasarkan ini, Anda membuat anotasi entitas dan mengimplementasikan DAO (atau membiarkan spring mengimplementasikannya untuk Anda jika Anda memilih untuk menggunakan spring-data).
  5. Jika persyaratan bisnis berkembang dan teknologi akses data Anda tidak cukup untuk mendukungnya (katakanlah, Anda memulai dengan JDBC dan beberapa entitas, tetapi sekarang membutuhkan model data yang lebih kaya dan JPA adalah pilihan yang lebih baik), Anda harus mengubah penerapannya DAO Anda, tambahkan beberapa anotasi pada entitas Anda dan ubah konfigurasi pegas (tambahkan definisi EntityManagerFactory). Kode bisnis Anda yang lain seharusnya tidak melihat dampak lain dari perubahan Anda.

Catatan: Manajemen Transaksi

Spring menyediakan API untuk manajemen transaksi. Jika Anda berencana menggunakan pegas untuk akses data, Anda juga harus menggunakan pegas untuk manajemen transaksi, karena keduanya terintegrasi dengan sangat baik. Untuk setiap teknologi akses data yang didukung oleh pegas, ada pengelola transaksi yang cocok untuk transaksi lokal, atau Anda dapat memilih JTA jika Anda membutuhkan transaksi terdistribusi. Semuanya menerapkan API yang sama, sehingga (sekali lagi) pilihan teknologi hanyalah masalah konfigurasi yang dapat diubah tanpa berdampak lebih jauh pada kode bisnis.

Catatan: Dokumentasi musim semi

Tautan ke dokumentasi Spring yang Anda sebutkan agak lama. Berikut adalah dokumentasi dari rilis terbaru (4.1.6, mencakup semua topik):

Spring-data bukan bagian dari framework Spring. Ada modul umum yang harus Anda baca terlebih dahulu agar terbiasa dengan prinsip. Dokumentasi dapat ditemukan di sini:

Gaetan
sumber
Saya menghargai Jawaban ini menggunakan istilah "payung" dalam beberapa uraian di sini (seperti Data Musim Semi), mengidentifikasi ada sub-komponen / modul di dalamnya (bukan payung yang lebih spesifik domain). Dan menyebutkan Spring Data sangat berguna dalam konteks di sini, meski tidak disebutkan dalam pertanyaan.
cellepo
Tidak spring-jdbcmenyediakan alat berguna lainnya yang tidak disebutkan di sini? Misalnya, menurut saya SimpleJdbcInsertsangat bersih dan berguna untuk penyisipan entri tunggal maupun massal (hingga skala yang wajar, tentu saja).
Nom1fan
3

Spring DAO ( D ata A ccess O bject): adalah objek yang menyediakan antarmuka abstrak untuk kerangka implementasi JDBC yaitu Spring DAO adalah konsep umum untuk mengakses JDBC dan Hibernate, MyBatis, JPA, JDO menggunakan kelas Dukungan individualnya. Dan itu menyediakan hierarki pengecualian umum dengan mendefinisikan @Repositoryanotasi. Anotasi ini mendefinisikan penampung Spring untuk terjemahan pengecualian SQL dari hierarki SQLExceptionstrategi-agnostik akses data Spring DataAccessException.

yaitu pengecualian khusus platform adalah tangkapan dan kemudian lemparan ulang sebagai salah satu pengecualian akses data yang tidak dicentang Spring.


Spring JDBC : Untuk JDBC biasa kami menggunakan modul ini, yang hanya bergantung pada DataSourcedan kelas Templat seperti JdbcTemplate, NamedParameterJdbcTemplate(membungkus JdbcTemplate) dan SimpleJdbcTemplateuntuk mengurangi masalah lintas sektor.

public class EmployeeDao {  
private JdbcTemplate jdbcTemplate;  

public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {  
    this.jdbcTemplate = jdbcTemplate;  
}  

public int saveEmployee(Employee e){  
    return jdbcTemplate.update(query);  
}  
public int updateEmployee(Employee e){  
    return jdbcTemplate.update(query);  
}  
public int deleteEmployee(Employee e){  
       return jdbcTemplate.update(query);  
}  

}  

dan di Spring XML:

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource"/>
</bean>

Semi JDBC juga menyediakan JdbcDaoSupport, NamedParameterJdbcDaoSupport, SimpleJdbcDaoSupport, yang mendukung (yaitu nyaman ) cara untuk memperpanjang dan mengembangkan kita sendiri DAO antarmuka abstrak sebagai berikut:

public interface EmployeeDao {

    public void saveEmployee(Employee emp);
}

public class EmployeeDaoImpl extends JdbcDaoSupport implements EmployeeDao{

    @Override
    public void saveEmployee(Employee emp) {

        Object[] inputs = new Object[] {emp.getName(), emp.getSalary(), emp.getDept()};
        getJdbcTemplate().update(query, inputs);
    }
}

dan di musim semi XML:

<bean id="employeeDAO" class="EmployeeDaoImpl">
        <property name="dataSource" ref="dataSource" />
    </bean>

Spring ORM: Untuk dukungan alat ORM seperti Hibernate, JPA, MyBatis ... dengan mudah mengintegrasikan Spring dengan menyuntikkan DataSourcebersama dengan kelas berikut dan masing-masing DaoSupportkelas.

  • SessionFactory untuk Hibernate
  • EntityManagerFactory untuk JPA,
  • SqlSessionFactory untuk MyBatis
Premraj
sumber
1

Spring-dao lib berhenti di versi 2.0.8 (Januari 2008). Kelas di spring-dao disalin ke spring-tx. Jadi, jika Anda membutuhkan kelas yang Anda temukan di spring-dao, tambahkan dependensi ke spring-tx sebagai gantinya. ( Sumber .)

Paulo Merson
sumber
0

Anda membuat antarmuka seperti SomeObjectDaodan kemudian membuat implementasi yang berbeda dari antarmuka ini seperti JdbcSomeObjectDao, HibernateSomeObjectDao. Kemudian di SomeObjectServicekelas Anda, Anda akan beroperasi pada SomeObjectDaoantarmuka, dan memasukkan salah satu implementasi konkret di sana. Jadi setiap implementasi SomeObjectDaoakan menyembunyikan detailnya, apakah Anda menggunakan JDBC, atau ORM, dll.

Biasanya JDBC, dan implementasi ORM yang berbeda memunculkan jenis pengecualian yang berbeda. Dukungan DAO Spring dapat memetakan pengecualian khusus teknologi yang berbeda tersebut ke pengecualian Spring DAO yang umum. Jadi, Anda lebih dipisahkan dari implementasi yang sebenarnya. Juga dukungan DAO Spring menawarkan sekumpulan *DataSupportkelas abstrak yang bahkan lebih membantu dalam pengembangan DAO. Jadi selain mengimplementasikan SomeObjectDaoantarmuka Anda, Anda dapat memperluas salah satu *DataSupportkelas Spring .

mike_m
sumber
Jadi maksud Anda, spring-dao memisahkan pengecualian khusus untuk Hibernate / JDO / JDBC dan menyediakan satu set standar pengecualian? Apakah ada templatesuntuk mengakses db? atau hanya abstraksi untuk digunakan dengan komponen pegas lainnya? Misalnya, apakah mungkin untuk menulis kode yang hanya menggunakan spring-dao untuk mengakses db (tanpa menggunakan spring-jdbc, spring-orm, hibernate atau framework lainnya)?
Tepuk
0

Sebagai info tambahan. Saya sarankan Anda menggunakan Spring Data JPA. Menggunakan anotasi seperti: @Repository, @Service. Saya tunjukkan contoh:

@Repository("customerEntitlementsRepository")
public interface CustomerEntitlementsRepository extends CrudRepository<BbsExerul, BbsExerulPK> {

  @Query(value = "SELECT " + "CONTRACT_NUMBER, EXECUTIVE_NUMBER, " + "GROUP_VALUE, " + "CODE, "
      + "SUBCODE, " + "CURRENCY " + "FROM BBS_EXERUL " + "WHERE CONTRACT_NUMBER =:clientId AND "
      + "EXECUTIVE_NUMBER =:representativeId", nativeQuery = true)
  Collection<CustomerEntitlementsProjection> getFieldsExerul(@Param("clientId") String clientId,
      @Param("representativeId") String representativeId);

}

Dimana CustomerEntitlementsProjection adalah proyeksi Musim Semi, terkait dengan entitas Anda atau DTO pojo;

@Projection(name = "customerEntitlementsProjection", types = { BbsExerul.class })
public interface CustomerEntitlementsProjection {

  String getContractNumber();

  String getExecutiveNumber();
Brandon Osorio
sumber
1
Harap format kode Anda dalam blok kode agar dapat dibaca.
Kinerja Tertentu