19 Kasım 2019 Salı

Criteria Arayüzü - Kullanmayın

Giriş
Şu satırı dahil ederiz.
import org.hibernate.Criteria;
Bu arayüz yerine JPA metodlarını kullanmak daha iyi. Şöyle yaparız.
javax.persistence.criteria.CriteriaBuilder
javax.persistence.criteria.CriteriaQuery

// Create CriteriaBuilder
CriteriaBuilder builder = session.getCriteriaBuilder();

// Create CriteriaQuery
CriteriaQuery<YourClass> criteria = builder.createQuery(YourClass.class);
Kullanım
1. Criteria bir sınıf ile beraber yaratılır. Şöyle yaparız.
session.createCriteria(Bus.class).list();
2. İstenirse isim yani alias ta verilebilir. Alias daha sonra Restrictions sınıfları içinde alanlara erişmek için kullanılır. Şöyle yaparız.
Criteria cr = session.createCriteria(Profession.class, "pro")
3. Criteria sınıfı session tarafından yaratılır ve en önemli metodu list()'tir.  list metodu generic olmadığı için sonucu hep cast etmek gerekir. Şöyle yaparız.
Criteria criteria =sessionFactory.getCurrentSession().createCriteria(Student.class);
criteria.add(Restrictions.eq("departmentId", departmentId));
criteria.add(Restrictions.eq("departmentType", departmentType));
ArrayList<Student> studentList = (ArrayList)criteria.list();
constructor
Criteria şöyle yaratılır.
Criteria cr = session.createCriteria(StPurOrders.class);
Criteria alias ile de yaratılabilir.
Criteria criteria = session.createCriteria(Employee2.class, "employee");
add metodu
Bu metod ile Restriction, Criteria nesnesine eklenir.
Örnek
Şöyle yaparız.
Criteria criteria = session.createCriteria(MyClass.class);
criteria.add(Restrictions.eq("id", id));
criteria.list();
addOrder metodu
Şöyle yaparız.
Criteria c = session.createCriteria(Cat.class);
c.createAlias("mother.kind", "motherKind");
c.addOrder(Order.asc("motherKind.value"));
return c.list();
createAlias metodu
Join yaparken alias kullanmak için kullanılır.
Örnek
Şöyle yaparız.
Criteria criteria = session.createCriteria("user");
criteria.createAlias("user.tracking", "tracking")
Örnek
Şöyle yaparız.
Session session = entityManager.unwrap(Session.class);
Criteria criteria = session.createCriteria(EntityA.class, "a_alias");
criteria.createAlias("a_alias.bList", "b_alias", JoinType.LEFT_OUTER_JOIN);
criteria.createAlias("b_alias.cList", "c_alias", JoinType.LEFT_OUTER_JOIN);

critier.add(Restrictions.eq("c_alias.name", "abc"));
return (List<EntityA>)criteria.list();
createCriteria metodu - Class
Sınıf ismi verilir. Sınıfın kullandığı tablo sorguda yer alır. Şöyle yaparız.
Criteria criteria = session.createCriteria(QrCodeList.class);
Criteria prdCrit = criteria.createCriteria("user");
createCriteria metodu - Class + alias
Şöyle yaparız.
Session session = entityManager.unwrap(Session.class);
Criteria criteria = session.createCriteria(EntityA.class, "a_alias");
list metodu
list() metodunun döndüreceği satır sayısı setMaxResults() metodu ile belirlenir.Örnek
Şöyle yaparız.
Criteria criteria = session.createCriteria(Profession.class);
criteria.add(Restrictions.eq("uid", id));
List results = criteria.list();
Örnek
Şöyle yaparız.
//This method will return all
public List<TargetDocument> getAll() {
  Criteria criteria = session.createCriteria(TargetDocument.class);
  return criteria.list();
}
setCacheable metodu
Sorgunun ve sonucunun ikincil önbellekte tutulması için şöyle yaparız.
criteria.setCacheable (true);
Eğer bunu yapmazsak sorgu ve sonucu ikincil önbellekte saklanmaz. Yani şu kod her zaman veritabanına gider.
List<?> results = criteria.list();
setFirstResult metodu
Sayfalama için setMaxResult() metodu ile beraber kullanılır. Şöyle yaparız. Sayfalamanın düzgün çalışması için bir sıralama kriteri de kullanılmalıdır
public List getPages(int start, int end) {
  Criteria criteria = session.createCriteria(Page.class);
  criteria.setFirstResult(start).setMaxResults(end);
  return criteria.list();
}
setFetchMode metodu
Bu metod ile sorgunun ilişkili olduğu diğer tabloların nasıl çekileceği belirtilir. 4 tip fetch yöntemi var. Bunlar şöyle

1. fetch-“join” = Disable the lazy loading, always load all the collections and entities.
2. fetch-“select” (default) = Lazy load all the collections and entities.
3. batch-size=”N” = Fetching up to ‘N’ collections or entities, Not record.
4. fetch-“subselect” = Group its collection into a sub select statement.
Criteria criteria = session.createCriteria(Profession.class, "pro")
.setFetchMode("user", FetchMode.JOIN);
setMaxResult metodu
Şöyle yaparız.
Criteria criteria = ...;
criteria.add(...);
criteria.setMaxResults(1);
MyClass quote = (MyClass) criteria.uniqueResult();
setProjection metodu
Örnek
Şöyle yaparız.
criteria.setProjection(Projections.distinct(Projections.property("id")));
Örnek
Şöyle yaparız.
criteria.setProjection(Projections.rowCount());
setResultTransformer metodu - Criteria.DISTINCT_ROOT_ENTITY
Bu metod SQL DISTINCT() çağrısı yapmaz! Hibernate tüm satırları çektikten sonra bellekte distinct'e benzer bir işlem yapar. Sadece OneToMany gibi ilişkilerde kullanılması gerekir. Açıklaması şöyle.
The only case, when we MUST to use that, if there is an association in the query - JOINING the one-to-many end.
Örnek
Şöyle yaparız.
getCurrentSession().createCriteria(Advertisement.class)
                .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
                .addOrder(Order.asc("adPkId")).list();
Örnek
Şöyle yaparız.
Criteria criteria = session.createCriteria(SillonBD.class);
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
setResultTransformer metodu - ResultTransformer
Örnek
Şöyle yaparız.
cr.setResultTransformer(Transformers.aliasToBean(PurOrderColl.class));
Örnek
Şöyle yaparız.
crit.setResultTransformer(new ResultTransformer() {

  @Override
  public Object transformTuple(Object[] tuple, String[] aliases) {
    String name = (Long) tuple[0];
    String firstName = (String) tuple[1];
    return new Person(name , firstName);
  }

  @Override
  public List<Reference> transformList(List collection) {
    return collection;
  }
});
uniqueResult metodu
Eğer sorgu sonucunda tek bir nesne bekleniyorsa bu metod kullanılır. Tek sonu dönmezse org.hibernate.NonUniqueResultException fırlatılır. Açıklaması şöyle.
Thrown when the application calls Query.uniqueResult() and the query returned more than one result.
Örnek
Şöyle yaparız.
session().createCriteria(Music.class)
  .add(Restrictions.eq("id",id)).uniqueResult();
Örnek
Şöyle yaparız.
criteria.setProjection(Projections.rowCount());

Number number = (Number) criteria.uniqueResult();
Örnek
Şöyle yaparız.
Criteria cr = session.createCriteria(...);
cr.add(...);
Profession pro = cr.uniqueResult();