如何保持Spring MVC与数据库的永久连接?

时间:2020-05-18 08:30:42

标签: java spring database spring-boot model-view-controller

摘要:我无法在Spring MVC中保持数据库连接处于活动状态,这就是为什么所有查询执行缓慢(首先连接而不是执行)的原因。下面我详细解释。

我继续学习Java。我使用servlet和JSP制作了一些simple websocket chat。我将其称为Project#1。现在,我正在使用Spring Boot和Thymeleaf将其重新设计为更现代的Spring MVC技术。当前结果为here,我将其称为Project#2。

Project#2现在运行与Project#1相同的功能,除了一些细节。但是有一个大问题。

当我在联系人之间切换时,我的应用程序将ajax查询发送到服务器并获取消息历史记录。在Project#2中,它会缓慢地发生。比Project#1慢得多。

我相信这是因为在Project#1中,MySQL连接手动存储在Httprequest属性中。可以通过servlet过滤器来完成,例如:

Connection conn = null;
        try {
            // Create a Connection.
            conn = ConnectionUtils.getConnection();
            // Set outo commit to false.
            conn.setAutoCommit(false);

            // Store Connection object in attribute of request.
            MyUtils.storeConnection(request, conn);

            // Allow request to go forward
            // (Go to the next filter or target)
            chain.doFilter(request, response);

            // Invoke the commit() method to complete the transaction with the DB.
            conn.commit();
        } catch (Exception e) {
            e.printStackTrace();
            ConnectionUtils.rollbackQuietly(conn);
            throw new ServletException();
        } finally {
            ConnectionUtils.closeQuietly(conn);
        }

因为我需要从数据库中获取一些东西,所以我使用了这样的现有连接:

Connection conn = MyUtils.getStoredConnection(request);
ArrayList<UserAccount> userList = new ArrayList();
    try {
        userList = DBUtils.userList(conn, loginedUser.getUserName());
    } catch (SQLException e) {
        e.printStackTrace();
        errorString = e.getMessage();
    }

但是,在Spring MVC中,还有另一种用于数据库连接的技术。 DAO类等。我的application.properties:

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://freshnoon.beget.tech/freshnoon_chat
spring.datasource.username=freshnoon_chat
spring.datasource.password=hgy78fdXVb0

由于未知原因,这还不够(我收到缺少DataSource bean的错误)。因此,我将此bean添加到了WebConfig.java:

@Bean
public DataSource dataSource() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
    dataSource.setUrl("jdbc:mysql://freshnoon.beget.tech/freshnoon_chat?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC");
    dataSource.setUsername("freshnoon_chat");
    dataSource.setPassword("hgy78fdXVb0");

    return dataSource;
}

数据库查询现在由DatabaseAccess extends JdbcDaoSupport处理:

@Repository
@Transactional
public class DatabaseAccess extends JdbcDaoSupport {

@Autowired 
private DataSource dataSource;

@Autowired
public DatabaseAccess(DataSource dataSource) {
    this.setDataSource(dataSource);
}

例如,获取历史记录的方法:

public List<Message> getHistory(String sender, String reciever) throws SQLException {

    String sql = "Select * from MESSAGES m where m.Sender = ? and m.Reciever = ? or m.Sender = ? and m.Reciever = ?";
    Object[] args = new Object[] { sender, reciever, reciever, sender };
    MessageMapper mapper = new MessageMapper();

    try {
        List<Message> history = this.getJdbcTemplate().query(sql, args, mapper);
        return history;
    } catch (EmptyResultDataAccessException e) {
        return null;
    }
}

我注意到,第二种技术的运行速度太慢。我录制了2个视频来代表:

感谢您阅读这么大的文字!请提供有关如何在Project#2(Spring MVC)中保持与数据库的连接的建议。

1 个答案:

答案 0 :(得分:1)

我需要连接池。 Application.properties:

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://freshnoon.beget.tech/freshnoon_chat?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
spring.datasource.username=freshnoon_chat
spring.datasource.password=hgy78fdXVb0
spring.datasource.type=org.apache.tomcat.jdbc.pool.DataSource
spring.datasource.tomcat.initial-size=15
spring.datasource.tomcat.max-wait=20000
spring.datasource.tomcat.max-active=50
spring.datasource.tomcat.max-idle=15
spring.datasource.tomcat.min-idle=8
spring.datasource.tomcat.default-auto-commit=true

一些必需的依赖项:

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>com.zaxxer</groupId>
                    <artifactId>HikariCP</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>

我是从这个guide那里得到的。

也许这不是我应用程序的最佳方式。也许我在实施它时犯了一些错误。但是我已经看到了区别,消息加载速度更快。感谢您的评论,继续学习;)

相关问题