Jdbi: Guia do desenvolvedor: migração de v2 para v3

Criado em 25 jan. 2017  ·  15Comentários  ·  Fonte: jdbi/jdbi

doc

Comentários muito úteis

Observações da migração de um pequeno projeto:

Classes renomeadas (não tão simples quanto excluir importações e deixar o IDE corrigi-las):

  • DBI -> Jdbi
  • IDBI -> Jdbi
  • DBIException -> JdbiException

Os construtores para Jdbi foram substituídos por um método de fábrica create() .

ResultSetMapper é substituído por RowMapper e o método map não tem mais o índice de linha. Uma classe chamada ResultSetMapper existe no Jdbi 3, mas serve a um propósito diferente. @Mapper é substituído por @UseRowMapper . registerMapper() em Jdbi é substituído por registerRowMapper() .

@BindIn é substituído por @BindList e não requer mais StringTemplate.

Com o modelo Jdbi padrão, os colchetes angulares não são citados, o que significa que o IntelliJ entende a sintaxe depois que você configura o Parameter Pattern em Tools -> Database -> User Patterns .

Query não tem mais um tipo padrão de Map e, portanto, list() não pode ser chamado diretamente. Ligue mapToMap() antes de ligar para list() .

TransactionStatus não existe mais.

TransactionConsumer.useTransaction() leva apenas Handle agora, então o argumento TransactionStatus precisa ser removido ao usar isso com os métodos useTransaction() em Jdbi ou Handle .

TransactionCallback.inTransaction() só aceita Handle agora, então o argumento TransactionStatus precisa ser removido ao usar isso com os métodos inTransaction() em Jdbi ou Handle .

CallbackFailedException não existe mais. As várias interfaces funcionais, como HandleConsumer , HandleCallback , TransactionalConsumer e TransactionalCallback , agora podem lançar qualquer tipo de exceção (mas restritas usando genéricos para evitar verificação desnecessária manipulação de exceção).

O suporte a objetos SQL não está mais disponível por padrão. Ele deve ser registrado a cada instância Jdbi criada.

O Migrate Refactor do IntelliJ foi útil para iniciar a migração.

Todos 15 comentários

Observações da migração de um pequeno projeto:

Classes renomeadas (não tão simples quanto excluir importações e deixar o IDE corrigi-las):

  • DBI -> Jdbi
  • IDBI -> Jdbi
  • DBIException -> JdbiException

Os construtores para Jdbi foram substituídos por um método de fábrica create() .

ResultSetMapper é substituído por RowMapper e o método map não tem mais o índice de linha. Uma classe chamada ResultSetMapper existe no Jdbi 3, mas serve a um propósito diferente. @Mapper é substituído por @UseRowMapper . registerMapper() em Jdbi é substituído por registerRowMapper() .

@BindIn é substituído por @BindList e não requer mais StringTemplate.

Com o modelo Jdbi padrão, os colchetes angulares não são citados, o que significa que o IntelliJ entende a sintaxe depois que você configura o Parameter Pattern em Tools -> Database -> User Patterns .

Query não tem mais um tipo padrão de Map e, portanto, list() não pode ser chamado diretamente. Ligue mapToMap() antes de ligar para list() .

TransactionStatus não existe mais.

TransactionConsumer.useTransaction() leva apenas Handle agora, então o argumento TransactionStatus precisa ser removido ao usar isso com os métodos useTransaction() em Jdbi ou Handle .

TransactionCallback.inTransaction() só aceita Handle agora, então o argumento TransactionStatus precisa ser removido ao usar isso com os métodos inTransaction() em Jdbi ou Handle .

CallbackFailedException não existe mais. As várias interfaces funcionais, como HandleConsumer , HandleCallback , TransactionalConsumer e TransactionalCallback , agora podem lançar qualquer tipo de exceção (mas restritas usando genéricos para evitar verificação desnecessária manipulação de exceção).

O suporte a objetos SQL não está mais disponível por padrão. Ele deve ser registrado a cada instância Jdbi criada.

O Migrate Refactor do IntelliJ foi útil para iniciar a migração.

Obrigado @electrum por montar isso! Esta será uma grande ajuda

