Во-первых, @SortComparator и @SortNatural не сортируют элементы после загрузки их из БД, но сортируют их во время их вставки.Таким образом, элементы сортируются в памяти.
При использовании @OrderBy (CULOMN_NAME ASC) Hibernate сортирует элементы коллекции, когда элементы загружаются из БД путем выполнения оператора Select с помощью ORDER BY.
Я измерил производительность для @SortNatural и @OrderBy (clause = "random_string ASC". Хранение и загрузка 200 тыс. Случайных строк с длиной восьмых символов. (Используемый код ниже.)
Результаты:
Сохранение данных с помощью @SortNatural:
- 472 секунды
- 424 секунды
Загрузка данных с помощью @SortNatural:
- 2,6 секунды
- 1,7 секунды
- 1,7 секунды
- 3,0 секунд
- 1,2 секунд
Сохранение данных с помощью @ OrderBy
- 431 секунд
- 413 секунд
Загрузка данных с помощью @ OrderBy
- 3,3 секунды
- 3,3 секунды
- 3,0 секунды
- 3,5 секунд
- 4,8 секунды
hibernate.cfg.xml
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/hibernateTest</property>
<property name="connection.username">root</property>
<property name="connection.password"></property>
<property name="conection.pool_size">1</property>
<property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>
<property name="show_sql">true</property>
<property name="current_session_context_class">thread</property>
<property name="hibernate.hbm2ddl.auto">create</property>
</session-factory>
</hibernate-configuration>
ClassWithStringCollection
@Entity
@Table(name="class_with_string_collection")
public class ClassWithStringColloction{
@Id
@Column(name="id")
private int id;
@ElementCollection
@CollectionTable(name="random_strings")
@Column(name="random_string")
//@SortNatural
@OrderBy(clause = "random_string ASC")
protected SortedSet<String> randomStrings = new TreeSet<String>();
public ClassWithStringColloction() {
}
public ClassWithStringColloction(SortedSet<String> modules) {
this.randomStrings = modules;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public SortedSet<String> getRandomStrings() {
return randomStrings;
}
public void setRandomStrings(SortedSet<String> randomStrings) {
this.randomStrings = randomStrings;
}
}
main
public class main {
public static void main(String[] args) {
SessionFactory factory = new Configuration()
.configure("hibernate.cfg.xml")
.addAnnotatedClass(ClassWithStringColloction.class)
.addAnnotatedClass(RandomString.class)
.buildSessionFactory();
Session session = factory.getCurrentSession();
try {
long timeBefore;
long timeAfter;
long elapsed;
SortedSet<String> randomStrings = new TreeSet();
ClassWithStringColloction classWithSC = new ClassWithStringColloction(new TreeSet());
//performance measurement propagating data to DB
RandomStringGenerator randStringGen = new RandomStringGenerator(10);
String randomString = "";
session.beginTransaction();
session.persist(classWithSC);
classWithSC = session.find(ClassWithStringColloction.class, 0);
randomStrings = classWithSC.getRandomStrings();
timeBefore = System.currentTimeMillis();
for (int i = 0; i < 200000; i++) {
randomString = randStringGen.nextString();
randomStrings.add(randomString);
session.update(classWithSC);
if (i % 100 == 0) {
session.flush();
session.clear();
}
}
session.getTransaction().commit();
timeAfter = System.currentTimeMillis();
elapsed = timeAfter - timeBefore;
System.out.println("Time for storing 200000 String:" + elapsed + " ms");
//Performance measurement for loading stored data.
session = factory.getCurrentSession();
session.beginTransaction();
timeBefore = System.currentTimeMillis();
classWithSC = session.get(ClassWithStringColloction.class, 0);
randomStrings = classWithSC.getRandomStrings();
System.out.println(randomStrings.first());
session.getTransaction().commit();
timeAfter = System.currentTimeMillis();
elapsed = timeAfter - timeBefore;
System.out.println("Time for loading 200000 Strings:" + elapsed + " ms");
System.out.println("Done");
} catch (Exception e) {
e.printStackTrace();
}
session.close();
}
}
RandomStringGenerator 1.Answer of Как создать случайную буквенно-цифровую строку?