我是Vaadin框架的新手,不确定如何继续进行数据库连接。
我不想要的是在每个会话中实现连接。在我的讲解中,vaadin在会话级别工作。
是否可以创建一个无论会话都会持久化的类,然后,vaadin会查询它以获取数据库连接?
答案 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的基础。