【Java・SpringBoot】Spring JDBC / ResultSetExtractor（SpringBootアプリケーション実践編17）

ホーム画面からユーザー一覧画面に遷移し、ユーザーの詳細を表示するアプリケーションを作成して、Spring JDBCの使い方について学びます⭐️
前回はBeanPropertyRowMapperについて学びました。今回はResultSetExtractorを実践して学びます^^
構成は前回/これまでの記事を参考にしてください

⭐️前回の記事
[【Java・SpringBoot】Spring JDBC / BeanPropertyRowMapper（SpringBootアプリケーション実践編16）](https://qiita.com/suema0331/items/f512531fbd4968f99d82)

#ResultSetExtractor
* RowMapper以外のO/Rマッパー
    * オブジェクトとRDBをマッピング（対応付け）する    
* ResultSetExtractorは、**複数件のselect結果をオブジェクトにマッピングする**

#ResultSetExtractorの設定
* **`ResultSetExtractor<List<T>>`をimplements**
    * `<T>`の部分に、任意の型を指定
        * `public class UserResultSetExtractor implements ResultSetExtractor<List<User>> {`
    * extractData()メソッドをOverride
        * そのメソッドの中でResultSetとオブジェクトのマッピングを行う
        * 複数件取得する前提なので、while文でループ処理をする

```UserResultSetExtractor.java
package com.example.demo.login.domain.repository.jdbc;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.springframework.dao.DataAccessException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.ResultSetExtractor;

import com.example.demo.login.domain.model.User;

public class UserResultSetExtractor implements ResultSetExtractor<List<User>> {

    @Override
    public List<User> extractData(ResultSet rs) throws SQLException, DataAccessException {

        //User格納用List
        List<User> userList = new ArrayList<>();

        //取得件数分のloop
        while(rs.next()) {

            //Listに追加するインスタンスを生成する
            User user = new User();

            //取得したレコードをUserインスタンスにセット
            user.setUserId(rs.getString("user_id"));
            user.setPassword(rs.getString("password"));
            user.setUserName(rs.getString("user_name"));
            user.setBirthday(rs.getDate("birthday"));
            user.setAge(rs.getInt("age"));
            user.setMarriage(rs.getBoolean("marriage"));
            user.setRole(rs.getString("role"));

            //ListにUserを追加
            userList.add(user);
        }

        //１件も無かった場合は例外を投げる
        if(userList.size() == 0) {
            throw new EmptyResultDataAccessException(1);
        }

        return userList;
    }
}

```
#リポジトリークラス
* UserDaoJdbcImpl4でもUserDaoJdbcImplをextends（継承）して、**select文の部分だけをOverride**

```UserDaoJdbcImpl4.java
package com.example.demo.login.domain.repository.jdbc;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import com.example.demo.login.domain.model.User;

@Repository("UserDaoJdbcImpl4")
public class UserDaoJdbcImpl4 extends UserDaoJdbcImpl {

    @Autowired
    private JdbcTemplate jdbc;

    @Override
    public List<User> selectMany() {

        //M_USERテーブルのデータを全件取得するSQL
        String sql = "SELECT * FROM m_user";

        //ResultSetExtractorの生成
        UserResultSetExtractor extractor = new UserResultSetExtractor();

        //SQL実行
        return jdbc.query(sql, extractor);
    }
}
```

#サービスクラスからUserDaoJdbcImpl4を指定
* コード全文は下記参考

```UserService.java
//省略
@Service
public class UserService {
    @Autowired
    @Qualifier("UserDaoJdbcImpl4")
    UserDao dao;
//省略
```

#SpringBootを起動してホーム画面確認！
* http://localhost:8080/home
* ユーザー一覧、ユーザー詳細画面に移ると、コンソールの表示がUserDaoJdbcImpl4に変わっています
* これでResultSetExtractorを使うことができました〜^o^

```
//コンソール
メソッド開始： List com.example.demo.login.domain.repository.jdbc.UserDaoJdbcImpl4.selectMany()
メソッド終了： List com.example.demo.login.domain.repository.jdbc.UserDaoJdbcImpl4.selectMany()
```

#(参考)コード全文

```UserService.java
package com.example.demo.login.domain.service;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.example.demo.login.domain.model.User;
import com.example.demo.login.domain.repository.UserDao;

@Service
public class UserService {
    @Autowired
    @Qualifier("UserDaoJdbcImpl4")
    UserDao dao;

    public boolean insert(User user) {
        // insert実行
        int rowNumber = dao.insertOne(user);
        // 判定用変数
        boolean result = false;

        if (rowNumber > 0) {
            // insert成功
            result = true;
        }
        return result;
    }

    public int count() {
        return dao.count();
    }

    public List<User> selectMany() {
        // 全件取得
        return dao.selectMany();
    }

    public User selectOne(String userId) {
        // selectOne実行
        return dao.selectOne(userId);
    }

    public boolean updateOne(User user) {

        // 判定用変数
        boolean result = false;

        // １件更新
        int rowNumber = dao.updateOne(user);

        if (rowNumber > 0) {
            // update成功
            result = true;
        }

        return result;
    }

    public boolean deleteOne(String userId) {

        // １件削除
        int rowNumber = dao.deleteOne(userId);

        // 判定用変数
        boolean result = false;

        if (rowNumber > 0) {
            // delete成功
            result = true;
        }
        return result;
    }
}
```