Mostrando postagens com marcador Hibernate. Mostrar todas as postagens
Mostrando postagens com marcador Hibernate. Mostrar todas as postagens

domingo, 1 de setembro de 2013

JPA - Hibernate

JPA (Java Persistence API)

 http://www.marcomendes.com/ArquivosBlog/AloMundoJPA.pdf
 http://www.devmedia.com.br/articles/viewcomp.asp?comp=4590
 http://evandropaes.wordpress.com/2007/06/22/introducao-a-java-persistence-api-%E2%80%93-jpa/
 http://www.slideshare.net/caroljmcdonald/td09jpabestpractices2
 http://www.slideshare.net/guestf54162/jpa-java-persistence-api
 http://www.slideshare.net/rodrigocasca/jpa
 https://www.redhat.com/docs/manuals/jboss/jboss-eap-4.2/doc/Server_Configuration_Guide/Java_EE_5_Application_Configuration.html
 http://www.slideshare.net/junyuo/java-persistence-api-jpa-step-by-step-presentation
 
 JPA é um framework utilizado na camada de persistência para obter maior produtividade. Modo padrão de mapeamento Objeto/Relacional.
 O JPA define um caminho para mapear os POJOs para um BD (Java Persistence Metadata). Os pojos são vistos como beans de entidade(Entity Beans).
 Utiliza-se o ORM(Mapeamento Objeto/Relacional) para os entity Beans possam ser portados facilmente de um fabricante para outro.
 
 
 
  Entity: POJO, suporta herança e polimorfismo
 EntityManager: Responsável pelas operações de persistência de objetos.
 PersistenceContext: Área de memória que mantém os objetos que estão sendo manipulados pelos EntityManager
 Provedores: Especificação para framework de persistência.
 Persistence Unit: Configuração do provedor JPA para localizar o banco de dados e estabelecer conexões JDBC.
 
 Exemplo simples:
 package addressbook;
 import javax.persistence.*;
 
 @Entity
 public class Person {
   @Id @GeneratedValue
   public Long id;
   public String first;
   public String middle;
   public String last;
 }
 
 package addressbook;
 import javax.persistence.*;
 
 public class Main {
   EntityManagerFactory factory; //Um factory por aplicação, pois é thread-safe. Mas só é importante para aplicações Web. App desktop só tem 1 usuário mesmo.
   EntityManager manager;       //Um manager por usuário.    
   
   public void init() {
     factory = Persistence.createEntityManagerFactory("sample");//Persistence unit no persistence.xml.
     manager = factory.createEntityManager();
   }
 
   private void shutdown() {
     manager.close();
     factory.close();
   }
   
   public static void main(String[] args) {
     // TODO code application logic here
     Main main = new Main();
     main.init();
     try {
       // do some persistence stuff
     } catch (RuntimeException ex) {
       ex.printStackTrace();
     } finally {
       main.shutdown();
     }
   }
 //Para fazer uma persistência, é só criar uma transação, criar os objetos e salvá-los
   private void create() {
     System.out.println("creating two people");
     EntityTransaction tx = manager.getTransaction(); //Criou a Transação.
     tx.begin();
     try {
       Person person = new Person();
       person.first = "Joshua";
       person.middle = "Michael";
       person.last = "Marinacci";
       manager.persist(person);
 
       tx.commit();
     } catch (Exception ex) {
       tx.rollback();
     }
     System.out.println("created one person");
   }
 }
 
 Chaves compostas usando @EmbeddedId
 @Embeddable
 public class ContactPK implements Serializable {
 
   @Column(name = "FIRSTNAME", nullable = false)
   private String firstname;
 
   @Column(name = "LASTNAME", nullable = false)
   private String lastname;
 }
 A chave primária da classe da Entidade é anotada com a anotação @EmbeddedId.
 @Entity
 public class Contact implements Serializable {
 
   /**
    * EmbeddedId primary key field
    */
   @EmbeddedId
   protected ContactPK contactPK;
 
   public void hashcode(){} // tem que incluir esses dois métodos para garantir que terá só uma chave.
   public void equals() {}
 ...
 }
 
 
 Persistence.xml
 •     Lista as classes a serem persistidas
 •     A conexão do Banco de Dados
 •     E propriedades específicas para a implementação de persistência (ex:Hibernate, Hypersonic)
 •     Deve ficar dentro do META-INF
 
 <?xml version="1.0" encoding="UTF-8"?>
 <persistence xmlns="http://java.sun.com/xml/ns/persistence"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation=
   "http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
   version="1.0">
   <persistence-unit name="sample" transaction-type="RESOURCE_LOCAL"> //Tem o nome da unidade, que tem que ser o mesmo recebido em Persistence.createEntityManagerFactory()
    <class>addressbook.Person</class>
    <properties>
      <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/>
      <property name="hibernate.connection.username" value="sa"/>
      <property name="hibernate.connection.password" value=""/>
      <property name="hibernate.connection.url"  value="jdbc:hsqldb:hsql://test"/>
      <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
      <property name="hibernate.hbm2ddl.auto" value="update"/> //Controla como o hibernate cria e gerencia as suas tabelas
 o     Validate:
 o     Update: Cria as tabelas se elas não existirem, se adicionar novos campos, altera a tabela, deixando os dados intactos.
 o     Create: Cria a tabela na primeira conexão, destruindo todos os dados anteriores. Bom para teste.
 o     Create-drop: como o Create, mas destroy a tabela quando a conexão é fechada. Bom pra teste de unidade.
    </properties>
   </persistence-unit>
 </persistence>
 
 Rodar
 java -classpath lib/hsqldb.jar org.hsqldb.Server //Para rodar o hypersonic
 
 public static void main(String[] args) throws Exception {
    // start hypersonic
    Class.forName("org.hsqldb.jdbcDriver").newInstance();
    Connection c = DriverManager.getConnection(
         "jdbc:hsqldb:file:test", "sa", "");
    // start persistence
    Main main = new Main();
    main.init();
 
    // rest of the program....
 
   // shutdown hypersonic
   Statement stmt = c.createStatement();
   stmt.execute("SHUTDOWN");
   c.close();
 }
 
 Outros exemplos de Persistence.xml
 http://download.oracle.com/docs/cd/B31017_01/web.1013/b28221/cfgdepds005.htm
      Usado para o servidor saber qual DabaBase será usado. Nele é configurado qual engine de mapeamento Objeto/Relacional, cache para melhor performance. Ele dá a flexibilidade completa para configurar o EntityManager.
 
      Colocar em: META-INF dentro do diretorio WEB-INF/classes ou do Jar.
 OpenJPA
 <?xml version="1.0"?>
 <persistence>
   <persistence-unit name="testjpa" transaction-type="RESOURCE_LOCAL">
     <provider>
       org.apache.openjpa.persistence.PersistenceProviderImpl
     </provider>
     <class>entidades.Cliente</class>
     <properties>
       <property name="openjpa.ConnectionURL" value="jdbc:postgresql://localhost:5432/jpateste"/>
       <property name="openjpa.ConnectionDriverName" value="org.postgresql.Driver"/>
       <property name="openjpa.ConnectionUserName" value="postgres"/>
       <property name="openjpa.ConnectionPassword" value="123456"/>
       <property name="openjpa.Log" value="SQL=TRACE"/>
     </properties>
   </persistence-unit>
 </persistence>
 
 Hibernate
 <persistence>
  <persistence-unit name="EmployeeService" transaction-type="RESOURCE_LOCAL">
 
   <provider>org.hibernate.ejb.HibernatePersistence</provider>
   <jta-data-source>java:/DefaultDS</jta-data-source>
   <properties>
    <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
    <property name="hibernate.connection.driver_class" value="org.apache.derby.jdbc.EmbeddedDriver"/>
    <property name="hibernate.connection.url" value="jdbc:derby:db; create=true"/>
    <property name="hibernate.connection.autocommit" value="true"/>
    <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" ou “DerbyDialect”/>
    <property name="hibernate.connection.username" value="APP" />
    <property name="hibernate.connection.password" value="APP" />
 
   </properties>
  </persistence-unit>
  OU
 <persistence>
  <persistence-unit name="EmployeeService" transaction-type="RESOURCE_LOCAL">
   <properties>
      <property name="hibernate.connection.driver_class" value="org.apache.derby.jdbc.ClientDriver" />
      <property name="hibernate.connection.url" value="jdbc:derby://localhost:1527/EmpServDB;create=true" />
      <property name="hibernate.connection.username" value="APP" />
      <property name="hibernate.connection.password" value="APP" />
      <property name="hibernate.dialect" value="org.hibernate.dialect.DerbyDialect" />
 </properties>
  </persistence-unit>
 </persistence>
 
 TopLink
 <persistence>
 <persistence-unit name="EmployeeService" transaction-type="RESOURCE_LOCAL">
  <properties>
      <property name="toplink.jdbc.driver" value="org.apache.derby.jdbc.ClientDriver"/>
      <property name="toplink.jdbc.url" value="jdbc:derby://localhost:1527/EmpServDB;create=true"/>
      <property name="toplink.jdbc.user" value="APP"/>
      <property name="toplink.jdbc.password" value="APP"/>
  </properties>
 </persistence-unit>
 </persistence>
 
 
 
 Tabela:
 create table bug (
 id_bug int(11) not null auto_increment,
 titulo varchar(60) not null,
 data date default null,
 texto text not null,
 primary key (id_bug)
 );
 
 Classe POJO
 @entity
 @table(name=”bug”)
 public class bug implements java.io.serializable {
      private integer id_bug;
      private string titulo;
      private java.util.date data;
      private string texto;
      @Enumerated(EnumType.STRING) → Define que um tipo vem de um enum
      @Conumn(name=”TIPO_MOEDA”, nullable=false, columnDefinition=”CHAR(1)”))
      private TipoMoeda tipoMoeda;
      @Transient → Valor não será gravado.
      private Integer valor = new Integer();
      /** creates a new instance of bug */
      public bug() {}
      /*a notação @generatedvalue(strategy=generationtype.sequence) informa que o id será gerado automaticamente pelo db.*/
      @id
      @generatedvalue(strategy=generationtype.sequence)
      @column(name=”id_bug”)
      public integer getid_bug() {     return id_bug;     }
      public void setid_bug(integer id_bug) {     this.id_bug = id_bug;     }
 
      @column(name=”titulo”, lenght=255, nullable=true)
      public string gettitulo() {     return titulo;     }
      public void settitulo(string titulo) {          this.titulo = titulo;     }
 
      @temporal(temporaltype.date)
      @column(name=”data”)
      public java.util.date getdata() {     return data;     }
      public void setdata(java.util.date data) {     this.data = data;     }
 
      @column(name=”texto”)
      @Lob → Define que o campo armazenará dados do tipo Long Object Binary(texto)
      public string gettexto() {     return texto;     }
      public void settexto(string texto) {     this.texto = texto;     }
      @override
      public string tostring(){     return “id: “+this.id_bug;     }
 }
 
 Query
 •     NamedQuery
 o     Query predefinidaes executadas por nome.
 @NamedQuery cria consulta predefinida (estática) associado com o @Entity
 
 @Entity
 @NamedQuery(name = “ConsultaPorId”, query = “SELECT f FROM Funcionarios f WHERE f.id = :id”)
 public class Funcionario implements Serializable {
 ...
 }
 
 •     Criteria
 o     So do Hibernate, baseado na API Criteria
 •     By Example
 •     JPAQL/ HQL / EJB3-QL
 o     Parecidas com SQL, mas mais objec-centric
 o     Suporta (Seleção de instancias, propriedades, polimorfismo), joining automático para propriedades nested.
 o     Confortável para quem é familiar ao SQL
 o     JPAQL é um subconjunto do HQL (Hibernate suporta ambos)
 o     Para rodar:
      EntityManager.createQuery(String jpaql)
      Session.createQuery(String hql)
 Ex: “from Item i where i.name = “aaa”
   private void search() {
     EntityTransaction tx = manager.getTransaction();
     tx.begin();
     System.out.println("searching for people");
     Query query = manager.createQuery("select p from Person p");
     List<Person> results = (List<Person>)query.getResultList();
     for(Person p : results) {
       System.out.println("got a person: " + p.first + " " + p.last);
     }
     System.out.println("done searching for people");
     tx.commit();
   }
 
 
 •     Native SQL
 o     Session.createSQLQuery(SQL)
 o     EntityManager.createNativeQuery(sql)
 
 
 
 Relacionamento
 •     Um para Um (@OneToOne)
 @OneToOne (mapedBy = “pessoa”)
 private Ramal ramal;
 
 @OneToOne
 @JoinColumn( name = “id_pessoa”)
 private Pessoa pessoa;
 Tabelas.
 ramal                    pessoa
  - numero:Integer                - id:Integer
  - pessoa_id: Integer (FK)           - nome: VARCHAR(50)
 
 
 •     Um para Muitos(@OneToMany)´
 Uma entidade possui uma coleção de outras entidades.
 @OneToMany(mappedBy=”pessoa”, cascade = CascadeType.ALL)
 private List<Ramal> ramais = new ArrayLIst<Ramal>();
 •     Muitos para um (@ManyToOne)
 A entidade faz parte de uma coleção de entidades de outra entidade.
 @ManyToOne(cascade=CascadeType.PERSIST)
 @JoinColumn(name=”id_pessoa”)
 private Pessoa pessoa;
 
 •     Muitos para muitos(@ManyToMany)
 @ManyToMany
 @JoinTable(name=”ramal_pessoa”,
 joinColumns=(@JoinColumn(name = “id_pessoa”)),
 inverseJoinColumns = (@JoinColumn(name = “id_ramal”))
 )
 @Column (name = “id_ramal”);
 private List<Ramal> ramais = new ArrayList<Ramal>();
       
 @ManyToMany
 @JoinTable(name=”ramal_pessoa”,
 joinColumns=(@JoinColumn(name = “id_ramal”)),
 inverseJoinColumns = (@JoinColumn(name = “id_pessoa”))
 )
 @Column(name = “id_pessoa”)
 private List<Ramal> pessoas= new ArrayList<Ramal>();
 
 Tabelas:
 Ramal               pessoa_has_ramal                    pessoa
  - numero:INTEGER     - pessoa_id: INTEGER (FK)                - id:INTEGER
                - ramal_numero: INTEGER                - nome: VARCHAR(50)
 
 Características dos Relacionamentos:
 •     Lazy loading
 o     Otimização de Performance
 o     Itens relacionados não são carregados até que eles sejam acessados pela primeira vez. (acesso a nível de Campo)
 o     Limitado para trabalhar somente com a Sessão ou EntityManager que carregou o objeto pai.
      Pode causar problemas em aplicações web.
 •     Fetch
 o     Fetch Mode
      Lazy
      Eager – desabilita o lazy loading
 o     Modo pode ser configurado em cada relacionamento.
 o     Considerar a performance e usar quando estiver configurando o fetch.
 @Basic(fetch = FetchType.LAZY) //Só vai carregar o objeto quando o método for acessado.
 @Lob      //Permite um BLOB ou CLOB (Bit or Char Large Object transforma valores para charS ou biteS
 public BufferedImage getPhoto() {
   return photo;
 }
 
 
 •     Cascading
 o     Fala do Hibernate o que fazer com o relacionamento nos casos de Insert, Update, Delete, All
 o     Cascade=PERSIST, REMOVE, MERGE, REFRESH, ALL.
 •     Polimorphic
 o     Três abordagens:
      Tabela por hierarquia de classe
 •     Todo dado de todas as propriedades das classes na herança são guardadas na tabela.
 •     Requer que as colunas que representam campos na subclasses permitam NULL.
 •     Usa uma coluna discriminadora para determinar o tipo de objeto representado em uma tupla.
 @Entity
 @Inheritance(strategy=InheritanceType.SINGLE_TABLE)
 @DiscriminatorColumn(name=”person_type”)
 public class Person {
      @Id     @GeneratedValue(strategy=GenerationType.AUTO)
      private int id = 0;
      private String name;
 }
 @Entity @DiscriminatorValue(value=”p”
 public class Patient extends Person {
      private boolean insured = false;
 }
 @Entity @DiscriminatorValue(value=”d”)
 public class Physician extends Person {
      private boolean accredited;
 }
 
 create table person {
      patient_id INTEGER,
      person_type varchar(255) not null,
      name varchar(255) not null,
      insured bit
      accredited bit
      primary key (patient_id));
 
      Tabela por sub-classe.
 •     Cada sub-classe tem a sua própria tabela.
 •     Campos da classe Pai estão em outra tabela.
 •     PK na tabela da sub-classe referem à tabela da classe pai.
 •     Usar configuração joined-subclass
 •     Também suporta o uso de discriminator
 @Entity     @Inheritance(strategy=InheritanceType.JOINED)
 public abstract class Payment
      @Id     @Column(name=”payment_id”)
      @GeneratedValue(strategy=GenerationType.AUTO)
      private int id = 0;
 }
 @Entity @Table(name=”check_payment”)
 @PrimaryKeyJoinColumn(name=”payment_id”)
 public class CheckPayment extends Payment{    
      private int check;
 }
 @Entity @Table(name=”credit_card_payment”)
 @PrimaryKeyJoinColumn(name=”payment_id”)
 public class CreditCardPayment extends Payment{    
      @Column(nullable=false)
      private String account;
 }
 create table payment { payment_id INTEGER, amount INTEGER, primary key(payment_id));
 create table check_payment { payment_id INTEGER, check-numer INTEGER, primary key(payment_id));
 create table credit_card_payment { payment_id INTEGER, account INTEGER, primary key(payment_id));
 
      Table por classe concreta
 •     Cada classe na hierarquia tem a sua própria tabela.
 •     O campos da classe pai são duplicadas em cada tabela.
 •     Duas abordagens:
 o     Subclass Union.
      Mapeia a classe pai normalmente, sem discriminador.
      @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
      Papeia cada uma das subclasses
 •     Especifica o nome da tabela
 •     Especifica as propriedades das subclasses
 o     Polimorfismo Implícito
      Class pai não é mapeada usando hibernate (@MappedSuperclass)
      Cada subclasse é mapeada como uma clase normal.
 •     Mapeia todas as propriedades, inclusive as propriedades do pai.
 @MappedSuperclass
 public class Vehicle{               //Class não é mapeada, mas as propriedades são.
      @Id      @Column(name=”vehicle_id”)
      @GeneratedValue(strategy=GenerationType.AUTO)
      private int id;
 }
 @Entity
 public class Car extends Vehicle{
      boolean coupe;
 }
 @Entity
 public class Truck extends Vehicle {
      @Column (name=”Max_weight”)
      private int maxWeight;
 }
 public SUV extends Truck {
      @Column (name=”spinner_wheels”)
      private boolean spinnerWheels;
 }
 create table vehicle ( vehicle_id INTEGER, coupe_ind bit, primary key(vehicle_id));
 create table truck ( vehicle_id INTEGER, max_weight bit, primary key(vehicle_id));
 create table suv ( vehicle_id INTEGER, max_weight bit, primary key(vehicle_id));
 
 
 Sem EJB
 EntityManagerFactory emf = Persistence.createEntityManagerFactory(“myapp);//O que está no persistence-unit
 EntityManager em = emf.createEntityManager();
 EntityTransaction et = em.getTransaction();
 et.begin();
      Insert: em.persist(carro);
      Update: em.merge(carro);
      Remove: em.remove(carro);
      Busca: Carro carro = em.find(Carro.class, id);
 et.commit() ou et.roolback();
 
 Com EJB
 EntityManagerFactory emf = Persistence.createEntityManagerFactory(“myapp);//O que está no persistence-unit
 @PersistenceContext
 EntityManager em = emf.createEntityManager();
 EntityTransaction et = em.getTransaction();
 et.begin();
      Insert: em.persist(carro);
      Update: em.merge(carro);
      Remove: em.remove(carro);
      Busca: Carro carro = em.find(Carro.class, id);
 et.commit() ou et.roolback();
 
  6.4.9.1 Entity Manager
 
 •     No Hibernate
 o     Configuration -> SessionFactoryy -> Session
 o     Session é o gateway para as funções de persistência.
 •     JPA
 o     Persistence -> EntityManagerFactory -> EntityManager
 o     EntityManager é o gateway para as funções de persistência.
 
 Ciclo de Vida de um Objeto
 Um objeto(Entity) pode ter 4 estados que indicam como eles estão conectados ao BD.
 •     New(transient): Objeto foi criado, mas ainda não foi persistido ou associado ao BD. Ao ser salvo com o EntityManager.persist() ele passa ao estado Managed.
 •     Managed(Persistent): O objeto já está associado ao BD. Mudanças no objeto vão, potencialmente gerar mudança no BD. Se necessário pode-se chamar EntityManager.flush() para sincronizar as mudanças, senão somente no commit da transação.
 •     Detached: O objeto já foi associado ao BD, mas não está mais. Um objeto Detached pode ser reatached usando o EntityManager.merge().
 •     Removed: Objeto que recebeu a operação de remoção. EntityManager.remove();
 
 Similar ao Hibernate Session, controla o ciclo de vida das entidades.
 •     new() → Cria uma nova entidade
 •     persist() → Salva ou faz um update em uma entidade
      public Order createNewOrder(Customer customer){
           Order order = new Order(customer);
           entityManager.persist(order);
           return order;          }
 •     refresh() → Atualiza o estado da entidade
 •     remove() → Marca uma entidade para remoção
      public void removeOrder(Long orderId){
           Order order = entityManager.find(Order.class, orderId);
           entityManager.remove(order);      }
 •     merge() → Sincroniza o estado de entidades desacopladas.
      public void updateOrder(Order order){
           entityManager.merge(order);      }
 •     find(Class type, Serializeble id) – Obtém o item de um tipo pelo id
 •     getTransaction
 ◦     Prove um objeto de transação para fazer o commit e rollback.
 
 

