Let's talk about Criteria query, which is easy for us programmers who are not very familiar with SQL statements.
Without further ado, let's take a look at the example:
The entity class is as follows:
public class User implements Serializable{ private static final long serialVersionUID = 1L; public Long id; private String name; private int age; //Omit Get/Set method} We won't write the mapping file, it's a very simple entity. If you don't understand children's shoes, please refer to my other articles in the hibernate category.
Next, let's see how to use Criteria to query:
public static void main(String[] args) { Configuration cfg = new Configuration().configure(); SessionFactory sessionFactory = cfg.buildSessionFactory(); Session session = sessionFactory.openSession(); Criteria criteria = session.createCriteria(User.class); criteria.add(Restrictions.eq("name","shun")); List list = criteria.list(); Iterator iter = list.iterator(); while(iter.hasNext()) { User user = (User)iter.next(); System.out.println(user.getName()+":"+user.getAge()); } session.close(); } Seeing the code, it is a very simple string.
We are all familiar with the previous ones, and we see the code after constructing the session:
Criteria criteria = session.createCriteria(User.class); criteria.add(Restrictions.eq("name","shun")); These two sentences of code are the key points. Let’s analyze what exactly does it mean?
In the first sentence, we obtain an object of the Criteria implementation class through session, and in the second sentence, we add a condition through the add method, and eq represents equality. Hibernate3 was previously implemented through Expression.eq. After 3, since Criteria was abandoned, we used the Restrictions class to implement it, which is the same as Expression. Let's look at the API and find that Expression inherits from Restrictions.
Going back to our two sentences above, after we finished these tasks, hibernate actually helped us construct similar
select * from user where name='shun'
Such a statement. (Here, the table corresponding to the User class in our mapping file is the user table, and the name attribute corresponds to the name field)
Restrictions also have many methods to help us construct SQL statements. It is easy to understand after checking the API.
Let's re-look at the above code. If we close the session, but we want to continue using this criteria, is that OK? Let's take a look.
After the above code, we re-traverse, adding:
List list2 = criteria.list(); Iterator iter2 = list.iterator(); while(iter.hasNext()) { User user = (User)iter.next(); System.out.println(user.getName()+":"+user.getAge()); } In order to distinguish the difference between the previous list and iter, we use another one here.
Run it and we get an exception:
org.hibernate.SessionException: Session is closed!
Reporting this exception means that the session has been closed. In many cases, we will report similar exceptions after closing the session and then performing operations related to saveOrUpdate, save, etc.
Hibernate3 takes into account our needs and implements a DetachedCriteria, which can exist independently of the Session.
Let's take a look at the example: (Entity is still above)
public static void main(String[] args) { Configuration cfg = new Configuration().configure(); SessionFactory sessionFactory = cfg.buildSessionFactory(); Session session = sessionFactory.openSession(); DetachedCriteria decriteria = DetachedCriteria.forClass(User.class); decriteria.add(Restrictions.eq("name","shun")); List list = decriteria.getExecutableCriteria(session).list(); Iterator iter = list.iterator(); while(iter.hasNext()) { User user = (User)iter.next(); System.out.println(user.getName()+":"+user.getAge()); } session.close(); Session session2 = sessionFactory.openSession(); List list2 = decriteria.getExecutableCriteria(session2).list(); Iterator iter2 = list2.iterator(); while(iter2.hasNext()) { User user = (User)iter2.next(); System.out.println(user.getName()+":"+user.getAge()); } } We see that after the session is closed, we can continue to use DetachedCriteria in another connection. We need to associate the current DetachedCriteria with a certain session through getExecutableCriteria (Session session).
Next, let's take a look at the combination of Subqueries class and DetachedCriteria:
public static void main(String[] args) { Configuration cfg = new Configuration().configure(); SessionFactory sessionFactory = cfg.buildSessionFactory(); Session session = sessionFactory.openSession(); DetachedCriteria decriteria = DetachedCriteria.forClass(User.class); decriteria.setProjection(Projections.avg("age")); Criteria criteria = session.createCriteria(User.class); criteria.add(Subqueries.propertyGt("age",decriteria)); List list = criteria.list(); Iterator iter = list.iterator(); while(iter.hasNext()) { User user = (User)iter.next(); System.out.println(user.getName()+":"+user.getAge()); } session.close(); } I guess the first code sentence you have questions:
decriteria.setProjection(Projections.avg("age")); This code refers to obtaining the average value of the age through decriteria. Then get the object with an age greater than the average value below.
Projections contains many encapsulation methods that implement SQL methods. You can take a look at the API.
Let’s learn about its slightly more advanced usage.
Just look at the code:
criteria.setFirstResult(10); criteria.setMaxResults(20);
Here we set the beginning record as Article 10, and then find 20 records from Article 10. According to this practice, we can implement the basic paging function.
Of course, we need sorting in many cases, and criteria also supports it:
criteria.addOrder(Order.desc("age")); Here, we can use the addOrder method directly, and obtain an Order object through Order.desc, which requires an attribute parameter. In fact, when we call addOrder, hibernate will help us generate order by age, such a statement.
How do we do this when we need to group it? This requires the groupProperty method of the Projections class we mentioned last time.
criteria.setProjection(Projections.groupProperty("age")); Here we group according to the age attribute, which is actually grouped through the field age corresponding to the age. Hibernate will automatically convert it into a statement like group by age.
There are many practical methods in Projections (note that this is only available after hibernate 3).