Оптимален ли код ниже для данной задачи?

Доброго дня всем! Сейчас переделываю архитектуру приложения, точнее его категории. Внедрил Materialized Path+ Adjacency List. И при добавлении новой категории, необходимо добавить ей полный путь. Можно ли sql запросом вытащить значения после последней точки у необходимой группы категории? Т.е есть такое значение в таблице: PATH: 1123.3131.33 Мне нужно получить 33, т.е то, что после последней запятой. И эту операцию необходимо провести у всей подгруппы, и найти наибольшее.В коде ниже я вытаскиваю ту группу категорий, которая мне необходима, и обрабатываю их. Оптимален ли этот код? Прошу оценить способ выборки.

public ResponseMessage addCategory(List<Category> newCategoryList, int parentId) {


        if (parentId == 0) {
            List<Category> categoryList = entityManager.createQuery("FROM Category c Where c.parentCategory.id=null", Category.class).getResultList();
            Integer largestIndex = getLargestIndex(categoryList);

            for (Category category : newCategoryList) {
                largestIndex++;
                String newPath = largestIndex.toString();
                category.setPath(newPath);
                entityManager.persist(category);

            }
            return new ResponseMessage(true, " ");

        } 

            Category parentCategory = entityManager.find(Category.class,  parentId);
            List<Category> categoryList = parentCategory.getCategoryList();
            categoryList.size();

            int largestIndex = getLargestIndex(categoryList);

            for (Category category : newCategoryList) {
                largestIndex++;
                StringBuilder newPath = new StringBuilder(parentCategory.getPath());
                newPath.append('.');
                newPath.append(largestIndex);
                parentCategory.addCategory(new Category(category.getName(), newPath));
            }
            return new ResponseMessage(true, " ");
   }

    public int getLargestIndex(List<Category> categoryList) {
        int largestIndex = 0;
        for (Category c : categoryList) {
            String[] sequence = c.getPath().split("\\.");
            int number = Integer.parseInt(sequence[sequence.length - 1]);
            if (number > largestIndex)
                largestIndex = number;
        }
        return largestIndex;
    }


p.s И оптимально ли разделение условием (parentId==0)? Т.к я решил не делать единого предка, а таким образом выбирать вышестоящие по иерархии.
  • Вопрос задан
  • 405 просмотров
Решения вопроса 1
@vayho
Category parentCategory = entityManager.find(Category.class, 1);

Здесь вероятно вместо 1 нужно поставить parentId.

И ответ на ваш вопрос: вместо ручного инкремента largestIndex вам нужно использовать id последней добавленной записи.

Кстати раз уж вы используете hibernate то посмотрите в сторону Closure Table, этот паттерн как мне кажется более органично смотрится с hibernate.

Вот пример кода с id(обязательно обернуть в транзакцию):
public ResponseMessage addCategory(List<Category> newCategoryList, int parentId) {
    Category parentCategory = parentId == 0 ? null : entityManager.find(Category.class, parentId);

    for (Category category : newCategoryList) {
        entityManager.persist(category);
        entityManager.flush();
        if (parentCategory != null) {
            category.setPath(parentCategory.getPath() + "." + category.getId());
            category.setParent(parentCategory);
        } else {
            category.setPath(String.valueOf(category.getId()));
        }
    }
    return new ResponseMessage(true, " ");
}
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
sanchezzzhak
@sanchezzzhak
Ля ля ля...
Кстати у вас } else {
лишний в первой функции достаточно условия. if( ... ) {
return
}
... другой код..
Можно ли sql запросом вытащить значения после последней точки у необходимой группы категории? Т.е есть такое значение в таблице: PATH: 1123.3131.33 Мне нужно получить 33, т.е то, что после последней запятой

select * from category where mpath like '%.33'
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы