diff --git a/dados.sql b/dados.sql
index 3097ea8d..197f3f22 100644
--- a/dados.sql
+++ b/dados.sql
@@ -1,3 +1,48 @@
+
+-- ########################################################################################################
+-- ENSINO
+drop table if exists pessoa;
+drop table if exists aluno;
+drop table if exists disciplina;
+drop table if exists matricula;
+
+create table pessoa (
+    id serial primary key not null,
+    nome varchar(75) not null,
+    data_cadastro date not null
+);
+
+create table aluno (
+    id serial primary key not null,
+    pessoa_id int not null,
+    data_cadastro date not null,
+    constraint fk_aluno_pessoa foreign key (pessoa_id) references pessoa(id)
+);
+
+alter table aluno add matricula varchar (10) not null;
+
+create table disciplina (
+    id serial primary key not null,
+    nome varchar(75) not null,
+    codigo varchar(6) not null,
+    data_cadastro date not null
+);
+
+create table matricula(
+    id serial primary key not null,
+    aluno_id int not null,
+    disciplina_id int not null,
+    data_cadastro timestamp not null default current_timestamp,
+    nota1 decimal(10,2) null,
+    nota2 decimal(10,2) null,
+    media decimal(10,2) null,
+    constraint fk_matricula_aluno foreign key (aluno_id) references aluno(id),
+    constraint fk_matricula_disciplina foreign key (disciplina_id) references disciplina(id)
+);
+
+-- ########################################################################################################
+
+
 -- Script PostgreSQL com cadastro de cidades e estados do país, conforme IBGE.
 -- Adaptado de https://www.ricardoarrigoni.com.br/cidades-brasil-lista-de-cidades-brasileiras-em-sql/
 -- Área por estado: https://pt.wikipedia.org/wiki/Lista_de_unidades_federativas_do_Brasil_por_área
diff --git a/src/main/java/com/example/App.java b/src/main/java/com/example/App.java
index 9407ea49..040be82c 100644
--- a/src/main/java/com/example/App.java
+++ b/src/main/java/com/example/App.java
@@ -1,93 +1,41 @@
 package com.example;
 
-import java.sql.Connection;
-import java.sql.DriverManager;
 import java.sql.SQLException;
+import java.util.List;
+
+import com.example.dao.ConnectManager;
+import com.example.dao.EstadoDAO;
+import com.example.model.Estado;
 
 public class App {
-    private static final String PASSWORD = "";
-    private static final String USERNAME = "gitpod";
-    private static final String JDBC_URL = "jdbc:postgresql://localhost/postgres";
 
     public static void main(String[] args) {
         new App();
     }
 
     public App(){
-        try(var conn = getConnection()){
-            carregarDriverJDBC();
-            listarEstados(conn);
-            localizarEstado(conn, "PR");
-            listarDadosTabela(conn, "produto");
-        } catch (SQLException e) {
-            System.err.println("Não foi possível conectar ao banco de dados: " + e.getMessage());
-        }        
-    }
-
-    private void listarDadosTabela(Connection conn, String tabela) {
-        var sql = "select * from " + tabela;
-        //System.out.println(sql);
-        try {
-            var statement = conn.createStatement();
-            var result = statement.executeQuery(sql);
-
-            var metadata = result.getMetaData();
-            int cols = metadata.getColumnCount();
-
-            for (int i = 1; i <= cols; i++) {
-                System.out.printf("%-25s | ", metadata.getColumnName(i));
+        try(var conn = ConnectManager.getConnection()){
+            //carregarDriverJDBC();
+            
+            EstadoDAO estadoDAO = new EstadoDAO(conn);
+            //estadoDAO.listarConsole("estado");
+            List<Estado> estados = estadoDAO.listar();
+            for (Estado estado : estados) {
+                System.out.println(estado);
             }
-            System.out.println();
-
-            while(result.next()){
-                for (int i = 1; i <= cols; i++) {
-                    System.out.printf("%-25s | ", result.getString(i));
-                }
-                System.out.println();
+            
+            Estado estado = estadoDAO.listarPorUF("DF");
+            if(estado != null){
+                System.out.println(estado);
             }
-        } catch (SQLException e) {
-            System.err.println("Erro na execução da consulta: " + e.getMessage());
-        }
-        
-    }
-
-    private void localizarEstado(Connection conn, String uf) {
-        try{
-            //var sql = "select * from estado where uf = '" + uf + "'"; //suscetível a SQL Injection
-            var sql = "select * from estado where uf = ?";
-            var statement = conn.prepareStatement(sql);
-            //System.out.println(sql);
-            statement.setString(1, uf);
-            var result = statement.executeQuery();
-            if(result.next()){
-                System.out.printf("Id: %d Nome: %s UF: %s\n", result.getInt("id"), result.getString("nome"), result.getString("uf"));
-            }
-            System.out.println();
-        } catch(SQLException e){
-            System.err.println("Erro ao executar consulta SQL: " + e.getMessage());
-        }
-        
-    }
 
-    private void listarEstados(Connection conn) {
-        try{
-            System.out.println("Conexão com o banco realizada com sucesso.");
 
-            var statement = conn.createStatement();
-            var result = statement.executeQuery("select * from estado");
-            while(result.next()){
-                System.out.printf("Id: %d Nome: %s UF: %s\n", result.getInt("id"), result.getString("nome"), result.getString("uf"));
-            }
-            System.out.println();
         } catch (SQLException e) {
-            System.err.println("Não foi possível executar a consulta ao banco: " + e.getMessage());
-        }
-    }
-
-    private Connection getConnection() throws SQLException {
-        return DriverManager.getConnection(JDBC_URL, USERNAME, PASSWORD);
+            System.err.println("Não foi possível conectar ao banco de dados: " + e.getMessage());
+        }        
     }
 
+    
     private void carregarDriverJDBC() {
         try {
             Class.forName("org.postgresql.Driver");
diff --git a/src/main/java/com/example/dao/ConnectManager.java b/src/main/java/com/example/dao/ConnectManager.java
new file mode 100644
index 00000000..3f5f8818
--- /dev/null
+++ b/src/main/java/com/example/dao/ConnectManager.java
@@ -0,0 +1,17 @@
+package com.example.dao;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+
+public class ConnectManager {
+
+    public static final String PASSWORD = "";
+    public static final String USERNAME = "gitpod";
+    public static final String JDBC_URL = "jdbc:postgresql://localhost/postgres";
+
+    public static Connection getConnection() throws SQLException {
+        return DriverManager.getConnection(JDBC_URL, USERNAME, PASSWORD);
+    }
+    
+}
diff --git a/src/main/java/com/example/dao/DAO.java b/src/main/java/com/example/dao/DAO.java
new file mode 100644
index 00000000..e442cff6
--- /dev/null
+++ b/src/main/java/com/example/dao/DAO.java
@@ -0,0 +1,38 @@
+package com.example.dao;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+public class DAO {
+    protected Connection conn;
+
+    public DAO(Connection conn) {
+        this.conn = conn;
+    }
+
+    public void listarConsole(String tabela){
+        var sql = "select * from " + tabela;
+        
+        try {
+            var statement = conn.createStatement();
+            var result = statement.executeQuery(sql);
+
+            var metadata = result.getMetaData();
+            int cols = metadata.getColumnCount();
+
+            for (int i = 1; i <= cols; i++) {
+                System.out.printf("%-25s | ", metadata.getColumnName(i));
+            }
+            System.out.println();
+
+            while(result.next()){
+                for (int i = 1; i <= cols; i++) {
+                    System.out.printf("%-25s | ", result.getString(i));
+                }
+                System.out.println();
+            }
+        } catch (SQLException e) {
+            System.err.println("Erro na execução da consulta: " + e.getMessage());
+        }
+    }
+}
diff --git a/src/main/java/com/example/dao/EstadoDAO.java b/src/main/java/com/example/dao/EstadoDAO.java
new file mode 100644
index 00000000..6e9be62a
--- /dev/null
+++ b/src/main/java/com/example/dao/EstadoDAO.java
@@ -0,0 +1,52 @@
+package com.example.dao;
+
+import java.beans.Statement;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.util.LinkedList;
+import java.util.List;
+
+import com.example.model.Estado;
+
+public class EstadoDAO extends DAO {
+
+    public EstadoDAO(Connection conn) {
+        super(conn);
+        //TODO Auto-generated constructor stub
+    }
+    
+    public List<Estado> listar(){
+        List<Estado> retorno = new LinkedList<>();
+        try {
+            String sql = "select * from estado";
+            var statement = conn.createStatement();
+            var result = statement.executeQuery(sql);
+            while(result.next()){
+                Estado estado = new Estado(result.getLong("id"), result.getString("nome"), result.getString("uf"));
+                retorno.add(estado);
+            }
+        } catch (Exception e) {
+            System.out.println("Não foi possivel executar a consulta de ESTADO.");
+        }
+        return retorno;
+       
+    }
+
+    public Estado listarPorUF(String uf) {
+        Estado estado = null;
+        try {
+            String sql = "select * from estado where uf = ? limit 1";
+            var statement = conn.prepareStatement(sql);
+            statement.setString(1, uf);
+            var result = statement.executeQuery();
+            while(result.next()){
+                estado = new Estado(result.getLong("id"), result.getString("nome"), result.getString("uf"));
+            }
+        } catch (Exception e) {
+            // TODO: handle exception
+        }
+       
+        return estado;
+    }
+
+}
diff --git a/src/main/java/com/example/dao/PessoaDao.java b/src/main/java/com/example/dao/PessoaDao.java
new file mode 100644
index 00000000..c0a47701
--- /dev/null
+++ b/src/main/java/com/example/dao/PessoaDao.java
@@ -0,0 +1,11 @@
+package com.example.dao;
+
+import java.sql.Connection;
+
+public class PessoaDao extends DAO{
+    
+    public PessoaDao(Connection conn) {
+        super(conn);
+    }
+
+}
diff --git a/src/main/java/com/example/model/Aluno.java b/src/main/java/com/example/model/Aluno.java
new file mode 100644
index 00000000..d34d070c
--- /dev/null
+++ b/src/main/java/com/example/model/Aluno.java
@@ -0,0 +1,38 @@
+package com.example.model;
+
+import java.time.LocalDate;
+
+public class Aluno {
+    private Long id;
+    private String matricula;
+    private LocalDate dataCadastro;
+    private Pessoa pessoa;
+    
+    public Long getId() {
+        return id;
+    }
+    public void setId(Long id) {
+        this.id = id;
+    }
+    public String getMatricula() {
+        return matricula;
+    }
+    public void setMatricula(String matricula) {
+        this.matricula = matricula;
+    }
+    public LocalDate getDataCadastro() {
+        return dataCadastro;
+    }
+    public void setDataCadastro(LocalDate dataCadastro) {
+        this.dataCadastro = dataCadastro;
+    }
+    public Pessoa getPessoa() {
+        return pessoa;
+    }
+    public void setPessoa(Pessoa pessoa) {
+        this.pessoa = pessoa;
+    }
+
+
+    
+}
diff --git a/src/main/java/com/example/model/Disciplina.java b/src/main/java/com/example/model/Disciplina.java
new file mode 100644
index 00000000..3974417b
--- /dev/null
+++ b/src/main/java/com/example/model/Disciplina.java
@@ -0,0 +1,37 @@
+package com.example.model;
+
+import java.time.*;
+
+public class Disciplina {
+    private Long id;
+    private String nome;
+    private String codigo;
+    private LocalDate dataCadastro;
+    
+    public Long getId() {
+        return id;
+    }
+    public void setId(Long id) {
+        this.id = id;
+    }
+    public String getNome() {
+        return nome;
+    }
+    public void setNome(String nome) {
+        this.nome = nome;
+    }
+    public String getCodigo() {
+        return codigo;
+    }
+    public void setCodigo(String codigo) {
+        this.codigo = codigo;
+    }
+    public LocalDate getDataCadastro() {
+        return dataCadastro;
+    }
+    public void setDataCadastro(LocalDate dataCadastro) {
+        this.dataCadastro = dataCadastro;
+    }
+
+
+}
diff --git a/src/main/java/com/example/model/Estado.java b/src/main/java/com/example/model/Estado.java
new file mode 100644
index 00000000..b9c5758a
--- /dev/null
+++ b/src/main/java/com/example/model/Estado.java
@@ -0,0 +1,59 @@
+package com.example.model;
+
+public class Estado {
+    private Long id;
+    private String nome;
+    private String uf;
+    private RegiaoGeografica regiao;
+    private int areaKm2;
+    private int populacao;
+   
+    
+    public Estado(Long id, String nome, String uf) {
+        this.id = id;
+        this.nome = nome;
+        this.uf = uf;
+    }
+    public Long getId() {
+        return id;
+    }
+    public void setId(Long id) {
+        this.id = id;
+    }
+    public String getNome() {
+        return nome;
+    }
+    public void setNome(String nome) {
+        this.nome = nome;
+    }
+    public String getUf() {
+        return uf;
+    }
+    public void setUf(String uf) {
+        this.uf = uf;
+    }
+    public RegiaoGeografica getRegiao() {
+        return regiao;
+    }
+    public void setRegiao(RegiaoGeografica regiao) {
+        this.regiao = regiao;
+    }
+    public int getAreaKm2() {
+        return areaKm2;
+    }
+    public void setAreaKm2(int areaKm2) {
+        this.areaKm2 = areaKm2;
+    }
+    public int getPopulacao() {
+        return populacao;
+    }
+    public void setPopulacao(int populacao) {
+        this.populacao = populacao;
+    }
+
+    public String toString(){
+        return "Estado: " + uf + " - " + nome;
+    }
+
+
+}
diff --git a/src/main/java/com/example/model/Matricula.java b/src/main/java/com/example/model/Matricula.java
new file mode 100644
index 00000000..7507d0aa
--- /dev/null
+++ b/src/main/java/com/example/model/Matricula.java
@@ -0,0 +1,59 @@
+package com.example.model;
+
+import java.time.LocalDate;
+
+public class Matricula {
+
+    private Long id;
+    private Aluno aluno;
+    private Disciplina disciplina;
+    private Double nota1;
+    private Double nota2;
+    private Double media;
+    private LocalDate dataCadastro;
+    
+    public Long getId() {
+        return id;
+    }
+    public void setId(Long id) {
+        this.id = id;
+    }
+    public Aluno getAluno() {
+        return aluno;
+    }
+    public void setAluno(Aluno aluno) {
+        this.aluno = aluno;
+    }
+    public Disciplina getDisciplina() {
+        return disciplina;
+    }
+    public void setDisciplina(Disciplina disciplina) {
+        this.disciplina = disciplina;
+    }
+    public Double getNota1() {
+        return nota1;
+    }
+    public void setNota1(Double nota1) {
+        this.nota1 = nota1;
+    }
+    public Double getNota2() {
+        return nota2;
+    }
+    public void setNota2(Double nota2) {
+        this.nota2 = nota2;
+    }
+    public Double getMedia() {
+        return media;
+    }
+    public void setMedia(Double media) {
+        this.media = media;
+    }
+    public LocalDate getDataCadastro() {
+        return dataCadastro;
+    }
+    public void setDataCadastro(LocalDate dataCadastro) {
+        this.dataCadastro = dataCadastro;
+    }
+
+    
+}
diff --git a/src/main/java/com/example/model/Pessoa.java b/src/main/java/com/example/model/Pessoa.java
new file mode 100644
index 00000000..421e8ec8
--- /dev/null
+++ b/src/main/java/com/example/model/Pessoa.java
@@ -0,0 +1,30 @@
+package com.example.model;
+
+import java.time.*;
+
+public class Pessoa {
+
+    private Long id;
+    private String nome;
+    private LocalDate dataCadastro;
+    
+    public Long getId() {
+        return id;
+    }
+    public void setId(Long id) {
+        this.id = id;
+    }
+    public String getNome() {
+        return nome;
+    }
+    public void setNome(String nome) {
+        this.nome = nome;
+    }
+    public LocalDate getDataCadastro() {
+        return dataCadastro;
+    }
+    public void setDataCadastro(LocalDate dataCadastro) {
+        this.dataCadastro = dataCadastro;
+    }
+    
+}
diff --git a/src/main/java/com/example/model/RegiaoGeografica.java b/src/main/java/com/example/model/RegiaoGeografica.java
new file mode 100644
index 00000000..fdb74359
--- /dev/null
+++ b/src/main/java/com/example/model/RegiaoGeografica.java
@@ -0,0 +1,19 @@
+package com.example.model;
+
+public class RegiaoGeografica {
+    private Long id;
+    private String nome;
+    
+    public Long getId() {
+        return id;
+    }
+    public void setId(Long id) {
+        this.id = id;
+    }
+    public String getNome() {
+        return nome;
+    }
+    public void setNome(String nome) {
+        this.nome = nome;
+    }
+}
