複数のDBユーザでテストしないといけない時の苦肉の策

## 背景
* ユーザAはHogeテーブルに参照できるが、Fugaテーブルの更新権限がない
* ユーザBはHogeテーブルに参照できないが、Fugaテーブルの更新権限がある
ユーザBを使ってテストデータの挿入をし、ユーザAでテストしたいロジックを実行したいというケース

`@BeforeAll`でDBのデータのバックアップを作成し、`@AfterAll`を使って復旧(DELETE、INSERT)する
ただし、データバックアップ→テスト開始の際など、トランザクションが切り替わる間に更新が走るとこの更新内容を消してしまう危険性がある。

### サンプル
```Java
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

@SpringJUnitConfig
public class YourTest {

    @Autowired
    private JdbcTemplate jdbcTemplateUserB;

    @Autowired
    private JdbcTemplate jdbcTemplateUserA;

    private static List<Map<String, Object>> originalDataUserB;  // user-B の元データ
    private static List<Map<String, Object>> originalDataUserA;  // user-A の元データ

    // BeforeAllでテスト前にデータを保存
    @BeforeAll
    public static void setUpBeforeAll(@Autowired JdbcTemplate jdbcTemplateUserB, @Autowired JdbcTemplate jdbcTemplateUserA) {
        // user-B のデータを取得して保存
        originalDataUserB = jdbcTemplateUserB.queryForList("SELECT * FROM your_table");

        // user-A のデータを取得して保存
        originalDataUserA = jdbcTemplateUserA.queryForList("SELECT * FROM your_table");
    }

    // AfterAllでテスト後に元のデータを復旧
    @AfterAll
    public static void tearDownAfterAll(@Autowired JdbcTemplate jdbcTemplateUserB, @Autowired JdbcTemplate jdbcTemplateUserA) {
        // user-B のデータを元に戻す
        jdbcTemplateUserB.update("DELETE FROM your_table");
        for (Map<String, Object> data : originalDataUserB) {
            // 全てのカラムを動的に処理
            StringBuilder columns = new StringBuilder();
            StringBuilder values = new StringBuilder();
            data.forEach((column, value) -> {
                if (columns.length() > 0) {
                    columns.append(", ");
                    values.append(", ");
                }
                columns.append(column);
                values.append("?");
            });

            // INSERT文の作成
            String insertSql = String.format("INSERT INTO your_table (%s) VALUES (%s)", columns.toString(), values.toString());
            
            // 値の準備
            Object[] insertValues = data.values().toArray();
            
            // INSERTを実行
            jdbcTemplateUserB.update(insertSql, insertValues);
        }

        // user-A のデータを元に戻す
        jdbcTemplateUserA.update("DELETE FROM your_table");
        for (Map<String, Object> data : originalDataUserA) {
            // 全てのカラムを動的に処理
            StringBuilder columns = new StringBuilder();
            StringBuilder values = new StringBuilder();
            data.forEach((column, value) -> {
                if (columns.length() > 0) {
                    columns.append(", ");
                    values.append(", ");
                }
                columns.append(column);
                values.append("?");
            });

            // INSERT文の作成
            String insertSql = String.format("INSERT INTO your_table (%s) VALUES (%s)", columns.toString(), values.toString());

            // 値の準備
            Object[] insertValues = data.values().toArray();

            // INSERTを実行
            jdbcTemplateUserA.update(insertSql, insertValues);
        }
    }

    @Test
    @Transactional
    public void testMyBatisOperations() {
        // user-A でデータ操作
        jdbcTemplateUserA.update("UPDATE your_table SET column1 = 'new_value' WHERE column1 = 'old_value'");
        
        // user-A でデータ参照
        List<String> data = jdbcTemplateUserA.queryForList("SELECT column1 FROM your_table", String.class);
        
        // アサート例: 'new_value'が存在するか確認
        assert(data.contains("new_value"));
    }

    @Test
    @Transactional
    public void testAnotherOperation() {
        // 他の操作を追加できます
    }
}

```