• Home

    Escolha seu Plano

    Carreiras Alura

    Evolua com profundidade técnica, direção clara e aplicação prática.

    Jornadas guiadas do básico ao avançado com checkpoints práticos, desenhadas para quem busca profundidade e protagonismo técnico.

    Iniciante

    Comece do zero com uma trilha clara e progressiva.

    Fundamentos práticos para dar os primeiros passos com segurança e construir uma base sólida.

    Intermediário

    Continue sua evolução com cursos que conectam fundamentos, ferramentas e prática profissional. Ganhe autonomia, e avance para projetos mais completos.

    Avançado

    Aprofunde temas técnicos e estratégicos para enfrentar desafios mais complexos. Explore boas práticas, arquitetura, performance com visão profissional.

    Cursos

    Ver mais cursos de Back-end
    • Pensamento computacional: fundamentos da computação e lógica de programação
    • Lógica de programação: mergulhe em programação com JavaScript
    • DDD: fundamentos do design orientado a domínio
    • ASP.NET: autenticação e autorização em APIs e aplicações web
    • Microsserviços: migração de monólitos e modularização

    Cursos

    Ver mais cursos de Dados
    • Python para Dados: primeiros passos
    • Excel: domine o editor de planilhas
    • Engenharia de Dados: Orquestração de Pipelines com Apache Airflow
    • Power BI Desktop: construindo meu primeiro dashboard
    • Governança e Arquitetura de Dados

    Cursos

    Ver mais cursos de Inteligência Artificial
    • IA: Explorando o Potencial da Inteligência Artificial Generativa
    • Engenharia de Prompt: Criando Prompts Eficazes para IA Generativa
    • Claude para Análise de Dados: prompts, integrações e automações
    • Agno: criando agentes e sistemas multiagente
    • Engenharia de software na era da IA: segurança de aplicações com agentes, MCPs e código gerado por IA

    Cursos

    Ver mais cursos de Front-end
    • HTML e CSS: ambiente, estrutura e estilo
    • React: realizando testes avançados com Jest e Testing Library
    • React: integrando TypeScript em projetos
    • JavaScript: aprendendo a programar
    • React: aplicando arquiteturas de Micro frontends

    Cursos

    Ver mais cursos de DevOps
    • Sistema Operacional Linux: fundamentos e administração prática
    • Containers e Docker: empacotamento, isolamento e gestão
    • Redes: dos conceitos iniciais à criação de uma intranet
    • Linux: gerenciando diretórios, arquivos, permissões e processos
    • Cibersegurança: Fundamentos e práticas integradas

    Cursos

    Ver mais cursos de UX & Design
    • UX Research: mapeando a experiência da pessoa usuária
    • UX/UI Design: Entregando produtos digitais com IA
    • UI Design: Prototipação e animações interativas
    • Figma: Conhecendo o programa
    • Product Design: métricas e ciclo de vida do produto

    Cursos

    Ver mais cursos de Gestão & Negócios
    • Canva: Criação de landing pages e e-mail marketing
    • Agilidade: como ela pode ajudar a criar um time de alta performance
    • Google Analytics 4: Extrair insights e configurar eventos
    • Management 3.0: gerencie o ambiente, não as pessoas
    • Automação de processos com n8n: Inteligência de dados para Marketing

    Cursos

    Ver mais cursos de Mobile
    • React Native: Estilização e Layouts com Flexbox e StyleSheet
    • Flutter: Graphql e suporte offline
    • Android com Gemini: Trabalhando com textos e imagens na IA
    • Dart: trabalhando com orientação a objetos
    • React Native: Dominando Listas com FlatList e ScrollView

    Carreiras

    Ver mais carreiras
    • Especialista em IA
    • Engenharia de IA
    • Ai native software engineering
    • Arquitetura de Soluções com IA
    • AI Product Design
    • Engenharia de Machine Learning
    • Desenvolvimento Front-End React
    • Engenharia de Dados
    • Cloud Security
    • Social Media Marketing
    • Engenharia de Agentes de IA

    Cursos

    • Engenharia de Prompt: Prompts Eficazes para IA Generativa
    • Claude Code: Criando sua Primeira Aplicação
    • Python: Crie sua Primeira Aplicação
    • Git e GitHub: Compartilhando e Colaborando
    • N8N: Fluxos de Trabalho Avançados

    Cursos

    • Copilot Studio: Solução Multiagentes
    • Padrões de API HTTP e Modelagem de APIs
    • Python para Análise de Dados com SQL
    • Docker: Criando e Gerenciando Containers
    • Design com IA: Otimizando o Processo Criativo

    Cursos

    • Model Context Protocol (MCP)
    • Spec-Driven Development: Dev Assistido por Agentes
    • Arquitetura de Sistemas Distribuídos com Java
    • Governança de Modelos e Reprodutibilidade
    • Pentest: Vulnerabilidades em Aplicações Web

    Escolha seu Plano

    Skills & Go

    O Skills & Go é para Tech Leads, Product Managers, estrategistas e early adopters que transformam ideias em soluções de alto impacto. Em cursos ao vivo e 100% online, você domina a nova era da IA em tempo real.

    Aulas ao vivo

    Saiba mais
    • Agentic Engineering: orquestre múltiplos agentes com confiabilidade
    • Building AI Products: transforme ideias em produtos reais com IA
    • AI Data Strategy: transforme dados em decisões estratégicas com IA

    Escolha seu Plano

    Eventos Alura

    Nossos eventos são pensados para quem quer estar à frente das mudanças em tecnologia, IA e inovação. Em experiências presenciais, você acompanha tendências e se conecta com especialistas que estão moldando o futuro.

    Próximos eventos

    • Imersão Engenharia de Software: Dev na Era da IA
    • IA Conference
    • Alura Signals
  • Talent Lab
  • IA

    Escolha seu Plano

    Conteúdos gratuitos

    Explore conteúdos gratuitos para aprender tecnologia no seu ritmo. Encontre artigos com conteúdos técnicos para aprender na prática, notícias para acompanhar as principais tendências do mercado e o Alura Labs, com análises e reflexões de especialistas sobre tecnologia, IA e carreira.

    Conteúdos gratuitos

    • Artigos
    • Notícias
    • Alura Labs
  • Para Empresas