Algumas notas adicionais da revisão da minha apresentação:

  • Artefatos renomeados org.jdbi:jdbi -> org. jdbi:jdbi3 , :jdbi3-sqlobject, :jdbi3-guava, etc
  • Pacote principal alterado: org.skife.jdbi.v2 -> org.jdbi.v3. Isso significa que v2 e v3 podem coexistir em um projeto enquanto você migra
  • Renomeado: GetHandle -> SqlObject
  • O argumento v3 e as fábricas de mapeadores usam java.lang.reflect.Type , enquanto a v2 usa java.lang.Class . Isso significa que a v3 é capaz de lidar com assinaturas de tipo genérico complexas que a v2 não conseguia.
  • v3 argumento e fábricas de mapeadores e interfaces funcionais de método único que retornam um opcional. v2 tinha métodos accepts() e build() separados.
  • Os tipos de objetos SQL na v3 devem ser apenas interfaces públicas - sem classes. Os tipos de retorno de método também devem ser públicos. Isso ocorre devido à mudança de implementação do Objeto SQL de CGLIB para java.lang.reflect.Proxy, que suporta apenas interfaces.
  • As anotações @Bind nos parâmetros do método SQL Object podem se tornar opcionais, compilando seu código com o sinalizador -parameters habilitado.
  • Objetos SQL sob demanda não funcionam bem com métodos que retornam Iterables. Objetos sob demanda fecham estritamente a alça após cada chamada de método e não mais "mantêm a porta aberta" para você terminar de consumir o iterável como faziam na v2. Isso exclui uma fonte importante de vazamentos de conexão.
  • Os objetos SQL não podem mais ser fechados -- eles são sob demanda ou seu ciclo de vida está vinculado ao ciclo de vida do identificador ao qual foram anexados.
  • A interface StatementLocator foi removida do núcleo. Todas as instruções principais esperam receber o SQL real agora. Um conceito semelhante, SqlLocator foi adicionado, mas apenas no domínio dos Objetos SQL.

Outra: StatementRewriter foi refatorado em TemplateEngine e SqlParser .

Muito importante adicionar à lista é o comportamento do select. Partiu disso:

List<Map<String, Object>> rs = h.select("select id, name from something");

Para isso:

List<Map<String, Object>> rs = h.select("select id, name from something").mapToMap().list();

Eu gostaria que o poder extra, flexibilidade e segurança da v3 não viesse com o preço da verbosidade.

Oi @javajosh , não consideramos esse particular muito ruim porque estamos tentando desencorajar o mapeamento para objetos Map . Se nada mais, as regras sobre diferenciação de maiúsculas e minúsculas para as chaves são confusas. Existe algum motivo para você emitir um Map em vez de criar seu próprio tipo definido? Eu, pessoalmente, sempre escreverei pequenas classes de resultado (usando mapeadores e fichários construtor/campo/propriedade) e sempre evito usar Map . Você tem algum caso de uso em que é muito conveniente?

Oi @stevenschlansker - Estou chegando na perspectiva da "primeira experiência dos desenvolvedores". O código acima foi retirado do seu próprio tutorial v2, que eu acho admiravelmente minimalista. E, de fato, com uma linguagem hospedada em JVM como Groovy, que possui um mapa semelhante a javascript embutido, você provavelmente veria um resultado não digitado com mais frequência.

@javajosh o que você acha de https://github.com/jdbi/jdbi/pull/925 ?

@stevenschlansker Você quis dizer #928?

@stevenschlansker Definitivamente uma melhoria! Mas ainda é mais detalhado que a v2. :) Isso é além da maior verbosidade no maven, etc. Eu só não quero ver o JDBI seguir o caminho do JUnit, que lutou para que as pessoas adotassem a v4 porque tinha alguns recursos interessantes, mas era muito mais complicado do que v3 e v3 foi "bom o suficiente". Eu tenho esse mesmo sentimento sobre a sintaxe "withHandle" (embora eu entenda seu instinto de eliminar todas as alças pendentes).

@javajosh Você ainda tem Jdbi.open() se quiser maior controle, embora recomendemos que você o use dentro de um bloco try-with-resources por segurança.

Iniciando o trabalho nos documentos de migração de v2 para v3.

@javajosh Voltando ao método ResultBearing.list() que retorna um List<Map<String,Object>> : não tenho certeza se adicionar isso foi uma boa ideia, especialmente no final do ciclo de lançamento.

Tenho empatia com suas preocupações sobre a verbosidade, mas essa verbosidade serve ao propósito de esclarecer a intenção do desenvolvedor:

handle.createQuery(sql)
    .mapToMap()
    .list()

é mais claro para o leitor do que:

handle.createQuery(sql)
    .list()

É uma coisa delicada, e não invejo sua posição tendo que escolher. JDBI é uma boa biblioteca, e estou feliz por simplesmente ter registrado minhas preocupações sobre verbosidade; se faz sentido adicionar um método de conveniência neste caso específico, não tenho certeza e tenderia a confiar em seu julgamento sobre o meu, já que não estou seriamente envolvido no projeto! Obrigado por ouvir!

Por favor, deixe-nos saber se você encontrar um exemplo concreto de como é melhor com um nome mais curto ou uma demonstração de como podemos melhorá-lo 😄

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

goxr3plus picture goxr3plus  ·  4Comentários

agavrilov76 picture agavrilov76  ·  5Comentários

keith-miller picture keith-miller  ·  3Comentários

buremba picture buremba  ·  5Comentários

electrum picture electrum  ·  3Comentários