Vaadin和db连接池

时间:2013-08-10 11:21:41

标签: connection connection-pooling vaadin

我是Vaadin框架的新手,不确定如何继续进行数据库连接。

我不想要的是在每个会话中实现连接。在我的讲解中,vaadin在会话级别工作。

是否可以创建一个无论会话都会持久化的类,然后,vaadin会查询它以获取数据库连接?

3 个答案:

答案 0 :(得分:1)

Vaadin只是一种创建应用程序UI层的技术,它与jdbc连接无关 - 您的服务层应该负责业务逻辑实现,包括使用您的数据库。这是Web应用程序的典型分层。根据我对你的问题的理解,其中一个选择是使用Spring作为你的后端 - 它非常适合管理各种类型的数据源和相关的东西。

答案 1 :(得分:0)

您需要在应用程序服务器中使用jdbc连接池。

答案 2 :(得分:0)

使用Vaadin和获取数据库是正交的问题,彼此之间并不真正相关。

DataSource界面

通常最好为您的特定数据库定义一个DataSource对象。

H2 Database Engine及其DataSource implementation为例。

// Setup the data source.
JdbcDataSource ds = new JdbcDataSource();
ds.setURL("jdbc:h2:˜/test");
ds.setUser("sa");
ds.setPassword("sa");
return ds ; // Return as a `DataSource` object rather than concrete class.

研究您的特定JDBC driver,以查找其可能的DataSource的实现。例如,postgresql.org的JDBC driver for Postgres provides org.postgresql.ds.PGConnectionPoolDataSource(已池)和org.postgresql.ds.PGSimpleDataSource(未池)。

然后,当您需要与数据库对话时,向该对象请求数据库连接。完成该数据库操作后,关闭连接。

Connection conn = myDataSource.getConnection() ;

您可以简单地使用Java try-with-resources语法。

try (
    Connection conn = myDataSource.getConnection() ;
) 
{
    // Use `conn` object to work with database.
    // When going out of scope here, the connection's `close` method is automatically called.
}

有些人强烈建议使用connection pooling。除了补救已证明的问题外,我建议连接池。连接池很难正确地完成,有几个臭名昭著的失败项目,还有其他一些甚至不建议自己用于生产的项目。即使实施得当,连接池也总是会带来其他问题,例如连接在不良情况下返回到池中(例如事务悬而未决)。每次重新连接都是最安全的方法。有些人谴责获得新的数据库连接的费用。但是从我自己的经验或其他人通过正式测试客观呈现出来的证据中,我还没有看到这笔费用的证据。

尽管如此,如果您决定使用池,则您的DataSource实现可以在后台处理池。因此,本答案中讨论的代码和概念适用于池数据源对象和非池数据源对象。这就是DataSource界面的要点,以掩盖诸如池化池与非池化池之类的差异。参见Oracle Tutorial

ServletContext和“属性”

问题就变成了存储DataSource对象的位置。这是Vaadin进入照片的地方。

Vaadin基于Jakarta Servlet(以前称为Java Servlet)技术。实际上,Vaadin是一个很大的servlet。您的Vaadin网站在能够托管servlet的服务器上运行。该服务器必须支持Jakarta Servlet specification。该规范要求支持javax.servlet.ServletContext对象,该对象代表您整个正在运行的Web应用程序。一个“上下文”具有当前正在运行您的Web应用程序的零个,一个或多个“会话”对象,每个Web浏览器每个用户一个会话。

为我们的目的而变得有趣的地方是ServletContext为您可能希望保留的所有对象提供缓存,以供应用程序的所有会话(用户)使用。该缓存称为“属性”,是键-值集合,其中键为String。您可以使用DataSource之类的密钥将"javax.sql.DataSource"存储在此处。

那么如何访问代表我们的Web应用程序的ServletContext对象?有关说明和可能更好的方法,请参见this Question

ServletContext servletContext = 
        VaadinServletService            // com.vaadin.flow.server.VaadinServletService
        .getCurrentServletRequest()     // Returns a javax.servlet.http.HttpServletRequest
        .getServletContext()            // Returns a `javax.servlet.ServletContext`. 
;

现在,我们可以存储DataSource实现对象。我们可以使用任何String,只要它在键值集合中是不同的即可。提示:为您的密钥字符串添加自己的域名以确保唯一性。

servletContext.setAttribute( "com.example-javax.sql.DataSource" , dataSource ) ;

并通过需要访问数据库的任何代码进行检索。键值集合将值存储为Object,因此我们必须进行强制转换。

DataSource dataSource = (DataSource) servletContext.getAttribute( "com.example-javax.sql.DataSource" ) ;

提示:您可能应该测试NULL结果。

您的积分

  

我不想在每个会话中都建立连接。

否,您不希望在每个会话中都创建数据库连接,这不是正常情况。保持开放的数据库连接会占用客户端和服务器上的资源(内存,CPU,端口等)。

当需要进行数据库工作时,请向DataSource对象请求一个Connection。完成数据库操作后,调用Connection::close或让try-with-resources语法自动执行。

  

尽管如此,vaadin还是在会话级别起作用。

Vaadin只是Jakarta Servlet。 servlet只是将大部分HTTP和网络工作委托给Web容器(例如Tomcat或Jetty或Glassfish等)的Web应用。

尽管HTTP具有无状态请求-响应体系结构,但常见网络工作的一部分是创建有状态连接的幻觉。 Cookies或其他技巧可用于在多个请求之间跟踪单个用户。基于Servlet的Web容器代表我们作为Web应用程序程序员来处理此问题,创建对象以将每个用户作为“会话”进行跟踪。 Vaadin在这方面没有什么特别之处。

  

是否有可能创建一个无论会话都将持久化的类,然后vaadin会话将查询该类以获取数据库连接?

Vaadin和数据库连接是两个彼此不直接相关的主题。

我建议您再做一些研究,以使您对基本的Web技术有所了解,以了解HTTP请求/响应的工作方式,以及会话如何造成状态连接的错觉。这不仅适用于Vaadin,而且适用于所有网络工作。 Vaadin建立在此基础之上,因此要了解Vaadin,您需要了解Web的基础。