Как реализовать обработку DataTables на стороне сервера с помощью JDB C, чтобы она разбивалась на страницы? - PullRequest
0 голосов
/ 23 января 2020

У меня есть приложение Spring Boot с серверной обработкой DataTables и базой данных Oracle. На самом деле, я начал с реализации одного из учебных пособий. Это сработало. Учебник использует JPA. Я хочу реализовать то же самое, используя JDB C. Я сделал все соответствующие классы, хранилище, новую модель с теми же полями, но без jpa. Но когда я попытался получить данные, это позволило мне получить только первую страницу без возможности попасть на вторую страницу. Ниже я выложу выдержки из оригинального и добавленного кода. Итак, в оригинальном уроке использовались следующие классы:

@Entity
@Table(name = "MYUSERS")
public class User {

    @Id
    @Column(name = "USER_ID")
    private Long id;

    @Column(name = "USER_NAME")
    private String name;

    @Column(name = "SALARY")
    private String salary;

...getters and setters
}

И

@Entity
public class UserModel {

    @Id
    private Long id;
    private String name;
    private String salary;

    private Integer totalRecords;

    @Transient
    private Integer rn;

...getters and setters
}

И я заменил эти два класса на один такой:

public class NewUser {

    private Long id;
    private String name;
    private String salary;
    private Integer totalRecords;
    private Integer rn;

...getters and setters
}

Таблица само по себе имеет только 3 поля: id, name и salary, остальные 2 поля создаются и заполняются позже. Репозиторий, который оригинальный автор имеет для пользователя, выглядит так:

public interface UserRepository extends JpaRepository<User, Long> {

    @Query(value = "SELECT * FROM MYUSERS", nativeQuery = true)
    List<User> findAllByUsernames(List<String> listOfUsernames);
}

Мой собственный репозиторий выглядит так:

@Repository
public class NewUserRepoImpl extends JdbcDaoSupport implements NewUserRepo {

    private static final String SELECT_ALL_SQL = "SELECT USER_ID as id, USER_NAME as name, SALARY as salary FROM MYUSERS";

    private final NamedParameterJdbcTemplate namedParameterJdbcTemplate;
    private final JdbcTemplate jdbctemplate;

    public NewUserRepoImpl(NamedParameterJdbcTemplate namedParameterJdbcTemplate, JdbcTemplate jdbctemplate, DataSource dataSource) {
        this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
        this.jdbctemplate = jdbctemplate;
        setDataSource(dataSource);
    }

    @Override
    public List<NewUser> findAll(PaginationCriteria pagination) {
        try {
            String paginatedQuery = AppUtil.buildPaginatedQueryForOracle(SELECT_ALL_SQL, pagination);
            return jdbctemplate.query(paginatedQuery, newUserRowMapper());
        } catch (DataAccessException e) {
            throw new EntityNotFoundException("No Entities Found");
        }
    }

    @Bean
    public RowMapper<NewUser> newUserRowMapper() {
        return (rs, i) -> {
            final NewUser newUser = new NewUser();
            newUser.setId(rs.getLong("ID"));
            newUser.setName(rs.getString("NAME"));
            newUser.setSalary(rs.getString("SALARY"));
            newUser.setTotalRecords(rs.getInt("TOTAL_RECORDS"));
            newUser.setTotalRecords(rs.getInt("RN"));
            return newUser;
        };
    }
}

buildPaginatedQueryFor Oracle вещь преобразует мой запрос и позволяет ему получить totalRecords и RSDN. Ниже я опубликую вывод его как для оригинала, так и для моих запросов (они одинаковые, я проверил).

Итак, основная часть, контроллер. Я оставил старые и новые фрагменты в нем для целей отладки и просто возвращаю один из результатов:

