Proljetni JDBC
1. Pregled
U ovom ćemo članku proći kroz slučajeve praktične upotrebe modula Spring JDBC.
Svi razredi u proljetnom JDBC podijeljeni su u četiri zasebna paketa:
- jezgra - osnovna funkcionalnost JDBC-a. Neke od važnih klasa u ovom paketu uključuju JdbcTemplate, SimpleJdbcInsert,SimpleJdbcCall i NamedParameterJdbcTemplate.
- izvor podataka - klase korisnih programa za pristup izvoru podataka. Također ima različite implementacije izvora podataka za testiranje JDBC koda izvan spremnika EE Jakarte.
- objekt - DB pristup objektno orijentiranom načinu. Omogućuje izvršavanje upita i vraćanje rezultata kao poslovni objekt. Također mapira rezultate upita između stupaca i svojstava poslovnih objekata.
- podrška - časovi podrške za nastavu pod jezgra i objekt paketi. Npr. pruža SQLException prevoditeljska funkcionalnost.
2. Konfiguracija
Za početak, krenimo s nekom jednostavnom konfiguracijom izvora podataka (za ovaj ćemo primjer koristiti MySQL bazu podataka):
@Configuration @ComponentScan ("com.baeldung.jdbc") javna klasa SpringJdbcConfig {@Bean public DataSource mysqlDataSource () {DriverManagerDataSource dataSource = novi DriverManagerDataSource (); dataSource.setDriverClassName ("com.mysql.jdbc.Driver"); dataSource.setUrl ("jdbc: mysql: // localhost: 3306 / springjdbc"); dataSource.setUsername ("gost_korisnik"); dataSource.setPassword ("lozinka_gosta"); vratiti dataSource; }}
Alternativno, možemo dobro iskoristiti ugrađenu bazu podataka za razvoj ili testiranje - ovdje je brza konfiguracija koja stvara instancu ugrađene baze podataka H2 i prethodno je popunjava jednostavnim SQL skriptama:
@Bean public DataSource dataSource () {return new EmbeddedDatabaseBuilder () .setType (EmbeddedDatabaseType.H2) .addScript ("classpath: jdbc / schema.sql") .addScript ("classpath: jdbc / test-build.sql"). (); }
Napokon - isto se, naravno, može učiniti pomoću XML konfiguriranja za izvor podataka:
3. The JdbcTemplate i pokretanje upita
3.1. Osnovni upiti
JDBC predložak glavni je API putem kojeg ćemo pristupiti većini funkcionalnosti koja nas zanima:
- stvaranje i zatvaranje veza
- izvršavanje izjava i pohranjenih poziva procedura
- ponavljanje preko Postavi rezultat i vraćanje rezultata
Prvo, krenimo s jednostavnim primjerom da vidimo što je JdbcTemplate mogu:
int result = jdbcTemplate.queryForObject ("SELECT COUNT (*) FROM EMPLOYEE", Integer.class);
a ovdje je i jednostavan INSERT:
javni int addEmplyee (int id) {return jdbcTemplate.update ("UMESTI U VRIJEDNOSTI ZAPOSLENIH (?,?,?,?)", id, "Bill", "Gates", "USA"); }
Primijetite standardnu sintaksu pružanja parametara - pomoću znaka `?`. Dalje - pogledajmo alternativu ovoj sintaksi.
3.2. Upiti s imenovanim parametrima
Dobiti podrška za imenovane parametre, koristit ćemo drugi JDBC predložak koji pruža okvir - NamedParameterJdbcTemplate.
Uz to, ovo obavija JbdcTemplate i pruža alternativu tradicionalnoj sintaksi koristeći "?”Za specificiranje parametara. Ispod haube zamjenjuje imenovane parametre u JDBC "?" rezervirano mjesto i delegati u zamotane JDCTemplate za izvršavanje upita:
SqlParameterSource namedParameters = new MapSqlParameterSource (). AddValue ("id", 1); povratak namedParameterJdbcTemplate.queryForObject ("ODABERI FIRST_NAME IZ ZAPOSLENOG GDJE ID =: id", namedParameters, String.class);
Primijetite kako koristimo MapSqlParameterSource kako bi se osigurale vrijednosti za imenovane parametre.
Na primjer, pogledajmo donji primjer koji koristi svojstva graha za određivanje imenovanih parametara:
Zaposlenik zaposlenik = novi zaposlenik (); worker.setFirstName ("James"); Niz SELECT_BY_ID = "ODABERI BROJ (*) OD ZAPOSLENIKA GDJE FIRST_NAME =: firstName"; SqlParameterSource namedParameters = new BeanPropertySqlParameterSource (zaposlenik); vrati namedParameterJdbcTemplate.queryForObject (SELECT_BY_ID, namedParameters, Integer.class);
Primijetite kako sada koristimo BeanPropertySqlParameterSource implementacije umjesto ručnog specificiranja imenovanih parametara kao prije.
3.3. Mapiranje rezultata upita u Java objekt
Još jedna vrlo korisna značajka je sposobnost mapiranja rezultata upita u Java objekte - implementacijom Mapa za redove sučelje.
Na primjer - za svaki redak vraćen upitom Spring koristi mapper reda za popunjavanje java graha:
javna klasa EmployeeRowMapper implementira RowMapper {@Override public Employee mapRow (ResultSet rs, int rowNum) baca SQLException {zaposlenik zaposlenik = novi zaposlenik (); zaposlenik.setId (rs.getInt ("ID")); worker.setFirstName (rs.getString ("FIRST_NAME")); worker.setLastName (rs.getString ("LAST_NAME")); worker.setAddress (rs.getString ("ADDRESS")); povratak zaposlenika; }}
Nakon toga sada možemo proslijediti mapiranje redaka API-ju upita i dobiti potpuno naseljene Java objekte:
String query = "SELECT * FROM EMPLYYE WHERE ID =?"; Zaposlenik zaposlenik = jdbcTemplate.queryForObject (upit, novi Object [] {id}, novi EmployeeRowMapper ());
4. Prijevod iznimke
Proljeće dolazi s vlastitom hijerarhijom izuzetaka podataka koja se isporučuje s okvirom DataAccessException kao korijenska iznimka - i u nju prevodi sve temeljne sirove iznimke.
I tako održavamo zdrav razum ne morajući se nositi s iznimkama upornosti na niskoj razini i koristimo činjenicom da Proljeće umotava iznimke na niskoj razini u DataAccessException ili jedna od njegovih podrazreda.
Također, ovo zadržava mehanizam rukovanja iznimkama neovisno o osnovnoj bazi podataka koju koristimo.
Osim toga, zadani SQLErrorCodeSQLExceptionTranslator, također možemo osigurati vlastitu implementaciju SQLExceptionTranslator.
Evo kratkog primjera prilagođene implementacije, prilagođavanja poruke o pogrešci kada postoji duplicirano kršenje ključa, što rezultira kodom pogreške 23505 kada se koristi H2:
javna klasa CustomSQLErrorCodeTranslator proširuje SQLErrorCodeSQLExceptionTranslator {@Override zaštićen DataAccessException customTranslate (zadatak niza, String sql, SQLException sqlException) {if (sqlException.getErrorCode5) Izjeta-pretplataExceptionExceptionTextExceptionDececertExceptionTextExceptionTextExceptionTextExt ); } return null; }}
Da bismo koristili ovaj prilagođeni prevoditelj iznimki, moramo ga proslijediti na JdbcTemplate pozivanjem setExceptionTranslator () metoda:
CustomSQLErrorCodeTranslator customSQLErrorCodeTranslator = novi CustomSQLErrorCodeTranslator (); jdbcTemplate.setExceptionTranslator (customSQLErrorCodeTranslator);
5. JDBC operacije pomoću klasa SimpleJdbc
SimpleJdbc klase pružaju jednostavan način konfiguriranja i izvršavanja SQL izraza. Te klase koriste metapodatke baze podataka za izgradnju osnovnih upita. SimpleJdbcInsert i SimpleJdbcCall klase pružaju lakši način izvođenja poziva umetnutih i pohranjenih procedura.
5.1. SimpleJdbcInsert
Pogledajmo izvršavanje jednostavnih izjava za umetanje s minimalnom konfiguracijom.
Izjava INSERT generira se na temelju konfiguracije SimpleJdbcInsert i sve što trebamo je navesti naziv tablice, nazive stupaca i vrijednosti.
Prvo, izradimo a SimpleJdbcInsert:
SimpleJdbcInsert simpleJdbcInsert = novo SimpleJdbcInsert (dataSource) .withTableName ("EMPLOYEE");
Dalje, navedimo imena i vrijednosti stupaca i izvršimo operaciju:
public int addEmplyee (Employee emp) {Parametri mape = novi HashMap (); parameters.put ("ID", emp.getId ()); parameters.put ("FIRST_NAME", emp.getFirstName ()); parameters.put ("LAST_NAME", emp.getLastName ()); parameters.put ("ADDRESS", emp.getAddress ()); vrati simpleJdbcInsert.execute (parametri); }
Nadalje, dopustiti baza podataka za generiranje primarnog ključa, možemo iskoristiti executeAndReturnKey () API; trebat ćemo konfigurirati i stvarni stupac koji se automatski generira:
SimpleJdbcInsert simpleJdbcInsert = novo SimpleJdbcInsert (dataSource) .withTableName ("EMPLOYEE") .usingGeneratedKeyColumns ("ID"); Broj id = simpleJdbcInsert.executeAndReturnKey (parametri); System.out.println ("Generirani id -" + id.longValue ());
Konačno - ove podatke možemo proslijediti i pomoću BeanPropertySqlParameterSource i MapSqlParameterSource.
5.2. Pohranjeni postupci s SimpleJdbcCall
Također, pogledajmo izvršavanje pohranjenih procedura - iskoristit ćemo SimpleJdbcCall apstrakcija:
SimpleJdbcCall simpleJdbcCall = novi SimpleJdbcCall (izvor podataka) .withProcedureName ("READ_EMPLOYEE");
javni Employee getEfficieeUsingSimpleJdbcCall (int id) {SqlParameterSource in = new MapSqlParameterSource (). addValue ("in_id", id); Karta van = simpleJdbcCall.execute (in); Zaposlenik emp = novi zaposlenik (); emp.setFirstName ((Niz) out.get ("FIRST_NAME")); emp.setLastName ((String) out.get ("LAST_NAME")); vratiti emp; }
6. Šaržne operacije
Još jedan jednostavan slučaj upotrebe - skupljanje više operacija zajedno.
6.1. Osnovne batch operacije pomoću JdbcTemplate
Koristeći JdbcTemplate, skupne operacije može se izvršiti putem batchUpdate () API.
Ovdje je zanimljiv jezgrovit, ali vrlo koristan BatchPreparedStatementSetter provedba:
public int [] batchUpdateUsingJdbcTemplate (Popis zaposlenika) {return jdbcTemplate.batchUpdate ("INSERT IN TO EMPLOYE VALUES (?,?,?,?)", new BatchPreparedStatementSetter () {@Override public void setValuceQ, Prepared iSepleStalueQ, Prepared inSetVacesQ {ps.setInt (1, zaposlenici.get (i) .getId ()); ps.setString (2, zaposlenici.get (i) .getFirstName ()); ps.setString (3, zaposlenici.get (i). getLastName ()); ps.setString (4, zaposlenici.get (i) .getAddress ();} @Override public int getBatchSize () {return 50;}});}
6.2. Skupne operacije pomoću NamedParameterJdbcTemplate
Također imamo mogućnost doziranja sa NamedParameterJdbcTemplate – batchUpdate () API.
Ovaj je API jednostavniji od prethodnog - nema potrebe za implementacijom dodatnih sučelja za postavljanje parametara, jer ima unutarnji pripremljeni postavljač izraza za postavljanje vrijednosti parametara.
Umjesto toga, vrijednosti parametara mogu se proslijediti u batchUpdate () metoda kao niz od SqlParameterSource.
SqlParameterSource [] batch = SqlParameterSourceUtils.createBatch (zaposlenici.toArray ()); int [] updateCounts = namedParameterJdbcTemplate.batchUpdate ("INSERT IN TO EMPLOYE VALUES (: id,: firstName,: lastName,: address)", batch); vratiti updateCounts;
7. Proljetni JDBC s proljetnim čizmom
Spring Boot nudi starter opruga-čizma-starter-jdbc za upotrebu JDBC-a s relacijskim bazama podataka.
Kao i kod svakog pokretača Spring Boot-a, i ovaj nam pomaže u brzom pokretanju i pokretanju aplikacije.
7.1. Ovisnost Mavena
Trebat će nam opruga-čizma-starter-jdbc ovisnost kao primarnu, kao i ovisnost baze podataka koju ćemo koristiti. U našem slučaju, ovo je MySQL:
org.springframework.boot spring-boot-starter-jdbc mysql mysql-connector-java runtime
7.2. Konfiguracija
Spring Boot automatski konfigurira izvor podataka za nas. Samo trebamo osigurati svojstva u a Svojstva datoteka:
spring.datasource.url = jdbc: mysql: // localhost: 3306 / springjdbc spring.datasource.username = gost_korisnik spring.datasource.password = guest_password
To je to, samo radeći samo ove konfiguracije, naša je aplikacija pokrenuta i možemo je koristiti za druge operacije baze podataka.
Eksplicitna konfiguracija koju smo vidjeli u prethodnom odjeljku za standardnu aplikaciju Spring je sada uključena kao dio automatske konfiguracije Spring Boot.
8. Zaključak
U ovom smo članku pogledali JDBC apstrakciju u Spring Framework-u, pokrivajući različite mogućnosti koje pruža Spring JDBC s praktičnim primjerima.
Također, ispitali smo kako možemo brzo započeti s Spring JDBC-om pomoću Spring Boot JDBC startera.
Izvorni kod za primjere dostupan je na GitHubu.