Ver planos
Links principais
  • Planos e Promoções
  • Links complementares do menu mobile
  • Talent lab
  • Inteligência Artificial
  • Pós Graduações
  • Para Empresas
  • Sobre a Alura
  • Grupo Alun
  • Entrar
    • Home
    • Carreiras
    • Skills & Go
    • Talent Lab
    • Inteligência Artificial
    • Pós Graduações
    • Artigos
    • Sobre a Alura
    • Grupo Alun
    LoginContato
    • LinkedIn
    • Instagram
    • YouTube
    1. Página inicial
    2. Back-end
    3. Persistência com Kotlin utilizando JDBC

    Persistência com Kotlin utilizando JDBC

    11 min11 minutos de leitura

    11 min11 minutos de leitura

    Publicado: 13/04/2021

    1. Projeto de exemplo
    2. Adicionando o conector do banco de dados MySQL
    3. Criando a conexão
    4. Criando tabelas
    5. Inserindo contas
    6. Buscando contas
    7. Um dos problemas com o JDBC
    8. Conclusão
    9. Projeto final

    Neste artigo, vamos aprender como persistir dados com o Kotlin utilizando o JDBC (Java Database Connectivity ou Conectividade com banco de dados Java).

    Projeto de exemplo

    Como exemplo vou utilizar o Bytebank, um projeto Gradle que simula um banco digital, para cadastrar contas. O cadastro da conta exige número de conta, nome do cliente e saldo:

    data class Conta(
        val numero: Int,
        val cliente: String,
        val saldo: Double
    )
    

    Na classe Conta representamos a nossa conta que pode ser criada da seguinte forma:

    fun main() {
    println("bem-vindo ao Bytebank")
        val contaAlex = Conta(1, "Alex", 1000.0)
    println("informações da conta $contaAlex")
    }
    

    E chegamos a este resultado ao executar o programa:

    bem-vindo ao Bytebank
    informações da conta Conta(numero=1, cliente=Alex, saldo=1000.0)
    

    Se quiser acompanhar os exemplos do artigo, você pode baixar o projeto inicial do Bytebank. Ele foi desenvolvido com o JDK 13, portanto, utilize a mesma versão para evitar incompatibilidades.

    Com a introdução do projeto e a criação de conta, vamos começar com a configuração do JDBC.

    Banner do Guia Tático Alura sobre carreira em tecnologia, destacando o mapa da carreira tech. A imagem convida a explorar diferentes caminhos profissionais, comparar possibilidades e encontrar a próxima fase da carreira na área de tecnologia, com chamada “Explore o mapa”.

    Adicionando o conector do banco de dados MySQL

    Como primeiro passo, precisamos criar uma conexão entre o nosso aplicativo e o banco de dados. Neste exemplo, vou utilizar o MySQL, mas é possível realizar essa mesma conexão utilizando outros bancos de dados comuns no mercado, pois cada um deles oferece um conector capaz de realizar a comunicação. O MySQL, por exemplo, tem uma página exclusiva com todos os drivers disponíveis, até mesmo de outras aplicações.

    Na página do MySQL temos a opção de fazer o download do conector, porém, considerando o uso de uma build tool (o Gradle), podemos adicionar a dependência no arquivo de build, o build.gradle.kts:

    dependencies{
    		implementation(kotlin("stdlib"))
    		implementation("mysql:mysql-connector-java:8.0.15")
    		testImplementation("junit", "junit", "4.12")
    }
    

    No projeto inicial a dependência está comentada. Remova o comentário e sincronize o projeto.

    Em seguida, basta apenas sincronizar o projeto para que o Gradle faça o download e disponibilize o uso do driver. Então, podemos começar a configurar a conexão.

    Criando a conexão

    Com o driver acessível, podemos criar a conexão com o MySQL da seguinte maneira:

    try {
        Class.forName("com.mysql.cj.jdbc.Driver")
        DriverManager.getConnection("jdbc:mysql://localhost/bytebank", "root", "")
        println("Conexão realizada com sucesso")
    } catch (e: Exception) {
        e.printStackTrace()
        println("não foi possível conectar com o banco")
    }
    

    Temos bastante código aqui! Não se assuste, pois vamos entender o que cada linha de código significa:

    • Class.forName(): configura o conector que vamos utilizar na conexão com o JDBC. Se você estivesse com outro driver, teria de colocar a classe correspondente ao driver que está utilizando, que nesse caso é o do MySQL ("com.mysql.cj.jdbc.Driver").
    • DriverManager.getConnection(): tenta fazer a conexão com o banco de dados por meio do JDBC, como argumento recebe o endereço de conexão, usuário e senha.

    Nesta chamada precisamos nos atentar principalmente ao endereço! Por exemplo, temos o padrão jdbc:mysql, que indica que vamos fazer uma conexão com o JDBC no banco de dados MySQL, ou seja, se você estiver fazendo a configuração para um outro banco de dados, o valor será diferente!

    Observações: um outro ponto a se notar é que estou utilizando um banco de dados no meu computador, na porta 3306 (porta padrão do MySQL), por isso o localhost é o suficiente. Porém, em uma integração com um banco de dados externo, o endereço será diferente! Note também que indicamos o banco de dados que queremos acessar e, nesse caso, criei o banco bytebank. Fique à vontade para usar esse mesmo exemplo ou utilize outro de sua preferência.

    Então, como segundo e terceiro argumento, precisamos enviar o usuário e a senha. Durante esse teste, vou utilizar o usuário root com uma senha vazia.

    "Beleza! Entendi a configuração do conector e como criamos uma conexão, mas por que utilizamos um try catch?"

    O try catch é necessário para que a nossa aplicação consiga identificar os problemas comuns durante a tentativa de conexão, por exemplo, um endereço inválido, uma falha na autenticação ou qualquer outro problema. Este é o motivo de apresentar a stack trace da exception e uma mensagem abaixo indicando que não foi possível conectar com o banco de dados.

    Após a introdução de cada linha de código, ao executar o programa, temos o seguinte resultado:

    bem-vindo ao Bytebank
    informações da conta Conta(numero=1, cliente=Alex, saldo=1000.0)
    Conexão realizada com sucesso
    

    Pronto! Podemos começar a executar instruções com o MySQL.

    Criando tabelas

    Entre as possibilidades, a nossa primeira instrução com o MySQL será a criação da tabela que vai armazenar as informações das contas! Para isso vamos considerar a seguinte instrução SQL:

    val sql = """
          CREATE TABLE contas (
              id INT PRIMARY KEY AUTO_INCREMENT,
              cliente VARCHAR(255),
              saldo DOUBLE
              );
          """.trimIndent()
    

    Para criar a query, precisamos envolver toda a instrução em uma String (podemos utilizar string literal ou raw string). Então, precisamos preparar a nossa query a partir do método prepareStatement() da conexão e executá-la com o execute():

    try {
        Class.forName("com.mysql.cj.jdbc.Driver")
        val conexao = DriverManager.getConnection("jdbc:mysql://localhost/bytebank", "root", "")
    println("Conexão realizada com sucesso")
        val sql = """
            CREATE TABLE contas (
                id INT PRIMARY KEY AUTO_INCREMENT,
                cliente VARCHAR(255),
                saldo DOUBLE
                );
            """.trimIndent()
        val query = conexao.prepareStatement(sql)
        query.execute()
    println("Tabela de contas criada")
    } catch (e: Exception) {
        e.printStackTrace()
    println("não foi possível conectar com o banco")
    }
    

    Ao executar o programa, temos o seguinte resultado no console:

    bem-vindo ao Bytebank
    informações da conta Conta(numero=1, cliente=Alex, saldo=1000.0)
    Conexão realizada com sucesso
    Tabela de contas criada
    

    Uma mensagem de sucesso! Ao verificar o banco de dados a partir da instrução DESC contas:

    mysql> DESC contas;
    +---------+--------------+------+-----+---------+----------------+
    | Field   | Type         | Null | Key | Default | Extra          |
    +---------+--------------+------+-----+---------+----------------+
    | id      | int          | NO   | PRI | NULL    | auto_increment |
    | cliente | varchar(255) | YES  |     | NULL    |                |
    | saldo   | double       | YES  |     | NULL    |                |
    +---------+--------------+------+-----+---------+----------------+
    3 rows in set (0.01 sec)
    

    Temos a nossa tabela! Agora podemos inserir contas no banco de dados!

    Inserindo contas

    Para inserir uma conta na tabela de contas, a princípio, realizamos passos similares ao que fizemos para criar a tabela, declaramos e preparamos a query e depois executamos:

    val insereContaSql = "INSERT INTO contas (cliente, saldo) VALUES (?, ?);"
    val queryInsereConta = conexao.prepareStatement(insereContaSql)
    queryInsereConta.execute()
    println("conta registrada: $contaAlex")
    

    A grande diferença é que precisamos realizar o processo de binding para vincular os dados do nosso objeto com a query. Para isso utilizamos os setters do PrepareStatement:

    val insereContaSql = "INSERT INTO contas (cliente, saldo) VALUES (?, ?);"
    val queryInsereConta = conexao.prepareStatement(insereContaSql)
    queryInsereConta.setString(1, contaAlex.cliente)
    queryInsereConta.setDouble(2, contaAlex.saldo)
    queryInsereConta.execute()
    println("conta registrada: $contaAlex")
    

    "Mas por que não concatenamos direto as informações do objeto na instrução SQL?"

    É bem comum surgir esse tipo de dúvida ao ver essa solução quando utilizamos a técnica de vínculo de dados, para evitar problemas de segurança, como o SQL Injection. Note que nessa técnica utilizamos o valor 1 para o setString(), que recebe o cliente como argumento, e o valor 2 para o setDouble(), que recebe o saldo.

    Isso significa que o valor 1 representa a primeira coluna (cliente) e o 2 a segunda coluna (saldo), em casos de mais colunas, basta adicionar os demais números sucessivamente, como 3, 4...

    Após realizar o processo de binding, podemos executar o programa, porém, é importante comentar ou remover o código de criação de tabela, pois se não temos a seguinte exception:

    bem-vindo ao Bytebank
    informações da conta Conta(numero=1, cliente=Flex, saldo=2000.0)
    Conexão realizada com sucesso
    java.sql.SQLSyntaxErrorException: Table 'contas' already exists
    	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120)
    	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
    	at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
    	at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:970)
    	at com.mysql.cj.jdbc.ClientPreparedStatement.execute(ClientPreparedStatement.java:387)
    	at br.com.alura.bytebank.MainKt.main(Main.kt:25)
    	at br.com.alura.bytebank.MainKt.main(Main.kt)
    não foi possível conectar com o banco
    

    Note que é a java.sql.SQLSyntaxErrorException indicando que a tabela contas já foi criada… Podemos utilizar algumas técnicas para evitar o problema, por exemplo, usar um if na instrução de criação de tabela:

    val sql = """
          CREATE TABLE NOT IF EXISTS contas (
              id INT PRIMARY KEY AUTO_INCREMENT,
              cliente VARCHAR(255),
              saldo DOUBLE
              );
          """.trimIndent() 
    

    Ao testar o programa novamente, a nossa conta é inserida na tabela:

    bem-vindo ao Bytebank
    informações da conta Conta(numero=1, cliente=Alex, saldo=1000.0)
    Conexão realizada com sucesso
    conta registrada: Conta(numero=1, cliente=Alex, saldo=1000.0)
    

    Podemos até mesmo conferir o resultado direto no MySQL:

    mysql> SELECT * FROM contas;
    +----+---------+-------+
    | id | cliente | saldo |
    +----+---------+-------+
    |  1 | Alex    |  1000 |
    +----+---------+-------+
    1 row in set (0.00 sec)
    

    Agora que aprendemos a salvar contas, podemos começar a implementação da busca de contas.

    Buscando contas

    Para buscar as contas, realizamos o mesmo procedimento, mas a diferença é que agora utilizamos o executeQuery() que devolve um ResultSet, que representa uma tabela do banco de dados de acordo com a query executada.

    val buscaContas = "SELECT * FROM contas;"
    val buscaContasQuery = conexao.prepareStatement(buscaContas)
    val resultado = buscaContasQuery.executeQuery()
    

    Nessa query, especificamente, temos acesso a todas as contas cadastradas!

    Para que seja possível pegar cada conta, precisamos fazer uma iteração em cada linha do ResultSet, podemos fazer essa iteração com o método next() que vai para a próxima linha do ResultSet e devolve true, se existirem dados, ou false, se não existirem:

    val buscaContas = "SELECT * FROM contas;"
    val buscaContasQuery = conexao.prepareStatement(buscaContas)
    val resultado = buscaContasQuery.executeQuery()
    while (resultado.next()){
        val numero = resultado.getInt(1)
        val cliente = resultado.getString(2)
        val saldo = resultado.getDouble(3)
        val conta = Conta(numero, cliente, saldo)
    		println("conta devolvida $conta")
    }
    

    Dessa forma, para cada linha, podemos pegar o valor das colunas a partir dos getters, por exemplo, na primeira coluna que representa o id do tipo Int, utilizamos o getInt() com o argumento 1 indicando ser a primeira coluna, na segunda utilizamos o getString() com o argumento 2 para pegar a segunda coluna que é o cliente e assim sucessivamente…

    Antes de executar o programa, podemos até mesmo salvar uma nova conta para o resultado apresentar mais de uma conta:

    bem-vindo ao Bytebank
    informações da conta Conta(numero=1, cliente=Fran, saldo=2000.0)
    Conexão realizada com sucesso
    conta devolvida Conta(numero=1, cliente=Alex, saldo=1000.0)
    conta devolvida Conta(numero=2, cliente=Fran, saldo=2000.0)
    

    Note que mesmo com o número de conta 1, na conta da Fran foi registrado com o valor 2. Isso acontece por não enviar o número da conta no processo de binding e por manter a configuração de incremento automático na tabela.

    Um dos problemas com o JDBC

    O grande detalhe desta solução é que precisamos saber exatamente o tipo de valor que desejamos pegar para cada coluna, pois se fizermos um getInt() e o valor da coluna for um texto (string), temos uma exception na conversão:

    java.lang.NumberFormatException: For input string: "Alex"
    	at java.base/jdk.internal.math.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2054)
    	at java.base/jdk.internal.math.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
    	at java.base/java.lang.Double.parseDouble(Double.java:549)
    	at com.mysql.cj.protocol.a.MysqlTextValueDecoder.decodeDouble(MysqlTextValueDecoder.java:228)
    	at com.mysql.cj.result.StringConverter.createFromBytes(StringConverter.java:114)
    	at com.mysql.cj.protocol.a.MysqlTextValueDecoder.decodeByteArray(MysqlTextValueDecoder.java:238)
    	at com.mysql.cj.protocol.result.AbstractResultsetRow.decodeAndCreateReturnValue(AbstractResultsetRow.java:143)
    	at com.mysql.cj.protocol.result.AbstractResultsetRow.getValueFromBytes(AbstractResultsetRow.java:250)
    	at com.mysql.cj.protocol.a.result.ByteArrayRow.getValue(ByteArrayRow.java:91)
    	at com.mysql.cj.jdbc.result.ResultSetImpl.getNonStringValueFromRow(ResultSetImpl.java:656)
    	at com.mysql.cj.jdbc.result.ResultSetImpl.getInt(ResultSetImpl.java:896)
    	at br.com.alura.bytebank.MainKt.main(Main.kt:43)
    	at br.com.alura.bytebank.MainKt.main(Main.kt)
    

    Você pode fazer essa simulação ao tentar pegar a coluna de cliente como se fosse um inteiro val teste = resultado.getInt(2).

    Este é um dos detalhes/problemas do JDBC. Note que ele mostra a exception NumberFormatException indicando a entrada em string com o valor Alex.

    Conclusão

    Conforme apresentado neste artigo, podemos utilizar as mesmas soluções em Java usando o Kotlin. Se você já teve contato com o JDBC, provavelmente não deve ter notado tanta diferença com a implementação em Java, pois com o Kotlin podemos explorar todo o conceito de interoperabilidade com o Java, o que permite utilizar as bibliotecas em Java no Kotlin! Isso significa que você também pode ir além e até mesmo utilizar a JPA com o Hibernate, por exemplo.

    Projeto final

    Você pode acessar o código do projeto final a partir deste repositório do GitHub. A grande diferença é que os comportamentos foram extraídos para funções, indicando as ações de criação de tabela, inserção e busca de contas.

    Caso seja o seu primeiro contato com o JDBC e você tenha interesse em aprender mais sobre essa biblioteca, aqui na Alura temos o curso de JDBC em Java, que além de apresentar uma introdução, também explica boas práticas, como DAO, connection pool, Data Sources e outros recursos importantes!

    Banner do Guia Tático Alura sobre carreira em tecnologia, destacando o mapa da carreira tech. A imagem convida a explorar diferentes caminhos profissionais, comparar possibilidades e encontrar a próxima fase da carreira na área de tecnologia, com chamada “Explore o mapa”.

    Avalie este artigo

    • Foto de Alex Felipe

      Autor(a)

      Alex Felipe

      Alex é instrutor e desenvolvedor e possui experiência em Java, Kotlin, Android. Atualmente cria conteúdo no canal https://www.youtube.com/@AlexFelipeDev.

    Explore por tópico

    • Back-end
    • Dados
    • DevOps
    • Front-end
    • Gestão & Negócios
    • Institucionais
    • Inteligência Artificial
    • Mobile
    • UX & Design

    Leia também

    • Alura
      16/08/2016

      Boas práticas de desenvolvimento PHP

      Ler mais
    • 14/06/2016

      Métodos de requisição do HTTP

      Ler mais
    • 11/12/2022

      O que são Cookies na Internet e como eles funcionam?

      Ler mais
    Ver mais conteúdos

    Inscreva-se em nossa Newsletter

    Fique por dentro de conteúdos, insights e oportunidades do universo tech. Receba novidades e lançamentos direto no seu e-mail.

    Institucional

    • Sobre nós
    • Trabalhe Conosco
    • Para Empresas
    • Para Escolas
    • Política de Privacidade
    • Compromisso de Integridade
    • Termos de Uso
    • Canal de Ética
    • Código de Ética
    • Fale Conosco
    • Documentos Institucionais
    • Status
    Institucional
    • Sobre nós
    • Trabalhe Conosco
    • Para Empresas
    • Para Escolas
    • Política de Privacidade
    • Compromisso de Integridade
    • Termos de Uso
    • Canal de Ética
    • Código de Ética
    • Fale Conosco
    • Documentos Institucionais
    • Status

    A Alura

    • Como Funciona
    • Inteligência Artificial
    • Plataforma
    • Depoimentos
    • Instrutores(as)
    • Dev em <T>
    • Luri, a Inteligência Artificial da Alura
    • IA Conference
    • Cursos Imersivos
    • Perguntas Frequentes
    A Alura
    • Como Funciona
    • Inteligência Artificial
    • Plataforma
    • Depoimentos
    • Instrutores(as)
    • Dev em <T>
    • Luri, a Inteligência Artificial da Alura
    • IA Conference
    • Cursos Imersivos
    • Perguntas Frequentes

    Conteúdos

    • Alura Cases
    • Imersão Engenharia de Software: Dev na Era da IA
    • Artigos
    • Podcasts
    • Artigos de educação corporativa
    Conteúdos
    • Alura Cases
    • Imersão Engenharia de Software: Dev na Era da IA
    • Artigos
    • Podcasts
    • Artigos de educação corporativa
    Uma Empresa do GrupoLogo Grupo Alun

    Outras empresas do Grupo Alun

    • FIAP
    • STARTSE
    • PM3
    • LUMINA

    Ao submeter seu e-mail, você concorda com a política de privacidade da Alura.

    Redes Sociais & Apps

    instagram
    youtube
    tiktok
    x
    appStore
    googlePlay
    Uma Empresa do GrupoLogo Grupo Alun

    Outras empresas do Grupo Alun

    • FIAP
    • STARTSE
    • PM3
    • LUMINA

    Ao submeter seu e-mail, você concorda com a política de privacidade da Alura.

    Redes Sociais & Apps

    instagram
    youtube
    tiktok
    x
    appStore
    googlePlay
    Alura