Tavaszi JDBC

1. Áttekintés

Ebben a cikkben áttekintjük a Spring JDBC modul gyakorlati felhasználási eseteit.

A Spring JDBC összes osztálya négy külön csomagra oszlik:

  • mag - a JDBC alapvető funkciói. A csomag alatt található néhány fontos osztály a következőket tartalmazza: JdbcTemplate, SimpleJdbcInsert,SimpleJdbcCall és NamedParameterJdbcTemplate.
  • adatforrás - segédosztályok az adatforrás eléréséhez. Különböző adatforrás-implementációkkal is rendelkezik a JDBC kód tesztelésére a Jakarta EE tárolón kívül.
  • tárgy - DB-hozzáférés objektum-orientált módon. Lehetővé teszi lekérdezések végrehajtását és az eredmények üzleti objektumként történő visszaadását. Ezenkívül feltérképezi a lekérdezés eredményeit az üzleti objektumok oszlopai és tulajdonságai között.
  • támogatás - támogató osztályok a mag és tárgy csomagok. Például. biztosítja a SQLEkivétel fordítási funkcionalitás.

2. Konfiguráció

Először is kezdjük az adatforrás néhány egyszerű konfigurálásával (ehhez a példához egy MySQL adatbázist fogunk használni):

@Configuration @ComponentScan ("com.baeldung.jdbc") public class SpringJdbcConfig {@Bean public DataSource mysqlDataSource () {DriverManagerDataSource dataSource = new DriverManagerDataSource (); dataSource.setDriverClassName ("com.mysql.jdbc.Driver"); dataSource.setUrl ("jdbc: mysql: // localhost: 3306 / springjdbc"); dataSource.setUsername ("vendég_felhasználó"); dataSource.setPassword ("vendég_jelszó"); return dataSource; }}

Alternatív megoldásként a beágyazott adatbázist is jól felhasználhatjuk fejlesztéshez vagy teszteléshez - íme egy gyors konfiguráció, amely létrehozza a H2 beágyazott adatbázis egy példányát, és egyszerű SQL szkriptekkel előre feltölti:

@Bean public DataSource dataSource () {return new EmbeddedDatabaseBuilder () .setType (EmbeddedDatabaseType.H2) .addScript ("classpath: jdbc / schema.sql") .addScript ("classpath: jdbc / test-data.sql"). (); } 

Végül - ugyanez természetesen megtehető az XML konfigurálásával is adatforrás:

3. Az JdbcTemplate és Futó lekérdezések

3.1. Alapvető lekérdezések

A JDBC sablon a fő API, amelyen keresztül hozzáférhetünk a legtöbb érdekelt funkcióhoz:

  • kapcsolatok létrehozása és lezárása
  • utasítások és tárolt eljáráshívások végrehajtása
  • iterálás a ResultSet és visszatérő eredmények

Először is kezdjünk egy egyszerű példával, hogy lássuk, mi a JdbcTemplate meg tud tenni:

int eredmény = jdbcTemplate.queryForObject ("SELECT COUNT (*) FROM EMPLOYEE", Integer.class); 

és itt van egy egyszerű INSERT:

public int addEmplyee (int id) {return jdbcTemplate.update ("INSERT INTO EMPLOYEE VALUES (?,?,?,?)", id, "Bill", "Gates", "USA"); }

Figyelje meg a paraméterek megadásának szokásos szintaxisát - a "?" Karakter használatával. Következő - nézzük meg ennek a szintaxisnak az alternatíváját.

3.2. Megnevezett paraméterekkel rendelkező lekérdezések

Hogy megszerezzem megnevezett paraméterek támogatása, a keretrendszer által biztosított másik JDBC sablont - a NamedParameterJdbcTemplate.

Ezenkívül ez becsomagolja a JbdcTemplate és alternatívát nyújt a hagyományos szintaxishoz a?”Paraméterek megadásához. A motorháztető alatt a megnevezett paramétereket JDBC „?” -Re cseréli helyőr és delegáltak a burkoltba JDCTemplate a lekérdezések végrehajtásához:

SqlParameterSource namedParameters = new MapSqlParameterSource (). AddValue ("id", 1); return namedParameterJdbcTemplate.queryForObject ("FIRST_NAME KIVÁLASZTÁSA A MUNKAVÁLLALÓBÓL WHERE ID =: id", namedParameters, String.class);

Figyelje meg, hogyan használjuk a MapSqlParameterSource a megnevezett paraméterek értékeinek megadásához.

Nézzük meg például az alábbi példát, amely egy bab tulajdonságait használja a megnevezett paraméterek meghatározásához:

Alkalmazott alkalmazott = új alkalmazott (); alkalmazott.setFirstName ("James"); Karakterlánc SELECT_BY_ID = "COUNT (*) KIVÁLASZTÁSA A MUNKAVÁLLALÓTÓL WHERE FIRST_NAME =: keresztnév"; SqlParameterSource namedParameters = new BeanPropertySqlParameterSource (alkalmazott); return namedParameterJdbcTemplate.queryForObject (SELECT_BY_ID, namedParameters, Integer.class);

Vegye figyelembe, hogyan használjuk most a BeanPropertySqlParameterSource megvalósítások helyett a korábban megnevezett paraméterek manuális megadása helyett.

3.3. A lekérdezési eredmények leképezése Java objektumra

Egy másik nagyon hasznos funkció a lekérdezés eredményeinek Java objektumokhoz való leképezése - megvalósítással a RowMapper felület.

Például - a lekérdezés által visszaadott minden egyes sorhoz Spring a sorleképezővel tölti fel a java babot:

public class EmployeeRowMapper megvalósítja a RowMapper {@Orride public Employee mapRow (ResultSet rs, int rowNum) dobja az SQLException {Employee worker = new Employee (); worker.setId (rs.getInt ("ID")); worker.setFirstName (rs.getString ("FIRST_NAME")); worker.setLastName (rs.getString ("LAST_NAME")); worker.setAddress (rs.getString ("CÍM")); visszatérő alkalmazott; }}

Ezt követően átadhatjuk a sor leképezőjét a lekérdezés API-nak, és teljesen kitöltött Java objektumokat kaphatunk:

Karakterlánc lekérdezés = "SELECT * FROM EMPLOYEE WHERE ID =?"; Alkalmazott alkalmazott = jdbcTemplate.queryForObject (lekérdezés, új objektum [] {id}, új EmployeeRowMapper ());

4. Kivétel fordítás

A tavasz a dobozon kívül megkapja a saját adatkivételi hierarchiáját - a DataAccessException gyökér kivételként - és lefordítja az összes mögöttes nyers kivételt.

Tehát megőrizzük józan eszünket azzal, hogy nem kell kezelnünk az alacsony szintű kitartás alóli kivételeket, és profitálnunk kell abból a tényből, hogy tavasz az alacsony szintű DataAccessException vagy annak egyik alosztálya.

Emellett a kivételkezelő mechanizmus független marad az általunk használt mögöttes adatbázistól.

Emellett az alapértelmezett SQLErrorCodeSQLExceptionTranslator, saját megvalósítását is biztosíthatjuk SQLExceptionTranslator.

Íme egy gyors példa az egyéni megvalósításra, a hibaüzenet testreszabására, ha ismétlődik a kulcs megsértése, ami a H2 használata esetén 23505 hibakódot eredményez:

public class CustomSQLErrorCodeTranslator kiterjeszti az SQLErrorCodeSQLExceptionTranslator {@Orride védett DataAccessException customTranslate (karakterlánc-feladat, karakterlánc-sql, SQLException sqlException) {if (sqlException.getErrorCode () == 2350. ); } return null; }}

Ennek az egyedi kivétel-fordítónak a használatához át kell adnunk a JdbcTemplate hívással setExceptionTranslator () módszer:

CustomSQLErrorCodeTranslator customSQLErrorCodeTranslator = új CustomSQLErrorCodeTranslator (); jdbcTemplate.setExceptionTranslator (customSQLErrorCodeTranslator);

5. JDBC műveletek SimpleJdbc osztályok használatával

SimpleJdbc osztályok egyszerű módszert kínálnak az SQL utasítások konfigurálására és végrehajtására. Ezek az osztályok adatbázis-metaadatokat használnak az alapvető lekérdezések összeállításához. SimpleJdbcInsert és SimpleJdbcCall osztályok egyszerűbb módot nyújtanak a beszúrás és a tárolt eljáráshívások végrehajtására.

5.1. SimpleJdbcInsert

Vessünk egy pillantást az egyszerű beszúrási utasítások végrehajtására minimális konfigurációval.

Az INSERT utasítás az. Konfigurációja alapján jön létre SimpleJdbcInsert és csak arra van szükségünk, hogy megadjuk a táblázat nevét, az oszlop nevét és értékét.

Először hozzunk létre egy SimpleJdbcInsert:

SimpleJdbcInsert simpleJdbcInsert = new SimpleJdbcInsert (dataSource) .withTableName ("EMPLOYEE");

Ezután adjuk meg az Oszlopok nevét és értékét, és hajtsuk végre a műveletet:

public int addEmplyee (Employee emp) {Térképparaméterek = új HashMap (); paraméterek.put ("ID", emp.getId ()); paraméterek.put ("FIRST_NAME", emp.getFirstName ()); Paraméterek.put ("LAST_NAME", emp.getLastName ()); Paraméterek.put ("ADDRESS", emp.getAddress ()); return simpleJdbcInsert.execute (paraméterek); }

Továbbá, hogy a adatbázis az elsődleges kulcs előállításához, használhatjuk a executeAndReturnKey () API; konfigurálnunk kell a tényleges automatikusan generált oszlopot is:

SimpleJdbcInsert simpleJdbcInsert = new SimpleJdbcInsert (dataSource) .withTableName ("EMPLOYEE") .usingGeneratedKeyColumns ("ID"); Szám id = simpleJdbcInsert.executeAndReturnKey (paraméterek); System.out.println ("Generált azonosító -" + id.longValue ());

Végül - ezeket az adatokat a BeanPropertySqlParameterSource és MapSqlParameterSource.

5.2. Tárolt eljárások SimpleJdbcCall

Vessünk egy pillantást a tárolt eljárások végrehajtására is - ki fogjuk használni SimpleJdbcCall absztrakció:

SimpleJdbcCall simpleJdbcCall = új SimpleJdbcCall (dataSource) .withProcedureName ("READ_EMPLOYEE"); 
public Employee getEmployeeUsingSimpleJdbcCall (int id) {SqlParameterSource in = new MapSqlParameterSource (). addValue ("in_id", id); Map out = simpleJdbcCall.execute (in); Employee emp = new Employee (); emp.setFirstName ((String) out.get ("FIRST_NAME")); emp.setLastName ((String) out.get ("LAST_NAME")); visszatérő emp; }

6. Kötegelt műveletek

Egy másik egyszerű felhasználási eset - több művelet együttes kötegelése.

6.1. Alapszintű kötegelt műveletek JdbcTemplate

Használata JdbcTemplate, Kötegelt műveletek segítségével lehet végrehajtani batchUpdate () API.

Az érdekes rész itt a tömör, de nagyon hasznos BatchPreparedStatementSetter végrehajtás:

public int [] batchUpdateUsingJdbcTemplate (Alkalmazottak listája) {return jdbcTemplate.batchUpdate ("INSERT INTO EMPLOYEE VALUES (?,?,?,?)", new BatchPreparedStatementSetter () {@Override public void setValues, PreparedStatQ (PreparedStatQ) {ps.setInt (1, alkalmazottai.get (i) .getId ()); ps.setString (2, alkalmazottak.get (i) .getFirstName ()); ps.setString (3, alkalmazottak.get (i). getLastName ()); ps.setString (4, alkalmazottak.get (i) .getAddress ();} @Orride public int getBatchSize () {return 50;}});}

6.2. Kötegelt műveletek használata NamedParameterJdbcTemplate

Lehetőségünk van kötegelt műveletekre is a NamedParameterJdbcTemplatebatchUpdate () API.

Ez az API egyszerűbb, mint az előző - a paraméterek beállításához nincs szükség extra interfészek bevezetésére, mivel a paraméterek beállításához belső előkészítő utasítással rendelkezik.

Ehelyett a paraméterértékeket át lehet adni a batchUpdate () metódus tömbjeként SqlParameterSource.

SqlParameterSource [] batch = SqlParameterSourceUtils.createBatch (alkalmazottak.toArray ()); int [] updateCounts = namedParameterJdbcTemplate.batchUpdate ("INSERT INTO EMPLOYEE VALUES (: id,: firstName,: vezetékNév,: address)", kötegelt); return updateCounts;

7. Tavaszi JDBC rugós csomagtartóval

A Spring Boot indítót jelent tavasz-boot-starter-jdbc a JDBC relációs adatbázisokkal való használatához.

Mint minden tavaszi indító indító esetében, ez is segít abban, hogy alkalmazásunk gyorsan elinduljon.

7.1. Maven-függőség

Szükségünk lesz a tavasz-boot-starter-jdbc függőség elsődleges, valamint az általunk használni kívánt adatbázis függősége. Esetünkben ez az MySQL:

 org.springframework.boot spring-boot-starter-jdbc mysql mysql-connector-java futásidejű 

7.2. Konfiguráció

A Spring Boot automatikusan konfigurálja számunkra az adatforrást. Csak meg kell adnunk a tulajdonságokat a tulajdonságait fájl:

spring.datasource.url = jdbc: mysql: // localhost: 3306 / springjdbc spring.datasource.username = guest_user spring.datasource.password = guest_password

Ez az, csak ezeknek a konfigurációknak az elvégzésével az alkalmazásunk működik és működik, és más adatbázis-műveletekhez is felhasználhatjuk.

Az előző szakaszban látott explicit konfiguráció a standard Spring alkalmazáshoz mostantól a Spring Boot automatikus konfigurálás részeként szerepel.

8. Következtetés

Ebben a cikkben megvizsgáltuk a JDBC absztrakcióját a Spring Framework-ben, gyakorlati példákkal lefedve a Spring JDBC által biztosított különféle lehetőségeket.

Megvizsgáltuk azt is, hogy miként kezdhetjük el gyorsan a Spring JDBC-t a Spring Boot JDBC starter használatával.

A példák forráskódja elérhető a GitHub oldalon.