Hoe losse koppeling tussen JDBC-stuurprogramma's en broncode te bereiken?

Ik wil mijn code niet strak koppelen aan een JDBC-stuurprogramma (bijvoorbeeld MySQL). Ik wil universele code maken, die met veel database-implementaties kan werken. En ik begrijp niet helemaal hoe ik dit doel kan bereiken bij het gebruik van JDBC.

Ik denk dat om dit te bereiken ik alleen de naam van de stuurprogrammaklasse (en verbindingsreeks) naar het .properties -bestand (bijvoorbeeld "com.mysql.jdbc.Driver" ) moet exporteren, en dan in code gebruik je het als volgt: Class.forName (PROPERTIES.getDriverName ()). newInstance (); Dus wanneer ik besluit om mijn database te veranderen, is alles wat ik moet veranderen jdbc driver naam in .properties bestand (bijvoorbeeld naar "COM.ibm.db2.jdbc.app.DB2Driver" ), verbindingstekenreeks en de .jar bestand in klassenpad.

Is het juist?

0
@JohnFx ok, bedankt, maar als je geen aandacht besteedt aan het verschil tussen de syntaxis van sql, dus dit idee is goed? Of bestaat er misschien een meer elegante manier om dit doel te bereiken?
toegevoegd de auteur MyTitle, de bron
In theorie is dat leuk, maar in mijn ervaring (1) verander je echt geen databases behalve in uiterst zeldzame omstandigheden; (2) Het is de SQL-syntax die het moeilijk zal maken, niet de driver.
toegevoegd de auteur JohnFx, de bron
Kan het worden verplaatst naar datasource?
toegevoegd de auteur kosa, de bron
@JohnFx was het ermee eens dat de meeste mensen niet veranderen in operaties, maar mogelijk maakt hij een service die afhankelijk is van een database-backend voor externe gebruikers om deze ergens anders te downloaden en te gebruiken, maar wil hij niet dat gebruikers gedwongen worden om een ​​specifieke databank/versie.
toegevoegd de auteur Mike, de bron

4 antwoord

Loose coupling can be achieved in several ways -

A. Use Hibernate , but this may be an overkill for your needs and hurt performance (if your application performs mostly write operation)

B. Use Spring-JDBC or any other framework that serves as JDBC wrapper - usually they provide some sort of abstraction

C. If your code is Java EE code, you can work with DataSources, and configure them on your Java application server - you will lookup the data source by name, and you will not know the implementation details behind

D. You can make sure you build the application in layers - a business logic layer, that uses a data access layer, which uses some data engine (Make sure your data engine class implement an interface you so u can change implementation easily).

Your Data engine class can read the information about the jdbc driver from a configuration (properties of xml files) - this is basically what Hibernate does , for example.

3
toegevoegd
@trashgod - bedankt voor de reactie. ik ben het helemaal met je eens
toegevoegd de auteur Yair Zaslavsky, de bron
Bij benadering D kunt u overwegen de interface aan te passen aan het strategiepatroon .
toegevoegd de auteur trashgod, de bron

Je hebt het goed. Voer de naam van de stuurprogrammaklasse, de database-URL, de gebruiker en het wachtwoord uit, en alsjeblieft. Dat is hoe dan ook door de meeste "frameworks" gedaan: Java EE-servers laten het configureren van gegevensbronnen op de server toe en gebruiken deze via JNDI. Verbindingspools gebruiken hiervoor meestal hun configuratiebestand, verbindingspools gebruiken meestal een XML- of eigenschappenbestand om hun configuratie te behouden.

Natuurlijk, als u eigen SQL-code gebruikt, kunt u niet zo gemakkelijk overschakelen van de ene database naar de andere, maar dat is een ander probleem.

2
toegevoegd

Dit kan zeker voor u werken. Ik zal echter wat completer zijn voor toekomstige lezers van de vraag:

maar veel van de vragen die u schrijft, kunnen database-specifiek zijn, of vertrouwen op bepaalde zoekwoorden om effectief te zijn. Neem bijvoorbeeld een veelgestelde vraag. U wilt alle producten in een database weergeven, maar de gebruiker 10 tegelijk laten zien:

MySQL:

select * from products LIMIT 0,10

dan voor de volgende 10 rijen:

select * from products LIMIT 10,10

enz.

Fantastisch, zodat gebruikers MySQL kunnen gebruiken voor de database. Wel, wat als ze postgres gebruiken, een andere gratis en erg populaire database? Die vraag zal niet werken:

SELECT * FROM product LIMIT 10 OFFSET 10

Dus je code is niet zo veel draagbaar als je denkt.

Een manier om dit te omzeilen is om uw eigen interfaces (interfacequery, interface Access) te maken voor alle query's/toegangen die u van plan bent te doen, en dan een queryfabriek te hebben die kan instantiëren, op basis van de DB-dialect (MySQL, postgres) , enz.) en maak MySQLQueryImpl en PostGresQueryImpl aan (beide implementeren de Query-interface).

Je moet helaas een deel van de databaseaanroepen tweemaal coderen of ze zelf naar een eigenschappenbestand verplaatsen. U kunt ook de queryfactor ontwerpen om vanuit een eigenschappenbestand te instantiëren (zoals u oorspronkelijk wilt), en andere gebruikers in de toekomst toestemming geven om hun eigen query uit te voeren, zodat de uitbreidbaarheid er is en u het niet allemaal zelf hoeft te doen.

Or ...

De andere optie, die waarschijnlijk eleganter en foutbestendig is (nou ja ... misschien) is om iemand anders dit voor je te laten doen. Slaapstand is een veelgebruikt hulpprogramma dat de voor u lees-/schrijfdatabase abstract maakt en kan worden geconfigureerd om een verschillende database zoals u dat wilt, alleen heeft het jarenlange ervaring en bugfixes. Het is niet het gemakkelijkste om te leren (voor complexe query's en joins, enz.) Maar voor de basismodellen en toewijzing aan een database, het geeft je alles wat je wilt en meer, inclusief de mogelijkheid om caching heel gemakkelijk in en uit te schakelen en lui het laden van gegevens, zodat u niet duizenden records bij de hand hebt die u niet zult gebruiken. Het zou lang duren om een ​​systeem als dit te maken en te verharden.

1
toegevoegd

Externalizing connection string stelt uw applicatie niet in staat om verschillende databases te verwerken. Maar hier is wat je kunt doen.

Use Datasource instead of connection This offers you the ability to create connection many different ways using JNDI, from Connection Pool, etc.

Meer over Datasource, rechtstreeks uit javax.sql.DataSource javadoc

Dit is een fabriek voor verbindingen met de fysieke gegevensbron   DataSource-object vertegenwoordigt. Een alternatief voor de DriverManager   faciliteit, een DataSource-object is het voorkeursmiddel om een   verbinding.

Define DAO interface for accessing data. Make your application code depend on Interface. You can provide database specific implementation for the DAO interface. When the database changes, create new implementation for the database. Let DAO factory pick and choose the appropriate instance of DAO depending on database.

Bibliotheken zoals Mybatis, Slaapstand die het ORM -paradigma ondersteunen automatiseren deze stappen voor u.

1
toegevoegd