除了jpa的@OrderBy
(在SQL级别上对元素进行排序)之外,hibernate还提供了@SortComparator
和@SortNatural
,它们是从数据库加载后对元素进行排序的。
@OrderBy
更好,为什么还会有人使用另一个选项,因为它甚至不是jpa标准?答案 0 :(得分:1)
首先,@SortComparator和@SortNatural在从数据库中加载元素后不对元素进行排序,而是在插入期间对其进行排序。因此,元素在内存中排序。
使用@OrderBy(CULOMN_NAME ASC)时,当通过使用ORDER BY执行Select-Statement从数据库加载元素时,Hibernate会对集合的元素进行排序。
我测量了@SortNatural和@OrderBy(clause =“ random_string ASC”的性能。 存储和加载200k个长度为8个字符的随机字符串。 (使用的代码在下面。)
结果是:
使用@SortNatural存储数据:
使用@SortNatural加载数据:
使用@OrderBy存储数据
使用@OrderBy加载数据
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;
}
}
主要
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,答案 How to generate a random alpha-numeric string?
答案 1 :(得分:0)
参考:https://thoughts-on-java.org/ordering-vs-sorting-hibernate-use/
如果函数经常调用,请使用OrderBy。
如果要将所有数据加载到内存中并手动进行管理,请使用“排序”。