簡體   English   中英

如何使用 JDBC 在 spring 引導測試類上創建事務上下文?

[英]How to create a transactional context on spring boot test classes using JDBC?

當我使用 hibernate 時,一旦我進行了測試,所做的所有更改都會在這些測試完成后回滾。

但是,當我將 JDBC 與我的 DAO 實現而不是 JpaRepositories 一起使用時,測試期間發生的突變不會被回滾。

我怎樣才能讓所有更改都被回滾?

在這里,您可以看到我的一個測試類的樣子:

package com.cemonan.bookdb2;

import com.cemonan.bookdb2.dao.BookDao;
import com.cemonan.bookdb2.domain.Book;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.context.annotation.ComponentScan;

import java.util.List;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;

@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@ComponentScan(basePackages = {"com.cemonan.bookdb2.dao"})
public class BookDaoIntegrationTest {

    @Autowired
    BookDao bookDao;

    @Test
    void testCreateBook() {
        List<Book> books = bookDao.findAll();
        int countBefore = books.size();

        Book book = new Book();
        book.setTitle("A book");
        book.setIsbn("123");
        book.setPublisher("Someone");

        Book savedBook = bookDao.save(book);

        books = bookDao.findAll();
        int countAfter = books.size();

        assertThat(savedBook).isNotNull();
        assertThat(countAfter).isGreaterThan(countBefore);
    }
}


package com.cemonan.bookdb2.dao;

import com.cemonan.bookdb2.domain.Book;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

import static com.cemonan.bookdb2.dao.utils.Utils.closeAll;

@Component
public class BookDaoImpl implements BookDao {

    @Autowired
    DataSource source;

    Book mapRsToBook(ResultSet rs) throws SQLException {
        Book book = new Book();
        book.setId(rs.getLong("id"));
        book.setTitle(rs.getString("title"));
        book.setIsbn(rs.getString("isbn"));
        book.setPublisher(rs.getString("publisher"));
        return book;
    }

    @Override
    public Book findById(Long id) {
        Connection connection = null;
        PreparedStatement ps = null;
        ResultSet rs = null;

        try {
            connection = this.source.getConnection();
            ps = connection.prepareStatement("SELECT * FROM book WHERE id = ?");
            ps.setLong(1, id);
            rs = ps.executeQuery();

            if (rs.next()) {
                return mapRsToBook(rs);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                closeAll(rs, ps, connection);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        return null;
    }

    @Override
    public Book save(Book book) {
        Connection connection = null;
        PreparedStatement ps = null;
        ResultSet rs = null;

        try {
            connection = this.source.getConnection();
            ps = connection.prepareStatement("INSERT INTO book (title, isbn, publisher) VALUES (?, ?, ?)");
            ps.setString(1, book.getTitle());
            ps.setString(2, book.getIsbn());
            ps.setString(3, book.getPublisher());
            ps.execute();

            Statement stmt = connection.createStatement();
            rs = stmt.executeQuery("SELECT LAST_INSERT_ID()");

            if (rs.next()) {
                return this.findById(rs.getLong(1));
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                closeAll(rs, ps, connection);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        return null;
    }

    @Override
    public Book update(Book book) {
        Connection connection = null;
        PreparedStatement ps = null;
        ResultSet rs = null;

        try {
            connection = this.source.getConnection();
            ps = connection.prepareStatement("UPDATE book SET title = ?, isbn = ?, publisher = ? WHERE id = ?");
            ps.setString(1, book.getTitle());
            ps.setString(2, book.getIsbn());
            ps.setString(3, book.getPublisher());
            ps.setLong(4, book.getId());
            ps.execute();

            if (rs.next()) {
                return this.findById(book.getId());
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                closeAll(rs, ps, connection);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        return null;
    }

    @Override
    public void delete(Book book) {
        Connection connection = null;
        PreparedStatement ps = null;
        ResultSet rs = null;

        try {
            connection = this.source.getConnection();
            ps = connection.prepareStatement("DELETE FROM book WHERE id = ?");
            ps.setLong(1, book.getId());
            ps.execute();

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                closeAll(rs, ps, connection);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public Book findByTitle(String title) {
        Connection connection = null;
        PreparedStatement ps = null;
        ResultSet rs = null;

        try {
            connection = this.source.getConnection();
            ps = connection.prepareStatement("SELECT * FROM book WHERE title = ?");
            ps.setString(1, title);
            rs = ps.executeQuery();

            if (rs.next()) {
                return this.mapRsToBook(rs);
            }
        } catch(SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                closeAll(rs, ps, connection);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        return null;
    }

    @Override
    public List<Book> findAll() {
        Connection connection = null;
        Statement stmt = null;
        ResultSet rs = null;
        List<Book> books = new ArrayList<>();

        try {
            connection = this.source.getConnection();
            stmt = connection.createStatement();
            rs = stmt.executeQuery("SELECT * FROM book");

            while(rs.next()) {
                Book book = this.mapRsToBook(rs);
                books.add(book);
            }
        } catch(SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                closeAll(rs, stmt, connection);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        return books;
    }
}

由於您最終已經作為 DAO 代碼的一部分close了連接,因此在@DataJpaTest可以回滾之前,事務(在啟動@DataJpaTest時啟動)可能正在提交。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM