[Resolvido]qual diferença Class.forname e DriverManager

qual diferença de carregar um driver com class ou driver manger

[code]
//Class.forName(“org.gjt.mm.mysql.Driver”);

        DriverManager.registerDriver(new OracleDriver());[/code]

qualquer um dos 2 funciona mais gostaria de saber a respeito da diferença performce etc…

A maior diferença é a independência da classe do driver para que o código compile. Desta forma você pode externalizar essa classe para configurar o driver, algo como:

[code]//inicialização
Properties properties = new Properties();
InputStream is = getClass().getResourceAsStream(“db-config.properties”);
properties.load(is);
is.close();

//configuração

Class.forName(properties.getProperty(“driver.class”));[/code]

Em termos de desempenho eu creio que você não precise se preocupar pois a diferença é desprezível nesse contexto (já que registrar um driver de banco não é algo que deva ser feito milhares de vezes em uma aplicação).

sim mais ainda não entendi a diferença… tipo o driver manager encapsula o class.forname algo assim?

Não, é ao contrário, o Class.forName encapsula o DriverManager.registerDriver.

Veja por exemplo este código, que é do driver do MySql (classe com.mysql.jdbc.Driver)

static { try { java.sql.DriverManager.registerDriver(new Driver()); } catch (SQLException E) { throw new RuntimeException("Can't register driver!"); } }
Obs: Estou assumindo que você sabe bem o que faz o Class.forName, e por que ele faz o código acima ser executado, mas se tiver dúvidas sobre isso não precisa se acanhar, pergunte :slight_smile:

tenho noção sim mais se quiser explicar melhor eu aceito.

obrigado

Então, o que acontece é o seguinte:
Esses são jeitos de obter uma instância do objeto Class, aquele que descreve a classe (é usado em Reflection):

Class clazz = Class.forName("NomeDaClasse"); Class clazz = NomeDaClasse.class; Class clazz = new NomeDaClasse().getClass();
Acontece que no dia-a-dia ninguém usa Class.forName() para obter o descritor da classe (Isso é feito por frameworks, ou pela IDE). Ele virou praticamente um “comando para carregar drivers JDBC”, e algumas pessoas acabam não se perguntando o porquê.

O motivo dele funcionar é que para poder te retornar o objeto Class, a JVM precisa carregar a classe primeiro (CASO O PROGRAMA NÃO A TENHA UTILIZADO AINDA).
As classes de driver JDBC, ao serem carregadas, se registram no DriverManager (é uma espécie de contrato que os desenvolvedores de drivers precisam seguir). Isso é feito em um bloco static {} , aquele do código que eu coloquei na outra resposta.

Conclusão: usamos o Class.forName() apenas para nos certificar que naquele ponto a classe do driver foi carregada. Qualquer referência que você fizer a esta classe terá o mesmo efeito, pois a JVM deve carregá-la na primeira utilização.

Por exemplo, estas também são maneiras de carregar o driver do MySQL:

Class clazz = com.mysql.jdbc.Driver.class; // Obtendo o objeto Class Driver driver = new com.mysql.jdbc.Driver(); // Criando uma instancia String s = com.mysql.jdbc.Driver.DBNAME_PROPERTY_KEY; // Pegando um atributo estatico qualquer, só para fazer referencia à classe. // E milhares de outros jeitos :-)
Como um exercício, você pode pensar sobre porque o Class.forName() é melhor do que essas maneiras - tem uma dica em uma das respostas deste tópico…

E finalmente, voltando à sua pergunta original sobre o DriverManager.registerDriver(): não faça dessa maneira, pois o método registerDriver() não é feito para nós e sim para os desenvolvedores de Driver, eles é que tem que se registrar no carregamento da classe (veja aqui) Se você chamar manualmente o driver pode ser registrado em duplicidade.

vlw pela atenção mais se é so para carregar a classe… por que mesmo se eu colocar o jar do driver no jre/ext/lib eu ainda tenho que registrar o driver isso não deveria ser automatico sendo que blocos staticos rodao quando jvm carrega a classe que por sua ves esta no classpath…

obrigado.

[quote=Diabo Loiro]vlw pela atenção mais se é so para carregar a classe… por que mesmo se eu colocar o jar do driver no jre/ext/lib eu ainda tenho que registrar o driver isso não deveria ser automatico sendo que blocos staticos rodao quando jvm carrega a classe que por sua ves esta no classpath…

obrigado.[/quote]
Só que infelizmente* a JVM não carrega todas as classes do CLASSPATH no início da aplicação. Cada vez que uma classe é usada pela primeira vez, o classloader procura no classpath e só então a carrega (e consequentemente executa os blocos estáticos).
Por isso esse truque de forçar uma referência à classe do driver antes de abrir conexão com o BD. Se for a primeira vez que a classe é referenciada, ela vai ser carregada e executa o static. Se já estiver carregada, beleza, nada acontece.

  • Eu coloquei infelizmente, mas na verdade é felizmente :slight_smile: Se fosse tudo carregado logo de cara teríamos pelo menos dois efeitos indesejados: (1) demoraria bem mais para iniciar a aplicação e (2) Carregaria um montão de classes desnecessárias.

vlw cara mais entao qual seria o problema dele carregar no primeiro acesso? alem de uma pequena lentidão.