quinta-feira, 22 de agosto de 2013

Spring with Data Base

From the book:
    Spring in Action 3rd Edition.
    Link to it-ebooks to Download


- Spring with Data Base
    Spring suports: JDBC, Hibernate, JPA(Java Persistence API), etc
    Objetivo do Spring e usar o conceito de interface do OO.  This is done in the Spring's data access
    Different from JDBC, Spring provides several data access exceptions rather than SQLException.
        The main exception DataAccessException is checked exception.
    Templating data access
        Two parts
            fixed(templates)
                Controls transaction, manages resouces, handle exceptions
            variable(callbacks)              
                create statements, bind parameters, marshals result sets
            Steps
                1- Prepare resources
                2 - Start Transaction        3 - Excecute in tarnsaction
                                            4 - Return data
                5 - Commit/Rollback transaction
                6 - Closes resources and handle erros
        Several different kinds of templates? JDBCTempale, HibernateTemplate, JpaTemplate, etc
    Configuring a data source
        Main options for configuring data source beans
        - JDBC Driver
            Two data source classes to choose?
                - DriverManagerDataSource: Returns a niew connection every time that a connection is requested.  No pool
                - SingleConnectionDataSource: Return the same connection every time a connection is requested.
                <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
                    <propertyname="driverClassName"
                    value="org.hsqldb.jdbcDriver"/>
                    <propertyname="url"
                    value="jdbc:hsqldb:hsql://localhost/spitter/spitter"/>
                    <propertyname="username"value="sa"/>
                    <propertyname="password"value=""/>
                </bean>      
                - Good for small applications or development.
        - look up by JNDI
            Usually in a Java EE application server/container.
            Configuration can be managed completely external
            <jee:jndi-lookupid="dataSource"
                jndi-name="/jdbc/SpitterDS"
            resource-ref="true"/>              
        - pool connections
            Uses Jakarta Commons Database connection Pooling(DBCP)
            Includes several data sources that provide pooling. Most used = BasicDataSource(similar to DriverManagerDataSource)
            <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
                <propertyname="driverClassName"value="org.hsqldb.jdbcDriver"/>
                <propertyname="url" value="jdbc:hsqldb:hsql://localhost/spitter/spitter"/>
                <propertyname="username"value="sa"/>
                <propertyname="password"value=""/>
                <propertyname="initialSize"value="5"/>
                <propertyname="maxActive"value="10"/>
            </bean>              
       
    Using JDBC with Spring
        - Dont require mastering another framework's query language
        - It's built on top of SQL
        - Take advantage of database's proprietary features
        - Lets you work with data as a lower level than any framework
            private static final String SQL_INSERT_SPITTER= "insert into spitter(username,password,fullname)values(?,?,?)";
            private DataSourcedataSource;
                public voidaddSpitter(Spitterspitter){
                    Connectionconn=null;
                    PreparedStatementstmt=null;          
                    try {
                        conn =dataSource.getConnection();
                        stmt =conn.prepareStatement(SQL_INSERT_SPITTER);
                        stmt.setString(1,spitter.getUsername());
                        stmt.setString(2,spitter.getPassword());
                        stmt.setString(3,spitter.getFullName());
                        stmt.execute();
                    }.... finally, SQLException....
                }
        JDBC Templates (Three templates classes)
            - JdbcTemplate: Most basic of Spring's JDBC templates.
                Provide simple access to a database through JDBC and simple indexed-parameter queries
            - NamedParameterJdbcTemplate:
                Enables you to perform queries where values are bound to named parameters in SQL, rather than indexed parameters
            - SimpleJdbcTemplate: (Most important)
                Take advantage of Java 5 with autoboxing, generics and variable parameter lists
                <bean id="jdbcTemplate" class="org.springframework.jdbc.core.simple.SimpleJdbcTemplate">
                    <constructor-argref="dataSource"/>
                </bean>
                ....
                public classJdbcSpitterDAO implements SpitterDAO{
                    ...
                    privateSimpleJdbcTemplatejdbcTemplate;
                    public voidsetJdbcTemplate(SimpleJdbcTemplatejdbcTemplate){
                        this.jdbcTemplate=jdbcTemplate;
                    }
                    public voidaddSpitter(Spitterspitter){
                        jdbcTemplate.update(SQL_INSERT_SPITTER,
                            spitter.getUsername(),
                            spitter.getPassword(),
                            spitter.getFullName(),
                            spitter.getEmail(),
                            spitter.isUpdateByEmail());
                            spitter.setId(queryForIdentity());
                    }
                   
                    public SpittergetSpitterById(longid){
                        return jdbcTemplate.queryForObject(
                        SQL_SELECT_SPITTER_BY_ID,
                        new ParameterizedRowMapper<Spitter>(){
                            public Spitter mapRow(ResultSet rs,int rowNum) <- para cada linha cria um Spitter dentro do resultSet
                                throws SQLException{
                                    Spitter spitter=newSpitter();
                                    spitter.setId(rs.getLong(1));
                                    spitter.setUsername(rs.getString(2));
                                    spitter.setPassword(rs.getString(3));
                                    spitter.setFullName(rs.getString(4));
                                    return spitter;
                                }
                            },
                            id
                        );
                    }
                }
                - How to access the template via DAO
                <bean id="spitterDao" class="com.habuma.spitter.persistence.SimpleJdbcTemplateSpitterDao">
                    <propertyname="jdbcTemplate"ref="jdbcTemplate"/>
                </bean>
            - DAO Support Classes for JDBC
                - public class JdbcSpitterDao extends SimpleJdbcDaoSupport implements SpitterDao {
                    public void addSpitter(Spitter spitter){
                        getSimpleJdbcTemplate().update(SQL_INSERT_SPITTER,
                            spitter.getUsername(),
                            spitter.getPassword(),
                            spitter.getFullName(),
                            spitter.getEmail(),
                            spitter.isUpdateByEmail());
                        spitter.setId(queryForIdentity());
                    }
                 }
                 <bean id="spitterDao" class="com.habuma.spitter.persistence.JdbcSpitterDao">
                    <property name="jdbcTemplate" ref="jdbcTemplate"/>
                </bean>
    Hibernate with Spring
        Services
            - Integrated support for Spring declarative transactions
            - Transparent exception handling
            - Thread-safe, lightweight template classes
            - DAO support classes
            - Resource management
        <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <property name="mappingResources">
                <list>
                    <value>Spitter.hbm.xml</value>  <<----  Indicates where find the database
                </list>
            </property>
            <property name="hibernateProperties">
                <props>
                <prop key="dialect">org.hibernate.dialect.HSQLDialect</prop>
                </props>
            </property>
        </bean>
         To use annotation-oriented persistence use AnnotationSessionFactoryBean instead of LocalSessionFactoryBean:
        <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
            <propertyname="dataSource"ref="dataSource"/>
            <property name="packagesToScan" value="com.habuma.spitter.domain"/>  <<<----  Scan the domain classes that are annotated for persistence with Hibernate
            OR
            <propertyname="packagesToScan">
                <list>
                    <value>com.habuma.spitter.domain</value>
                </list>
            </property>
            <property name="hibernateProperties">
                <props>
                    <propkey="dialect">org.hibernate.dialect.HSQLDialect</prop>
                </props>
            </property>
        </bean>
       
         packagesToScan
            Scan the domain classes that are annotated for persistence with Hibernate.
            Annotations can be     @Entity or @MappedSuperClass.
           
        Spring-Free Hibernate
            Ex:
                @Repository
                public class HibernateSpitterDao implements SpitterDao{
                    privateSessionFactorysessionFactory;
                    @Autowired  <<---  Pegaria a session já criada automaticamente.
                    public HibernateSpitterDao(SessionFactory sessionFactory){    this.sessionFactory=sessionFactory;    } <--- Constructor
                   
                    private Session currentSession(){    return sessionFactory.getCurrentSession(); } Retrieve the Current Session
                    public void addSpitter(Spitterspitter){    currentSession().save(spitter);    }
                    public Spitter getSpitterById(longid){ return(Spitter)currentSession().get(Spitter.class,id); }
                    public void saveSpitter(Spitterspitter){    currentSession().update(spitter);    }
                    ...
                }
            With <context:component-scan>, it is not necessary to explicit a DAO class in xml config.  You can just use @Repository
                    <context:component-scan base-package="com.habuma.spitter.persistence"/>
        JPA (Java Persistence API)
            - Two kind of persistence managers (both implements EntityManager)
                - Application-managed: Entity managers are created when a application directly request one from the factory.  Application is responsible
                    for opening and closing entity managers and the transaction.  Most apropriate for use in standalone applications that dont run in a J2EE container.
                - Container-managed: Entity managers are created and managed by the J2EE container.  App doesnt interact with the factory.  
                    Entity managers are obtained from JNDI.
            - Configure Application-managed JPA (persistence.xml)
            <persistencexmlns="http://java.sun.com/xml/ns/persistence"    version="1.0">
                <persistence-unit name="spitterPU">      <<<<--------------------------- unit name
                    <class>com.habuma.spitter.domain.Spitter</class>
                    <class>com.habuma.spitter.domain.Spittle</class>
                    <properties>
                        <property name="toplink.jdbc.driver" value="org.hsqldb.jdbcDriver"/>
                        <property name="toplink.jdbc.url"value="jdbc:hsqldb:hsql://localhost/spitter/spitter"/>
                        <property name="toplink.jdbc.user"value="sa" />
                        <property name="toplink.jdbc.password"value="" />
                    </properties>
                </persistence-unit>
            </persistence>
            <bean id="emf" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
                <property name="persistenceUnitName"value="spitterPU"/>  <<<<--------------------------- unit name
            </bean>

A project in Spring from www.wikidot.com

Step by Step of a project using spring.
- Spring MVC
- Validation
- Hibernate
- Maven
- Eclipse

http://andercidagastosspring.wikidot.com/