Точная разница между .iterate () и .list (). Iterator () в спящем режиме? [Дубликат]

Вопрос не совсем ясен, но вот краткое описание способов инициализации данных в объекте. Предположим, что у вас есть класс A, который содержит список объектов.

1) Поместите начальные значения в объявление поля:

class A {
    private List<Object> data = new ArrayList<Object>();
}

2) Назначьте начальные значения в конструкторе:

class A {
    private List<Object> data;
    public A() {
        data = new ArrayList<Object>();
    }
}

В обоих случаях предполагается, что вы не хотите передавать «данные» в качестве аргумента конструктора.

Все становится немного сложнее, если вы смешиваете перегруженные конструкторы с внутренними данными, такими как выше , Рассмотрим:

class B {
    private List<Object> data;
    private String name;
    private String userFriendlyName;

    public B() {
        data = new ArrayList<Object>();
        name = "Default name";
        userFriendlyName = "Default user friendly name";
    }

    public B(String name) {
        data = new ArrayList<Object>();
        this.name = name;
        userFriendlyName = name;
    }

    public B(String name, String userFriendlyName) {
        data = new ArrayList<Object>();
        this.name = name;
        this.userFriendlyName = userFriendlyName;
    }
}

Обратите внимание, что существует много повторяющегося кода. Вы можете исправить это, заставив конструкторы вызвать друг друга, или вы можете получить частный метод инициализации, который вызывает каждый конструктор:

class B {
    private List<Object> data;
    private String name;
    private String userFriendlyName;

    public B() {
        this("Default name", "Default user friendly name");
    }

    public B(String name) {
        this(name, name);
    }

    public B(String name, String userFriendlyName) {
        data = new ArrayList<Object>();
        this.name = name;
        this.userFriendlyName = userFriendlyName;
    }
}

или

class B {
    private List<Object> data;
    private String name;
    private String userFriendlyName;

    public B() {
        init("Default name", "Default user friendly name");
    }

    public B(String name) {
        init(name, name);
    }

    public B(String name, String userFriendlyName) {
        init(name, userFriendlyName);
    }

    private void init(String _name, String _userFriendlyName) {
        data = new ArrayList<Object>();
        this.name = name;
        this.userFriendlyName = userFriendlyName;
    }
}

Эти два (более или меньше).

Надеюсь, это даст вам несколько советов о том, как инициализировать данные в ваших объектах. Я не буду говорить о статических инициализационных блоках, поскольку это, вероятно, немного продвинуто на данный момент.

EDIT: Я интерпретировал ваш вопрос как «как инициализировать мои переменные экземпляра», а не «как инициализатор блокирует работу ", поскольку блоки инициализации являются относительно продвинутой концепцией, и из тон вопроса кажется, что вы спрашиваете о более простой концепции. Я мог ошибаться.

5
задан Avinash R 19 February 2013 в 14:12
поделиться

4 ответа

Если экземпляры уже находятся в сеансе (кеш основного уровня) или кеш второго уровня iterate(), это даст лучшую производительность.

Если они еще не кэшированы, iterate() будет медленнее, чем list() и может потребовать много запросов к базе данных для простого запроса.

4
ответ дан timrau 28 August 2018 в 02:19
поделиться

Query.list (): Выполняет 1 SQL-запрос и загружает все данные. Даже если записи присутствуют в кеше, выполняется новый SQL-запрос для загрузки записей из базы данных.

List<Employee> list1 = session.createQuery("from Employee").list(); // SELECT *FROM EMP
for (Employee e : list1) {
    System.out.println(e);
}
List<Employee> list2 = session.createQuery("from Employee").list(); // SELECT *FROM EMP
for (Employee e : list2) {
    System.out.println(e);
}

Query.iterate (): Выполняет 1 + N SQL-запросы. Первый запрос возвращает только идентификатор всех записей, и когда возвращенный итератор повторяется, каждый раз, когда выполняется отдельный SQL-запрос, который содержит предложение WHERE, такое как «WHERE id = N». Если записи присутствуют в кеше, то выполняется первый запрос, а остальные N запросов не выполняются и записи получаются из кеша.

Iterator<Employee> iterator1 = session.createQuery("from Employee").iterate(); // SELECT EMP_ID FROM EMP
while(iterator1.hasNext()) {
    System.out.println(iterator1.next()); // SELECT * FROM EMP WHERE EMP_ID=?
}
Iterator<Employee> iterator2 = session.createQuery("from Employee").iterate(); // SELECT EMP_ID FROM EMP
while (iterator2.hasNext()) {
    System.out.println(iterator2.next()); // From cache, no SQL
}
12
ответ дан Amitabha Roy 28 August 2018 в 02:19
поделиться

javadoc говорит:

Вернуть результаты запроса в качестве Итератора. Если запрос содержит несколько предварительных строк результатов, результаты возвращаются в экземпляре Object [].

Объекты, возвращаемые по мере инициализации результатов по запросу. Первый SQL-запрос возвращает только идентификаторы.

(акцент мой)

3
ответ дан JB Nizet 28 August 2018 в 02:19
поделиться
+----------------------------------------------+-----------------------------------------------+
|                    list()                    |                   iterate()                   |
+----------------------------------------------+-----------------------------------------------+
| Return type is List                          | Return type is Iterate                        |
| All records loads at single database request | For each record, one database hit is made     |
| This is faster if cache is not available     | This is very slower if cache is not available |
| Eager loading                                | Lazy loading                                  |
+----------------------------------------------+-----------------------------------------------+  

Для списка ():

Query query = session.createQuery("from Employee");
List list = query.list(); // SELECT * FROM EMP
Iterator iterator = list.iterator();
while(iterator.hasNext()){
}  

Для итерации ():

Query query = session.createQuery("from Employee");
Iterator iterator = query.iterate(); // SELECT * FROM EMP
while(iterator.hasNext()){
    // SELECT * FROM EMP WHERE EMP_ID=?
}
1
ответ дан Premraj 28 August 2018 в 02:19
поделиться
Другие вопросы по тегам:

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