Spring dao

1,052 views

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,052
On SlideShare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
20
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Spring dao

  1. 1. Spring framework Motto: Musíte rozbít vejce když chcete udělat omeletu Spring framework training materials by Roman Pichlík is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.Sunday 13 May 2012
  2. 2. Přístup k datům Jak efektivně používat Spring framework pro přístup k datůmSunday 13 May 2012
  3. 3. Práce s daty • Různé oblasti • Definice datového zdroje • Údržba zdrojů • Ošetření výjimek • Řízení transakcíSunday 13 May 2012- bez ohledu na použiti konkretního frameworku
  4. 4. Definice datového zdrojeSunday 13 May 2012
  5. 5. • Datasource je beana • java.sql.Datasource • Lokální/Poskytovaný • JNDI aplikačního serveruSunday 13 May 2012- datasource participuje v dependency injection jako jákákoliv jiná beana
  6. 6. Lokální datasource <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="org.hsqldb.jdbcDriver"/> <property name="url" value="jdbc:hsqldb:mem:test"/> <property name="username" value="sa"/> <property name="password" value=""/> </bean> • Connection pool s využitím • Apache DBCP http://commons.apache.org/dbcp/ • Pozor na DBCP v produkci • http://blog.novoj.net/2010/02/07/commons-dbcp-industrialni- standard-s-chybami/Sunday 13 May 2012- zduraznit, ze nezalezi na tom odkud pochazi trida, ktera reprezentuje datasource- DBCP alternativy C3PO, pool aplikacniho serveru (pokud to neni Tomcat)
  7. 7. Lokální ds. pro embedded DB • Spring 3.x namespace embedded DB • HSQL, H2, Derby • Inicializace skripty <jdbc:embedded-database id="dataSource"> <jdbc:script location="classpath:schema.sql"/> <jdbc:script location="classpath:test-data.sql"/> </jdbc:embedded-database> EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder(); EmbeddedDatabase db = builder.setType(H2).addScript("schema.sql").addScript("test-data.sql").build(); // do stuff against the db (EmbeddedDatabase extends javax.sql.DataSource) db.shutdown()Sunday 13 May 2012- rozsiritelne, muznost konfigurovat jinou embedded DB- programový i deklarativní způsob
  8. 8. Data Access Object • Návrhový vzor pro přístup k datům • Pouze DAO implementuje logiku pro práci s DB • Motivace • změna implementace • odpovědnost v jedné vrstvěSunday 13 May 2012
  9. 9. Implementační možnosti • Přímé použití JDBC • ORM či Semi-ORM framework • JPA, Hibernate, iBatis, JDO... • Co budeme řešit • Konfigurace • Resource management • Exception handlingSunday 13 May 2012- Spring všechny tyto věci řeší za nás- poskytuje high level API, které odstiňuje
  10. 10. JDBCSunday 13 May 2012
  11. 11. Co obnáší práce s JDBC • Získání databázového připojení • Vytvoření java.sql.Statement • Nastavení parametru • Vykonání • Procházení výsledků a zpracováníSunday 13 May 2012
  12. 12. Jak vypadá typický kód Connection con = null; PreparedStatement ps = null; • Kde jsou problémy? ResultSet rs = null; try{ con = getConnection(); • NPE ignorujte ps = con.prepareStatement("select * x"); rs = ps.executeQuery(); while(rs.next()){ //zpracuj hodnoty } } catch(SQLException e) { throw new RuntimeException(e); } finally { try { rs.close(); ps.close(); con.close(); } catch(SQLException e) {} } Sunday 13 May 2012
  13. 13. Jak vypadá typický kód Connection con = null; PreparedStatement ps = null; • Kde jsou problémy? ResultSet rs = null; try{ con = getConnection(); • Často se opakující kód ps = con.prepareStatement("select * x"); rs = ps.executeQuery(); while(rs.next()){ //zpracuj hodnoty • Návrhový vzor } } catch(SQLException e) { Copy&Paste throw new RuntimeException(e); } finally { try { • Uvolnění zdrojů rs.close(); ps.close(); con.close(); • Míchání odpovědností } catch(SQLException e) {} } • Vykonání/Zpracování výsledkuSunday 13 May 2012
  14. 14. Jak vypadá typický kód Connection con = null; r u o PreparedStatement ps = null; • Kde jsou problémy? ResultSet rs = null; try{ v z m con = getConnection(); • Často se opakující kód é • Návrhový vzor ps = con.prepareStatement("select * x"); rs = ps.executeQuery(); v o h od h t Copy&Paste while(rs.next()){ r e //zpracuj hodnoty } } catch(SQLException e) { v á m } finally { n e • Uvolnění zdrojů throw new RuntimeException(e); v at je pl try { í m rs.close(); n e ps.close(); e T con.close(); • Míchání odpovědností } e š } catch(SQLException e) {} Ř • Vykonání/Zpracování výsledkuSunday 13 May 2012
  15. 15. Template method • Společný kód v předkovi • Potomek přepisuje jenom to je pro něj specifické • zpracování výsledkůSunday 13 May 2012
  16. 16. JDBC se SpringemSunday 13 May 2012
  17. 17. Klíčové abstrakce org.springframework.jdbc.core.JdbcTemplate org.springframework.jdbc.core.support.JdbcDaoSupportSunday 13 May 2012- resource management- exception handling
  18. 18. JdbcTemplate • Centrální třídá pro práci s JDBC • Thread safe • Překlad výjimek • Resource management • Alternativy • org.springframework.jdbc.core.simple.SimpleJdbcTe mplate • org.springframework.jdbc.core.namedparam.NamedPar ameterJdbcTemplateSunday 13 May 2012
  19. 19. UkázkySunday 13 May 2012
  20. 20. SQL int rowCount = jdbcTemplate.queryForInt("select count(0) from t_accrual"); int countOfActorsNamedJoe = jdbcTemplate.queryForInt( "select count(0) from t_actors where first_name = ?", new Object[]{"Joe"} ); Actor actor = (Actor) jdbcTemplate.queryForObject( "select first_name, surname from t_actor where id = ?", new Object[]{new Long(1212)}, new RowMapper() { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { Actor actor = new Actor(); actor.setFirstName(rs.getString("first_name")); actor.setSurname(rs.getString("surname")); return actor; } });Sunday 13 May 2012
  21. 21. DML a DDL jdbcTemplate.update( "insert into t_actor (first_name, surname) values (?, ?)", new Object[] {"Leonor", "Watling"}); jdbcTemplate.execute( "create table mytable (id integer, name varchar(100))");Sunday 13 May 2012
  22. 22. Pojmenované parametry NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource); String sql = "select count(0) from T_ACTOR where first_name = :first_name"; Map namedParameters = new HashMap(); namedParameters.put("first_name", firstName); int count = namedParameterJdbcTemplate.queryForInt(sql, namedParameters);Sunday 13 May 2012
  23. 23. Podpora generik simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource); String sql = "select id, first_name, last_name from T_ACTOR where id = ?"; ParameterizedRowMapper<Actor> mapper = new ParameterizedRowMapper<Actor>() { public Actor mapRow(ResultSet rs, int rowNum) throws SQLException { Actor actor = new Actor(); actor.setId(rs.getLong("id")); actor.setFirstName(rs.getString("first_name")); actor.setLastName(rs.getString("last_name")); return actor; } }; Actor actor = simpleJdbcTemplate.queryForObject(sql, mapper, id);Sunday 13 May 2012
  24. 24. Překlad výjimek • Spring překládá checked výjimky DAO tříd na vlastní rodinu runtime výjimekSunday 13 May 2012- překlad podle vendor codes
  25. 25. Překlad SQLException • SQLException • Spring zpracuje error code • Namapování na konkrétní DataAccessException • Rozšiřitelné • custom kódy z triggeruSunday 13 May 2012
  26. 26. Přidání custom error kódu • classpath kontext v rootu sql-error- codes.xmlSunday 13 May 2012default org/springframework/jdbc/support/sql-error-codes.xmlsql-error-codes.xml do rootu classpathzkopirovat z originalu beanu/DB kterou chceme zmenit
  27. 27. Autom. překlad @Repository • Post-processor zajišťující @Repository public class ProductDaoImpl implements automatický překlad ProductDao { vyjímek na @Repository // class body here... třídách } • PersistenceExceptionTra nslationPostProcessor <beans> <!-- Exception translation bean post processor • vytváří proxy --> <bean class="org.springframework.dao.annotation.Pe rsistenceExceptionTranslationPostProcessor"/ > <bean class="product.ProductDaoImpl"/> </beans>Sunday 13 May 2012využití v případě, že pracujeme přímo s JDBC, Hibernatem, JPA případně dalšímitechnologiemi podporovanými Spring frameworkem
  28. 28. SimpleJdbcInsert insertActor = new SimpleJdbcInsert(dataSource).withTableName("t_actor"); Map<String, Object> parameters = new HashMap<String, Object>(3); parameters.put("id", actor.getId()); parameters.put("first_name", actor.getFirstName()); parameters.put("last_name", actor.getLastName()); insertActor.execute(parameters);Sunday 13 May 2012
  29. 29. Co dál • BLOB/CLOB handling • Connection extractor • Podpora volání stored procedures • ...Sunday 13 May 2012
  30. 30. Batch updates • Více update/insert příkazů • menší počet round-trips do DB • DB může lépe optimalizovat • Použití pokud pracujeme s jednou tabulkouSunday 13 May 2012
  31. 31. Batch updates batch size=25Sunday 13 May 2012
  32. 32. Batch updates - JdbcTemplateSunday 13 May 2012
  33. 33. BatchSqlUpdateSunday 13 May 2012
  34. 34. DAO Support • JdbcDaoSupport, • HibernateDaoSupport • JpaDaoSupport... • Každý z těchto objektů obsahuje třídu založenou na vzoru TemplateMethod • JdbcTemplate, HibernateTemplateSunday 13 May 2012- automaticky preklad vyjimek
  35. 35. JPASunday 13 May 2012
  36. 36. JPA == ORM • ORM • Object To Relational Mapping • Snaží se řešit střet dvou světů • Objektového a Relačního • Není specifické pro Javu • každý jazyk/platforma má svůj ORM frameworkSunday 13 May 2012- snaží se pomáhat při prekonávání rozdílů mezi Objektovým a Relačním světem- odstínění od konkrétní databázove technologie
  37. 37. ORM přibližuje oba světy Svět objektů Svět relací a tabulek public class User { private List<Order> orders; private String email; private String name; User private Address address; 1 * private class Address { private String street; Order private String zipCode; 1 } * } Item public class Order { private List<Item> orderItems; private long number; } public class Item { private long id; private String name; }Sunday 13 May 2012
  38. 38. ORM přibližuje oba světy Svět objektů ORM Svět relací a tabulek public class User { private List<Order> orders; private String email; private String name; User private Address address; 1 * Order private class Address { private String street; private String zipCode; 1 } * } Item public class Order { private List<Item> orderItems; private long number; } public class Item { private long id; private String name; }Sunday 13 May 2012
  39. 39. Agenda • Představení JPA • koncepce • mapování • dotazy • Konfigurace EntityManageru • Implementace JPA DAOSunday 13 May 2012
  40. 40. Koncept • EntityManager • Reprezentuje jednotku práce • Umožňuje řídit lifeczcle persistentních objektů • vznik, aktualizaci, smazáníSunday 13 May 2012
  41. 41. Koncept • EntityManagerFactory • thread-safe objekt • reprezentuje jeden datový zdroj (DB) • faktory pro EntityManager • PersistenceUnit (persistence.xml) • združuje skupinu persistentních tříd • umožňue napojení na transakční infrastrukturu • konfiguruje JPA poskytovateleSunday 13 May 2012persistence.xml musi lezet v rootu classpath
  42. 42. PersistentContext a EntityManagerSunday 13 May 2012- entity manager umoznuje pristup k persistentnimu contextu- persistentni context predstavuje in-memory stav pers. entit a stara se o jeho synchronizacis databází
  43. 43. EntityManager API Metoda v EntityManager API Popis SQL příkaz Přidání instance entity do persist(Entity instance) insert into table PersistenContext Odstranění entity z remove(Entity instance) delete from table where id=? PersistentContext Nahrání podle primárního find(Entity class, Primary key) select * from table where id=? klíče Aktualizace stavu entity v merge(Entity instance) update table set ... where id=? PersistentContext Vytvoří objekt reprezentující createQuery(String jpql) dotaz Vynutí synchronizaci flush() PersistenContext s databází Transakce, zjištování existence další metody entity atd.Sunday 13 May 2012
  44. 44. JPA Providers • Implementace JPA specifikace • EclipseLink/Toplink • referenční implementace • Apache OpenJPA • Hibernate EntityManagerSunday 13 May 2012
  45. 45. Hibernate JPA • Hibernate EntityManager • bridge pro JPA rozhrani • Starý dobrý Hibernate pod kapotou • Lze používat Hibernate anotace nad rámec JPA specifikaceSunday 13 May 2012
  46. 46. JPA mapování • Metadata pro popis vztahu • Entita/Tabulka • Field/Sloupec • Vazby (one2one, one2many) • Využití smart defaults • pokud DB schéma koresponduje s obj. modelemSunday 13 May 2012
  47. 47. Co můžeme anotovat • Třídy • propojení na tabulku • aplikuje se na celou třídu pokud na fieldech neřekneme jinak • Fieldy • propojení na sloupečky • všechny fieldy jsou persitentí • @Transient - excludeSunday 13 May 2012
  48. 48. Jednoduché mapováníSunday 13 May 2012
  49. 49. Relační mapováníSunday 13 May 2012- podporovany vsechny mozne i nemozne způsoby mapování
  50. 50. JPA a dotazy • Získání entity podle primárního klíče • Použití JPQL • Použití SQLSunday 13 May 2012- při použití SQL padá výhoda odstínění od konkrétní databáze, přesto je to někdy nutné- pokud už musíte držte SQL kód na jednom místě
  51. 51. Získání entity primarním klíčemSunday 13 May 2012
  52. 52. Získání dotazemSunday 13 May 2012
  53. 53. Konfigurace EntityManagerFactory ve Springu • LocalEntityManagerFactoryBean • LocalContainerEntityManagerFact oryBean • JNDI lookup • Všechny vyžadují persisten.xml pro konfiguraciSunday 13 May 2012
  54. 54. persistence.xml • Vždy na classpath v META-INF • Specifikuje persistence unit a vendor konfiguraciSunday 13 May 2012
  55. 55. LocalEntityManagerFactoryBean • Standalone aplikace, testy • Nelze specifikovat datasource • JPA provider určen z • META-INF/services/javax.persistence.spi.PersistenceProviderSunday 13 May 2012
  56. 56. LocalContainerEntityManagerFactoryBean • Plně konfigurovatelné do nejmenších detailů • Datasource a Vendor specific konfiguraceSunday 13 May 2012
  57. 57. Jak funguje factory beanaSunday 13 May 2012
  58. 58. JNDI lookup • EntityManagerFactory se získá z JNDI • Použití v případe deploymentu do ASSunday 13 May 2012
  59. 59. Implementace DAO • Žadná závislost na Spring třídách • nemusíme dědit • inject @PersistentContext • překlad vyjímek přes • PersistentExceptionTranslationPostProces sorSunday 13 May 2012
  60. 60. Ukázka DAO s překladem výjimek @Repository public class UserJPADao implements UserDao{ @PersitenceContext private EntityManager entityManager; public void saveUser(User user) { entityManager.persiste(user); } }Sunday 13 May 2012
  61. 61. • springdao projekt • dodejte chybějící implementaci do • cz.sweb.pichlik.springdao.hibernate.UserStorageDaoHibernate • cz.sweb.pichlik.springdao.jdbc.UserStorageDaoJdbc • samozřejmostí je zelený test • cz.sweb.pichlik.springdao.UserStorageDaoTest • cz.sweb.pichlik.springdao.hibernate.UserStorageDaoHibernateTestSunday 13 May 2012ukazata konfiguraci Springu

×