56
J1Brasil Alexandre Porcelli Persistência de Dados além do JPA, ou Como usar noSQL em Java [email protected] segunda-feira, 13 de dezembro de 2010

J1Brasil: Persistência de Dados além do JPA, ou Como usar noSQL em Java

Embed Size (px)

DESCRIPTION

 

Citation preview

  • 1. J1Brasil Persistncia de Dados alm do JPA, ou Como usar noSQL em Java Alexandre Porcelli [email protected], 13 de dezembro de 2010
  • 2. Java One Brasil 2010 Alexandre Porcelli Founder Alexandre Porcelli Writer Alexandre Porcelli Organizer Alexandre Porcelli Commiter / Parser Developer Alexandre Porcelli Creator & Project Leadsegunda-feira, 13 de dezembro de 2010
  • 3. JDBCsegunda-feira, 13 de dezembro de 2010
  • 4. !public class Pessoa { ComboPooledDataSource ds = new ComboPooledDataSource(); private int id; try { private String nome; ds.setDriverClass("com.mysql.jdbc.Driver"); O private String email; ds.setJdbcUrl("jdbc:mysql://localhost:3306/j1br"); private String telefone; ... ... } catch (PropertyVetoException e) { G} throw new RuntimeException(e); } I String nome = "Alexandre Porcelli"; String email = "[email protected]"; D String telefone = "+55 11 1234-5678"; Connection conn = null; try { conn = ds.getConnection(); PreparedStatement st = conn.prepareStatement( C "INSERT INTO PESSOA (nome, email, telefone) VALUES (?, ?, ?)", Statement.RETURN_GENERATED_KEYS); st.setString(1, nome); st.setString(2, email); O st.setString(3, telefone); st.executeUpdate(); conn.commit(); T st.getGeneratedKeys().next(); I Pessoa novaPessoa = new Pessoa(st.getGeneratedKeys().getInt(1), nome, email, telefone); } catch (Exception e) { U throw new RuntimeException("Pessoa insert failed.", e); } finally { try { if (conn != null) { M conn.close(); } } catch (SQLException e) { throw new RuntimeException("Cant close connection", e); } }segunda-feira, 13 de dezembro de 2010
  • 5. JPAsegunda-feira, 13 de dezembro de 2010
  • 6. @RunWith(Arquillian.class) @Entity public class PessoaTestCase { public class Pessoa { @Deployment @Id public static Archive createDeployment() { @GeneratedValue return ShrinkWrap.create(WebArchive.class, "test.war") private int id; .addPackage(Game.class.getPackage()) private String nome; .addManifestResource("test-persistence.xml", "persistence.xml") private String email; .addWebResource(EmptyAsset.INSTANCE, "beans.xml"); private String telefone; } ... } @PersistenceContext EntityManager em; @Inject UserTransaction utx; @Test public void insertSampleRecords() throws Exception { utx.begin(); OK! em.joinTransaction(); Pessoa novaPessoa = new Pessoa(); novaPessoa.setNome("Alexandre Porcelli"); novaPessoa.setTelefone("+55 11 1234-5678"); novaPessoa.setEmail("[email protected]"); em.persist(novaPessoa); System.out.println(novaPessoa); utx.commit(); } }segunda-feira, 13 de dezembro de 2010
  • 7. noSQLsegunda-feira, 13 de dezembro de 2010
  • 8. hypesegunda-feira, 13 de dezembro de 2010
  • 9. segunda-feira, 13 de dezembro de 2010
  • 10. problemas do dia-a-diasegunda-feira, 13 de dezembro de 2010
  • 11. OLTP On-line Transaction Processing is characterized by a large number of short on-line transactions (INSERT, UPDATE, DELETE). The main emphasis for OLTP systems is put on very fast query processing, maintaining data integrity in multi-access environments and an effectiveness measured by number of transactions per second.segunda-feira, 13 de dezembro de 2010
  • 12. segurana autenticaosegunda-feira, 13 de dezembro de 2010
  • 13. JAAS, LDAP, OAUTH...segunda-feira, 13 de dezembro de 2010
  • 14. public boolean isValid(String nomeUsuario, String passw) { PreparedStatement st; Connection conn = null; try { conn = dataSource.getConnection(); st = conn.prepareStatement("SELECT 1 FROM USERS WHERE id = ? and passw = ?"); st.setString(1, nomeUsuario); st.setString(2, passw); ResultSet rs = st.executeQuery(); if (rs.next()) { return true; } return false; } catch (SQLException e) { return false; } finally { try { if (conn != null) { conn.close(); } } catch (SQLException e) { throw new RuntimeException("Cant close connection", e); } } }segunda-feira, 13 de dezembro de 2010
  • 15. Estrura de Dados: Chave-Valor Durabilidade: In-Memory / Serializao Paralela / Rplica Site: http://redis.io/ Escrito em: C + Baixa Latncia + Serializao Paralela Pontos Positivos: + Estruturas de Dados + Cases Pontos Negativos: o/segunda-feira, 13 de dezembro de 2010
  • 16. public class SegurancaRedisCode { public static void main(String[] args) { SegurancaRedisCode seg = new SegurancaRedisCode(); seg.addUserPassw("porcelli", "1234"); Assert.assertTrue(seg.isValid("porcelli", "1234")); Assert.assertFalse(seg.isValid("porcelli", "123")); Assert.assertFalse(seg.isValid("xxx", "1234")); } private final Jedis jedis; public SegurancaRedisCode() { jedis = new Jedis("localhost"); } public boolean isValid(String nomeUsuario, String passwd) { String correctPassw = jedis.get("user:" + nomeUsuario + ":passwd"); if (correctPassw != null && passwd.equals(correctPassw)) { return true; } else { return false; } } public void addUserPassw(String nomeUsuario, String passwd) { jedis.set("user:" + nomeUsuario + ":passwd", passwd); jedis.save(); } }segunda-feira, 13 de dezembro de 2010
  • 17. rvoresegunda-feira, 13 de dezembro de 2010
  • 18. segunda-feira, 13 de dezembro de 2010
  • 19. @Entity @Table(name = "categorias") public class Categoria { @Id @GeneratedValue private Integer id; private String nome; @OneToMany @OrderColumn @JoinColumn(name = "parent_id") private List filhos = new LinkedList(); @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "parent_id", insertable = false, updatable = false) private Categoria parent; .... }segunda-feira, 13 de dezembro de 2010
  • 20. Estrura de Dados: Grafo Durabilidade: Single Node Site: http://neo4j.org Escrito em: Java + ACID + Maturidade Pontos Positivos: + Velocidade no Traverse + Suporte RDF & SPARQL Pontos Negativos: - Falta de Shardingsegunda-feira, 13 de dezembro de 2010
  • 21. private static enum TipoRelacionamento implements RelationshipType { PAI } private final GraphDatabaseService graph; private static final String NEO4J_PATH = "sample/tree"; public Neo4jSampleCode() { graph = new EmbeddedGraphDatabase(NEO4J_PATH); } public Node novaCategoria(String nome, Node pai) { Transaction tx = graph.beginTx(); try { Node newCat = graph.createNode(); newCat.setProperty("nome", nome); if (pai != null) { pai.createRelationshipTo(newCat, TipoRelacionamento.PAI); } tx.success(); return newCat; } finally { tx.finish(); } }segunda-feira, 13 de dezembro de 2010
  • 22. public Node getPai(Node node) { Transaction tx = graph.beginTx(); Node result; try { Iterable relationships = node.getRelationships( TipoRelacionamento.PAI, Direction.INCOMING); if (relationships.iterator().hasNext()) { result = relationships.iterator().next().getStartNode(); } else { result = null; } tx.success(); return result; } finally { tx.finish(); } }segunda-feira, 13 de dezembro de 2010
  • 23. public List getFilhos(Node pai) { Transaction tx = graph.beginTx(); List result = new LinkedList(); try { Iterable relationships = pai.getRelationships( TipoRelacionamento.PAI, Direction.OUTGOING); for (Relationship relationship : relationships) { result.add(relationship.getEndNode()); } tx.success(); return result; } finally { tx.finish(); } }segunda-feira, 13 de dezembro de 2010
  • 24. public List getArvoreCompleta(Node pai) { Transaction tx = graph.beginTx(); List result = new LinkedList(); try { Traverser traverser = pai.traverse(Order.BREADTH_FIRST, StopEvaluator.END_OF_GRAPH, ReturnableEvaluator.ALL_BUT_START_NODE, TipoRelacionamento.PAI, Direction.OUTGOING); for (Node node : traverser) { result.add(node); } tx.success(); return result; } finally { tx.finish(); } }segunda-feira, 13 de dezembro de 2010
  • 25. public static void main(String[] args) { Neo4jSampleCode sample = new Neo4jSampleCode(); Node roupasCat = sample.novaCategoria("Vesturio", null); Node camisaCat = sample.novaCategoria("Camisas", roupasCat); Node calcasCat = sample.novaCategoria("Calas", roupasCat); Node eletronicosCat = sample.novaCategoria("Estronicos", null); Assert.assertNull(sample.getPai(eletronicosCat)); Assert.assertNotNull(sample.getPai(calcasCat)); Assert.assertEquals(sample.getPai(calcasCat), roupasCat); Assert.assertNotNull(sample.getPai(camisaCat)); Assert.assertEquals(sample.getPai(camisaCat), roupasCat); Assert.assertEquals(0, sample.getFilhos(camisaCat).size()); Assert.assertEquals(2, sample.getFilhos(roupasCat).size()); for (Node childCat : sample.getFilhos(roupasCat)) { if (!childCat.equals(camisaCat) && !childCat.equals(calcasCat)) { Assert.fail(); } } Node camisaMangaCurtaCat = sample.novaCategoria("Manga Curta", camisaCat); Node camisaMangaLongCat = sample.novaCategoria("Manga Longa", camisaCat); Assert.assertEquals(4, sample.getArvoreCompleta(roupasCat).size()); for (Node childCat : sample.getFilhos(roupasCat)) { if (!childCat.equals(camisaCat) && !childCat.equals(calcasCat) && !childCat.equals(camisaMangaLongCat) && !childCat.equals(camisaMangaCurtaCat)) { Assert.fail(); } } }segunda-feira, 13 de dezembro de 2010
  • 26. produtos diversidade & irregularidadesegunda-feira, 13 de dezembro de 2010
  • 27. nome effective java tv led 32 mesa de madeira mod valor R$ 80 R$ 1234 R$ 503 um dos melhores livros descr. tv de led 32 muito boa! mesa de canto legal sobre java! qtd. pginas 300 X X tcnico/tecnologia/ categoria X X programao/java cons. energia X A X cor X X marrom claro dimenso X X 20x40x90segunda-feira, 13 de dezembro de 2010
  • 28. segunda-feira, 13 de dezembro de 2010
  • 29. ? oo ||relacional ?segunda-feira, 13 de dezembro de 2010
  • 30. Estrura de Dados: Documento Durabilidade: Rplica Site: http://mongodb.org Escrito em: C++ + Velocidade + Index Pontos Positivos: + Consultas ad-hoc + Auto Sharding - Durabilidade Pontos Negativos: - Update in Place Google: mongodb and fourquaresegunda-feira, 13 de dezembro de 2010
  • 31. private final DB db; public MongoDBSampleCode() throws UnknownHostException, MongoException { Mongo mongo = new Mongo(); db = mongo.getDB("MeuDatabase"); db.getCollection("produtos").drop(); } public void novoEletronico(int id, String nome, int valor, String descricao, String consumoEnergia) { DBCollection coll = db.getCollection("produtos"); DBObject dados = new BasicDBObject(); dados.put("id", id); dados.put("nome", nome); dados.put("valor", valor); dados.put("tipo", "eletronico"); dados.put("desc", descricao); dados.put("cons_energia", consumoEnergia); coll.insert(dados); }segunda-feira, 13 de dezembro de 2010
  • 32. public void getProdutosPorValorMenorQue(int valor) { DBCollection coll = db.getCollection("produtos"); DBObject query = new BasicDBObject(); query.put("valor", new BasicDBObject("$lt", valor)); for (DBObject foundDoc : coll.find(query)) { System.out.println(foundDoc); } }segunda-feira, 13 de dezembro de 2010
  • 33. public static void main(String[] args) throws UnknownHostException, MongoException { MongoDBSampleCode samp = new MongoDBSampleCode(); samp.novoEletronico(1, "tvled32", 1234, "Tv de led 32"", "A"); samp.novoEletronico(2, "geladeira", 2030, "Geladeira Duas portas", "B"); samp.novoLivro(3, "effective java", 80, "um dos melhores livros sobre java!", "tcnico/tecnologia/programao/java", 300); samp.novoLivro(4, "senhor dos anis 2", 23, "clssico", "romance/fico", 300); samp.novoMovel(5, "mesa de madeira", 503, "mesa de canto legal", "clara", "20x40x90"); samp.getProdutosPorValorMenorQue(600); }segunda-feira, 13 de dezembro de 2010
  • 34. { "id": 3, "nome": "effective java", "valor": 80, "tipo": "livro", "desc": "um dos melhores livros sobre java!", "categoria": "tcnico/tecnologia/programao/java", "qtd_pgs": 300 } { "id": 4, "nome": "senhor dos anis 2", "valor": 23, "tipo": "livro", "desc": "clssico", "categoria": "romance/fico", "qtd_pgs": 300 } { "id": 5, "nome": "mesa de madeira", "valor": 503, "tipo": "movel", "desc": "mesa de canto legal", "cor": "clara", "dimensao": "20x40x90" }segunda-feira, 13 de dezembro de 2010
  • 35. cache + db bigdata & latnciasegunda-feira, 13 de dezembro de 2010
  • 36. Big Datasegunda-feira, 13 de dezembro de 2010
  • 37. mas fora do #trendtopic... 1.000.000 tx/hora 100tx/seg.segunda-feira, 13 de dezembro de 2010
  • 38. no incio... Cdigo Banco de Dadossegunda-feira, 13 de dezembro de 2010
  • 39. depois... CACHE Cdigo Banco de Dadossegunda-feira, 13 de dezembro de 2010
  • 40. Estrura de Dados: Famlia de Colunas Durabilidade: Rplica Site: http://cassandra.apache.org Escrito em: Java + Conceito Dynamo & Big-Table Pontos Positivos: + Escalabilidade + Congurao Pontos Negativos: Google: cassandra & diggsegunda-feira, 13 de dezembro de 2010
  • 41. modelosegunda-feira, 13 de dezembro de 2010
  • 42. exemplo... Keyspace: Keyspace1 Famlia de Colunas: Standard1 nome chave valor timestamp da coluna porcelli telefone 1234-5678 1291325256 ...segunda-feira, 13 de dezembro de 2010
  • 43. final private CassandraClientPool pool; public CassandraSampleCode() { pool = CassandraClientPoolFactory.INSTANCE.get(); } public void novoDado(String nomeUsuario, String telefone, String email) { CassandraClient client = null; try { client = pool.borrowClient("localhost", 9160); Keyspace keyspace = client.getKeyspace("Keyspace1"); ColumnPath columnPath = new ColumnPath(); columnPath.setColumn_family("Standard1"); columnPath.setColumn(bytes("telefone")); keyspace.insert(nomeUsuario, columnPath, bytes(telefone)); columnPath.setColumn(bytes("email")); keyspace.insert(nomeUsuario, columnPath, bytes(email)); } finally { pool.releaseClient(client); } }segunda-feira, 13 de dezembro de 2010
  • 44. public String getTelefone(String nomeUsuario) { CassandraClient client = null; try { client = pool.borrowClient("localhost", 9160); Keyspace keyspace = client.getKeyspace("Keyspace1"); ColumnPath columnPath = new ColumnPath(); columnPath.setColumn_family("Standard1"); columnPath.setColumn(bytes("telefone")); Column colValue = keyspace.getColumn(nomeUsuario, columnPath); return string(colValue.getValue()); } catch (NotFoundException e) { return null; } finally { pool.releaseClient(client); } }segunda-feira, 13 de dezembro de 2010
  • 45. public static void main(String[] args) throws Exception { CassandraSampleCode samp = new CassandraSampleCode(); Assert.assertNull(samp.getTelefone("porcelli")); Assert.assertNull(samp.getEmail("porcelli")); samp.novoDado("porcelli", "+55 11 1234-5678", "[email protected]"); Assert.assertEquals("+55 11 1234-5678", samp.getTelefone("porcelli")); Assert.assertEquals("[email protected]", samp.getEmail("porcelli")); }segunda-feira, 13 de dezembro de 2010
  • 46. buscasegunda-feira, 13 de dezembro de 2010
  • 47. SELECT * FROM PRODUTO WHERE NOME LIKE TE%segunda-feira, 13 de dezembro de 2010
  • 48. segunda-feira, 13 de dezembro de 2010
  • 49. Estrura de Dados: Lista Invertida Durabilidade: Single Node Site: http://lucene.apache.org Escrito em: Java + Baixa Latncia Pontos Positivos: + Durabilidade + Padro Pontos Negativos: o/segunda-feira, 13 de dezembro de 2010
  • 50. OLAP On-line Analytical Processing is characterized by relatively low volume of transactions. Queries are often very complex and involve aggregations. For OLAP systems a response time is an effectiveness measure. OLAP applications are widely used by Data Mining techniques.segunda-feira, 13 de dezembro de 2010
  • 51. segunda-feira, 13 de dezembro de 2010
  • 52. persistncia poliglotasegunda-feira, 13 de dezembro de 2010
  • 53. quer saber mais?segunda-feira, 13 de dezembro de 2010
  • 54. Perguntas? @porcellisegunda-feira, 13 de dezembro de 2010
  • 55. Cdigo Fonte https://github.com/porcelli/j1brasil-sample-codesegunda-feira, 13 de dezembro de 2010
  • 56. Obrigado @porcelli github.com/porcelli about.me/porcelli porcelli.com.br [email protected] linkedin.com/in/alexandreporcellisegunda-feira, 13 de dezembro de 2010