1 Criteria query
In addition to providing powerful HQL queries, Hibernate also provides a query method called Criteria. HQL is very similar to SQL, which is characterized by flexibility and rich functions, but the disadvantage is that users must be familiar with the syntax of SQL, and when combining conditional queries, it is often necessary to assemble the Where condition and provide parameters for the condition. Criteria query is more object-oriented, better combined with Java code, and often more convenient when combining conditional queries. Of course, Criteria also has its disadvantages. Its readability is not as high as HQL, and its functions are not as many as HQL.
Hibernate officials often recommend using HQL to solve problems.
1.1 How to use Criteria .
Criteria criteria = sess.createCriteria(Category.class); // Create the query object Criteria of the persistent class
criteria.add( rule ); // Set query rule criterion
List list = query.list(); // Get query results
1.2 Rules - Criterion
Criterion is the query condition of Criteria. Criteria provides the add(Criterion criterion) method to add query conditions. The main implementations of the Criterion interface include: Example, Junction, and SimpleExpression. The actual use of Junction is its two subclasses, conjunction and disjunction, which use AND and OR operators to join query condition sets respectively.
Criterion instances can be provided through the Restrictions factory class, and Restrictions provides a large number of static methods, such as eq (equal), ge (greater than or equal to), between, etc. to create Criterion query conditions
(SimpleExpression instance). In addition, Restrictions also provides methods to create conjunction and
Disjunction instance, add query criteria to form a set of query criteria by adding (Criteria) method to the instance.
Static method conditions in Restrictions
meaning
Criteria
HQL
equal
Restrictions.eq()
=
not equal to
Restrictions.not(Exprission.eq())
<>
more than the
Restrictions.gt()
>
greater or equal to
Restrictions.ge()
>=
less than
Restrictions.lt()
<
less than or equal to
Restrictions.the()
<=
equal to empty
Restrictions.isnull()
is null
non empty
Restrictions.isNotNull()
is not null
fuzzy query
Restrictions.like()
like
logic and
Restrictions.and()
and
logic and
Restrictions.conjunction()
and
logical or
Restrictions.or()
or
logical or
Restrictions.disjunction()
or
logical NOT
Restrictions.not()
not
equal to a certain value
Restrictions.in()
in( )
not equal to any value
Restrictions.not(Restrictions.in())
not in()
interval
Restrictions.between()
between x and y
not in range
Restrictions.not(Restrictions..between())
not between x and y
(1) Add simple type attribute restrictions (query conditions) for Criteria.
Criteria criteria = sess.createCriteria(Movie.class);
criteria.add(Restrictions.like("title", "%狂%"));
List<Movie> list = criteria.list();
(2) Add association class attribute restrictions for Criteria.
Direct use of the add() method of criteria can only add simple type attribute restrictions and Id attribute restrictions for associated classes. If you want to add other attribute restrictions of the associated class (such as adding the name attribute restriction of the associated class Category for the Movie entity, you must re-createCriteria() and pass in the associated attribute name as a parameter, and then you can use the attribute of the associated class Category as the restriction condition .
Criteria criteria = sess.createCriteria(Movie.class);
criteria = criteria.createCriteria("category"); // re-execute createCriteria()
criteria.add(Restrictions.eq("name","动漫"));
List<Movie> list = criteria.list();
The above effects can also be achieved through the createAlias() method of criteria. Unlike createCriteria, it just gives an alias to the associated entity. After using createAlias, other attributes of the queried object can still be used as restrictions.
List<Movie> list = sess.createCriteria(Movie.class)
.createAlias("category", "c")
.add(Restrictions.eq("c.name", "战争"))
.add(Restrictions.like("title", "风%"))
.list();
1.3 Use an entity to declare multiple restrictions on equal or like rules at once—Example
Example is also a way to add Criteria rules. This way uses an object of the query entity class to declare multiple rules in one go. The creation of Example is different. Example itself provides a static method create(Object entity), and the parameter is an entity object (usually a mapped entity object in actual use) to create. Then you can set some filter conditions:
Example example = Example.create(entity)
.ignoreCase() // ignore case
.enableLike(MatchMode.ANYWHERE); // use like
criteria.add(example);
List list = criteria.list()
1.4 Implement sorting
You can use Criteria's addOrder(Order order) to control the order of query results. The Order object instance can be obtained through Order.asc("property name") and Order.desc("property name").
List cats = sess.createCriteria(Cat.class)
.add( Restrictions.like("name", "F%")
.addOrder( Order.asc("name") )
.addOrder( Order.desc("age") )
.list() ;
1.5 Realize pagination
The Criteria object, like the Query object, can implement pagination through the setFirstResult() and setMaxResults() methods
1.6 Projection Projection—implementing aggregation functions and grouping
Criteria can implement aggregation statistics and grouping through the setProjection(Projection projection) method.
Projection mainly enables Criteria to perform statistical queries and realize grouping. Projection is mainly realized by SimpleProjection and ProjectionList. The creation of SimpleProjection and ProjectionList is done through the built-in static method of Projections, such as the provided avg(), count(), max(), min(), sum() can make it easy for developers to set a certain field Perform statistical queries. The groupProperty() method of Projections can also group results.
ProjectionList projectionList = Projections.projectionList();
Projection prjCount = Projections.count("id");
projectionList.add(prjCount);
projectionList.add(Projections.groupProperty("category"));
criteria.setProjection(projectionList);
List<Object[]> list = criteria.list();
1.7 DetachedCriteria
The DetachedCriteria class is similar to the Criteria interface. You can use the methods mentioned above (Criterion and Projection) to set the query conditions, but the creation methods of the two are different: the Criteria must be created by the Session object, and the DetachedCriteria does not need the Session object when it is created. Therefore, DetachedCriteria can be constructed outside the Session scope, and a series of complex conditions can be added, and then passed to the Dao method with the Session environment for execution. The emergence of DetachedCriteria realizes the separation of "conditional construction" and "query execution".
public static void main(String[] args) { DetachedCriteria cri = DetachedCriteria.forClass(Movie.class); cri.add(Restrictions.eq("category.id", 1)); List<Movie> list = get(cri); for(Movie m: list){ System.out.println(m.getTitle()+","+m.getCategory().getName()); } } static List get(DetachedCriteria cri){ Session sess = null; try { sess = HibernateUtil.getSession(); return cri.getExecutableCriteria(sess).list(); } finally { if(sess!=null) sess.close(); } }
2 Native SQL operations
2.1 Native SQL query
Although HQL is powerful enough, because different database systems have different extensions to standard SQL (such as T-SQL of SQL Server, PL/SQL of Oracle, and dialect "Dialect" in Hibernate), HQL cannot be completed 100%. What we can achieve in native SQL. Moreover, HQL must eventually be converted to SQL for execution. This automatic conversion is always unsatisfactory. After converting overly complex HQL to SQL, the execution efficiency may be low. For this reason, Hibernate also reserves our right to directly use the local SQL of the database, and we can directly write SQL statements to control the query results. It is worth noting that once native SQL is used, if you switch to another database system for the data access layer in the future, you will need to modify these native SQL to conform to the new database dialect.
(1) A native SQL query that returns an array of primitive types Object.
The usage of local SQL query and HQL query is basically similar, the difference is that SQL query needs to use the createSQLQuery(String sql) method of Session, and the returned query object is of type SQLQuery.
String sql = "select m.Title, c.name from Movie m inner join Category c on m.CategoryId=c.Id where c.name=:cname";
SQLQuery query = sess.createSQLQuery(sql);
query.setString("cname", " war ");
List<Object[]> list = query.list();
(2) A native SQL query that directly returns the mapped entity.
We often hope to return persistent entity objects through local SQL queries. If the above method is used, the result returned by Hibernate is an array of basic types of Object. To obtain entities, it is necessary to rebuild entity objects and set properties. In order to simplify our work, the SQLQuery interface object directly provides the addEntity(String alias, Class entityClass) method, which can help us directly fill the SQL result into the entity object and return the entity object array and list.
String sql = "select m.*, c.* from Movie m inner join Category c on m.CategoryId=c.Id where c.name=:cname"; SQLQuery query = sess.createSQLQuery(sql); query.addEntity("m",Movie.class); query.addEntity("c",Category.class); query.setString("cname", "战争"); List<Object[]> list = query.list(); for(Object[] arr : list){ Category c = (Category)arr[1]; Movie m = (Movie)arr[0]; System.out.println( c.getName() + "," + m.getTitle()); }
2.2 Native JDBC operation
If you want to use native JDBC to add, delete, and modify more flexibly, you can use the doWork method provided by the Session object to write an internal anonymous class through the Work interface. We can call the underlying API of JDBC to implement batch operations.
The Session.doWork() method is executed as shown below.
Session session=HibernateUtil.openSession(); Transaction transaction=session.beginTransaction(); session.doWork(new Work() { public void execute(Connection conn) throws SQLException { //这里是SQL非HQL String sql = "delete from Movie where categoryId=?"; PreparedStatement stmt = conn.prepareStatement(sql); stmt.setInt(1, 2); stmt.executeUpdate(); } }); transaction.commit();