@RequestMapping(value="/users/paginated/orcl", method=RequestMethod.GET)
    @ResponseBody
    public String listUsersPaginatedForOracle(HttpServletRequest request, HttpServletResponse response, Model model) {

        DataTableRequest<User> dataTableInRQ = new DataTableRequest<User>(request);
        System.out.println(new Gson().toJson(dataTableInRQ));
        DataTableRequest<NewUser> dataTableInRQNew = new DataTableRequest<NewUser>(request);
        System.out.println(new Gson().toJson(dataTableInRQNew));
        PaginationCriteria pagination = dataTableInRQ.getPaginationRequest();
        System.out.println(new Gson().toJson(pagination));
        PaginationCriteria paginationNew = dataTableInRQNew.getPaginationRequest();
        System.out.println(new Gson().toJson(paginationNew));
        String baseQuery = "SELECT USER_ID as id, USER_NAME as name, SALARY as salary FROM MYUSERS";
        String paginatedQuery = AppUtil.buildPaginatedQueryForOracle(baseQuery, pagination);
        String paginatedQueryNew = AppUtil.buildPaginatedQueryForOracle(baseQuery, paginationNew);

        System.out.println(paginatedQuery);
        System.out.println(paginatedQueryNew);

        Query query = entityManager.createNativeQuery(paginatedQuery, UserModel.class);
        System.out.println("Query:");
        System.out.println(query);

        @SuppressWarnings("unchecked")
        List<UserModel> userList = query.getResultList();
        System.out.println(new Gson().toJson(userList));

        @SuppressWarnings("unchecked")
        List<NewUser> userListNew = newUserRepo.findAll(paginationNew);     
        System.out.println(new Gson().toJson(userListNew));

        DataTableResults<UserModel> dataTableResult = new DataTableResults<UserModel>();
        DataTableResults<NewUser> dataTableResultNew = new DataTableResults<NewUser>();
        dataTableResult.setDraw(dataTableInRQ.getDraw());
        dataTableResultNew.setDraw(dataTableInRQNew.getDraw());
        dataTableResult.setListOfDataObjects(userList);
        dataTableResultNew.setListOfDataObjects(userListNew);
        if (!AppUtil.isObjectEmpty(userList)) {
            dataTableResult.setRecordsTotal(userList.get(0).getTotalRecords()
                    .toString());
            if (dataTableInRQ.getPaginationRequest().isFilterByEmpty()) {
                dataTableResult.setRecordsFiltered(userList.get(0).getTotalRecords()
                        .toString());
            } else {
                dataTableResult.setRecordsFiltered(Integer.toString(userList.size()));
            }
        }
        if (!AppUtil.isObjectEmpty(userListNew)) {
            dataTableResultNew.setRecordsTotal(userListNew.get(0).getTotalRecords()
                    .toString());
            if (dataTableInRQ.getPaginationRequest().isFilterByEmpty()) {
                dataTableResultNew.setRecordsFiltered(userListNew.get(0).getTotalRecords()
                        .toString());
            } else {
                dataTableResultNew.setRecordsFiltered(Integer.toString(userListNew.size()));
            }
        }
        System.out.println(new Gson().toJson(dataTableResult));
        System.out.println(new Gson().toJson(dataTableResultNew));
        return new Gson().toJson(dataTableResult);
    }

Итак, я выхожу из системы в консоли. Вот вывод:

