我该如何在Java中手动配置DataSource?

53

我正在尝试按照Sun的JDBC教程http://java.sun.com/docs/books/tutorial/jdbc/basics/connecting.html进行学习。

它提供了以下示例代码:

DataSource ds = (DataSource) org.apache.derby.jdbc.ClientDataSource()
ds.setPort(1527);
ds.setHost("localhost");
ds.setUser("APP")
ds.setPassword("APP");

Connection con = ds.getConnection();
这段代码无法编译,因为除了最后调用的getConnection()方法之外,DataSource接口没有这些方法。
(这里是Java文档:http://java.sun.com/javase/6/docs/api/javax/sql/DataSource.html
我错过了什么吗?
编辑: 实际上我正在尝试连接到MySQL(com.mysql.jdbc), 但我找不到相关的javadoc。 我会接受一个指向以下内容的答案:
1)对于我能理解的DataSourcecom.mysql.jdbc文档,或者
2)给出一个示例,作为教程代码的替代方案,可以适用于任何数据库。

以下是一些例子:http://www.tugay.biz/2016/09/hikaricp-hello-world.html http://www.tugay.biz/2016/09/bonecp-hello-world.html http://www.tugay.biz/2016/07/tomcat-connection-pool-vs-apache.html - Koray Tugay
7个回答

130

你可能需要查看Commons DBCP项目。它提供了一个BasicDataSource,其配置方式与您的示例非常相似。要使用它,您需要将数据库供应商的JDBC JAR文件加入到类路径中,并正确指定供应商的驱动程序类名和数据库URL格式。

编辑:

如果您想为MySQL配置BasicDataSource,您可以像这样操作:

BasicDataSource dataSource = new BasicDataSource();

dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUsername("username");
dataSource.setPassword("password");
dataSource.setUrl("jdbc:mysql://<host>:<port>/<database>");
dataSource.setMaxActive(10);
dataSource.setMaxIdle(5);
dataSource.setInitialSize(5);
dataSource.setValidationQuery("SELECT 1");

需要DataSource的代码可以使用它。


25

在JDBC中,大多数这些属性并不像API那样可以配置,而是取决于实现方式。 JDBC处理这个问题的方式是允许每个供应商使用不同的连接URL。

所以你要做的是注册驱动程序,以便JDBC系统知道如何处理URL:

 DriverManager.registerDriver((Driver) Class.forName("com.mysql.jdbc.Driver").newInstance());

然后你形成URL:

 String url = "jdbc:mysql://[host][,failoverhost...][:port]/[database][?propertyName1][=propertyValue1][&propertyName2][=propertyValue2]"

最后,使用它来获取一个连接:

 Connection c = DriverManager.getConnection(url);

在更复杂的JDBC中,您将涉及连接池等问题,应用程序服务器通常有自己的注册驱动程序到JNDI中的方法,并从那里查找一个DataSource,然后调用它的getConnection。

关于MySQL支持哪些属性,请参见此处

编辑:还有一个想法,技术上只需要一行代码Class.forName("com.mysql.jdbc.Driver")就足够了,因为该类应该有自己的静态初始化程序来注册版本,但有时JDBC驱动程序没有这样做,所以如果您不确定,注册第二个驱动程序并没有什么害处,它只是在内存中创建了一个重复的对象。


好的,这可以使用。虽然教程说首选是DataSource,但我还是可以接受。 - Eric Wilson
13
DataSource 实际上是为应用服务器和其他提供 JNDI 服务的容器而设计的。如果没有 JNDI 服务,它们就没有太多意义,而且这个教程在这一点上写得并不好。 - Yishai
你可以创建自己的类来实现DataSource接口,使用上面的代码来实现getConnection方法。除此之外,你只需要实现loginTimeout和LogWriter的getter和setter方法。 - GregA100k
@Yishai: 感谢您的澄清。而且,总体来说,这个教程不符合Sun的通常标准。 - Eric Wilson
数据源的一个重要优点是能够依赖于连接池。 - Rytek
@Rytek 嗯,你可以使用 DriverManager 从池中获取连接,而不是仅仅打开它们(那么 DriverManager 从哪里获取实际的新连接呢?嗯,从它包装的“真正” DriverManager 中获取)。一个例子是 org.apache.commons.dbcp2.PoolingDriver - David Tonhofer

25

DataSource是供应商特定的,在MySQL中,您可以使用提供在MySQL Java连接器jar中的MysqlDataSource:

    MysqlDataSource dataSource = new MysqlDataSource();
    dataSource.setDatabaseName("xyz");
    dataSource.setUser("xyz");
    dataSource.setPassword("xyz");
    dataSource.setServerName("xyz.yourdomain.com");

MysqlDataSource不在MySQL连接器6和8中,因此BasicDataSource更好。 - Xdg
@Xdg那不正确。它已经移动,但它还在那里。 - user207421
数据源不一定必须是特定于某个供应商的,事实上最好使用一个通用的数据源,比如 Spring 的 DriverManagerDataSource、DPCP 或者更好的 HikariCP。 - rustyx

9

以MYSQL为例: 1)使用数据库连接池:例如Apache Commons DBCP,同时需要在类路径中添加basicDataSource jar包。

@Bean
public BasicDataSource dataSource() {
    BasicDataSource ds = new BasicDataSource();
    ds.setDriverClassName("com.mysql.jdbc.Driver");
    ds.setUrl("jdbc:mysql://localhost:3306/gene");
    ds.setUsername("root");
    ds.setPassword("root");
    return ds;
}

2) 使用基于JDBC的驱动程序,通常用于不考虑连接池的情况:

@Bean
public DataSource dataSource(){
    DriverManagerDataSource ds = new DriverManagerDataSource();
    ds.setDriverClassName("com.mysql.jdbc.Driver");
    ds.setUrl("jdbc:mysql://localhost:3306/gene");
    ds.setUsername("root");
    ds.setPassword("root");
    return ds;
}

2

我认为这个例子是错误的 - javax.sql.DataSource 也没有这些属性。你的 DataSource 需要是类型为 org.apache.derby.jdbc.ClientDataSource 的,这个类应该有那些属性。


1

您所参考的DataSource javadoc属于错误的包。您应该查看javax.sql.DataSource。正如您所见,这是一个接口。主机和端口名称配置取决于实现,即您正在使用的JDBC驱动程序。

我还没有检查过Derby javadocs,但我认为代码应该像这样编译:

ClientDataSource ds = org.apache.derby.jdbc.ClientDataSource()
ds.setHost etc....

0

对于Postgres,以下内容有效。我实际上在集成测试中使用过它。我想在生产环境中应该考虑更多的因素。

PGSimpleDataSource ds = new PGSimpleDataSource() ;  
ds.setServerName( "localhost" );  
ds.setDatabaseName( "your_db_name_here" );   
ds.setUser( "scott" );       
ds.setPassword( "tiger" );   

这个类被捆绑在Postgres JDBC驱动程序中。

我遵循的原始stackoverflow帖子:https://dev59.com/G1cO5IYBdhLWcg3w5lbX#45091982


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接