{"uniqueId":"1579786571491","draw":"1","start":0,"length":5,"search":"","regex":false,"columns":[{"index":0,"data":"id","name":"ID","searchable":true,"orderable":true,"search":"","regex":false,"sortDir":"ASC"},{"index":1,"data":"name","name":"Name","searchable":true,"orderable":true,"search":"","regex":false},{"index":2,"data":"salary","name":"Salary","searchable":true,"orderable":true,"search":"","regex":false}],"order":{"index":0,"data":"id","name":"ID","searchable":true,"orderable":true,"search":"","regex":false,"sortDir":"ASC"},"isGlobalSearch":false,"maxParamsToCheck":3}
{"uniqueId":"1579786571491","draw":"1","start":0,"length":5,"search":"","regex":false,"columns":[{"index":0,"data":"id","name":"ID","searchable":true,"orderable":true,"search":"","regex":false,"sortDir":"ASC"},{"index":1,"data":"name","name":"Name","searchable":true,"orderable":true,"search":"","regex":false},{"index":2,"data":"salary","name":"Salary","searchable":true,"orderable":true,"search":"","regex":false}],"order":{"index":0,"data":"id","name":"ID","searchable":true,"orderable":true,"search":"","regex":false,"sortDir":"ASC"},"isGlobalSearch":false,"maxParamsToCheck":3}
{"pageNumber":0,"pageSize":5,"sortBy":{"mapOfSorts":{"id":"ASC"}},"filterBy":{"mapOfFilters":{},"globalSearch":false}}
{"pageNumber":0,"pageSize":5,"sortBy":{"mapOfSorts":{"id":"ASC"}},"filterBy":{"mapOfFilters":{},"globalSearch":false}}
SELECT * FROM (SELECT FILTERED_ORDERED_RESULTS.*, COUNT(1) OVER() total_records, ROWNUM AS RN FROM (SELECT BASEINFO.* FROM ( SELECT USER_ID as id, USER_NAME as name, SALARY as salary FROM MYUSERS ) BASEINFO ) FILTERED_ORDERED_RESULTS   ORDER BY id ASC ) WHERE RN > (0 * 5) AND RN <= (0 + 1) * 5 
SELECT * FROM (SELECT FILTERED_ORDERED_RESULTS.*, COUNT(1) OVER() total_records, ROWNUM AS RN FROM (SELECT BASEINFO.* FROM ( SELECT USER_ID as id, USER_NAME as name, SALARY as salary FROM MYUSERS ) BASEINFO ) FILTERED_ORDERED_RESULTS   ORDER BY id ASC ) WHERE RN > (0 * 5) AND RN <= (0 + 1) * 5 
Query:
org.hibernate.query.internal.NativeQueryImpl@3ea49a4
[{"id":3,"name":"user3","salary":"300","totalRecords":18},{"id":4,"name":"user4","salary":"400","totalRecords":18},{"id":5,"name":"user5","salary":"500","totalRecords":18},{"id":6,"name":"user6","salary":"600","totalRecords":18},{"id":7,"name":"user7","salary":"700","totalRecords":18}]
[{"id":3,"name":"user3","salary":"300","totalRecords":1},{"id":4,"name":"user4","salary":"400","totalRecords":2},{"id":5,"name":"user5","salary":"500","totalRecords":3},{"id":6,"name":"user6","salary":"600","totalRecords":4},{"id":7,"name":"user7","salary":"700","totalRecords":5}]
{"draw":"1","recordsFiltered":"18","recordsTotal":"18","data":[{"id":3,"name":"user3","salary":"300","totalRecords":18},{"id":4,"name":"user4","salary":"400","totalRecords":18},{"id":5,"name":"user5","salary":"500","totalRecords":18},{"id":6,"name":"user6","salary":"600","totalRecords":18},{"id":7,"name":"user7","salary":"700","totalRecords":18}]}
{"draw":"1","recordsFiltered":"1","recordsTotal":"1","data":[{"id":3,"name":"user3","salary":"300","totalRecords":1},{"id":4,"name":"user4","salary":"400","totalRecords":2},{"id":5,"name":"user5","salary":"500","totalRecords":3},{"id":6,"name":"user6","salary":"600","totalRecords":4},{"id":7,"name":"user7","salary":"700","totalRecords":5}]}

Это помогло мне понять, что:

  1. DataTableRequest входящие сзади одинаковы для jpa и jdb c
  2. PaginationCriteria также одинаковы
  3. paginatedQuery, выполненные с помощью указанного выше метода, одинаковы.
  4. Различия уже видны в списках: где получен список Jpa в нативном Query значение totalRecords равно 18 для каждой строки, репозиторий JDB C с тем же запросом возвращает 1,2,3 ... для каждой последующей строки.

Это заставило меня думать, что я следует посмотреть на запрос, сделанный для JPA. Но, как вы видите в журнале, System.out.println не смог расшифровать его по какой-то причине. Будем весьма благодарны за любые советы о том, как его расшифровать и, что более важно, как получить правильный общий результат для каждой строки !!!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...