HQL-hibernate 管理
使用请注明出处:http://alex2012-c.j.overblog.com/
使用hibernate用java对数据库进行操作,通常在一个DAO中会有很多很多HQL的查询语句,长期下去语句越来越多,不断的修改,导致有些语句已经不用了,但是还是依然在代码中。对代码的维护造成了很大的麻烦。
在这里提出一个建议,可以把每一个语句建为一个class,这样非常有利于维护。建议文档,以airport IT application为例:
Context
When you are working with queries or DAO's, there are some guidelines to follow in order to avoid development issues.
Step-by-step guide
The following section summarizes the steps to be followed at each level in order to ensure a safe development.
I. Create a dedicated class for each Named Query
This class must be final. It is meant to do two things. First to store query name and second to declare a "createQuery" method.
You have to define the Query you want to use. This will ensure that query name is defined in only one location.
Final query class example
public static final String NAME = "Towing.findBySequenceNumber";
public static final String QUERY = "SELECT tow FROM com.amadeus.apt.fom.flights.domain.TowingMovementData tow"
+ " left join fetch tow.towingResources res"
+ " WHERE tow.ownerVisit.externalInfo.identifier = ?1 AND tow.ownerVisit.externalInfo.originator = ?2"
+ " AND tow.sequenceNumber = ?3 AND tow.ownerVisit.customerId = ?4";
You can define Query type you want to return. You have to define method parameter list and I strongly recommend that you should take care of the parameter order. Then you have to define query parameter order when creating the query. This will ensure a full control when creating the query.
Final query class example
public static TypedQuery<TowingMovementData> createQuery(EntityManager entityManager, int sequenceNumber,
String customerId, String externalId, String originator)
{
return entityManager.createNamedQuery(NAME, TowingMovementData.class).setParameter(1, externalId)
.setParameter(2, originator).setParameter(3, sequenceNumber).setParameter(4, customerId);
}
Final query class example
package com.amadeus.apt.fom.queries.type;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import com.amadeus.apt.fom.flights.domain.TowingMovementData;
public final class QueryTowingFindTowingBySequenceNumber {
public static final String NAME = "FindTowingBySequenceNumber";
public static final String QUERY = "SELECT tow FROM com.amadeus.apt.fom.flights.domain.TowingMovementData tow"
+ " left join fetch tow.towingResources res"
+ " WHERE tow.ownerVisit.externalInfo.identifier = ?1 AND tow.ownerVisit.externalInfo.originator = ?2"
+ " AND tow.sequenceNumber = ?3 AND tow.ownerVisit.customerId = ?4";
public static TypedQuery<TowingMovementData> createQuery(EntityManager entityManager, String externalId,
String originator, int sequenceNumber, String customerId)
{
return entityManager.createNamedQuery(NAME, TowingMovementData.class).setParameter(1, externalId)
.setParameter(2, originator).setParameter(3, sequenceNumber).setParameter(4, customerId);
}
}
II. Define the NamedQuery
Final query class example
@NamedQueries({
@NamedQuery(name = QueryTowingFindBySequenceNumber.NAME, query = "SELECT tow FROM com.amadeus.apt.fom.flights.domain.TowingMovementData tow "
Final query class example
@NamedQuery(name = QueryTowingFindBySequenceNumber.NAME, query = "SELECT tow FROM com.amadeus.apt.fom.flights.domain.TowingMovementData tow "
+ "left join fetch tow.towingResources res "
+ "WHERE tow.ownerVisit.externalInfo.identifier = ?1 AND tow.ownerVisit.externalInfo.originator = ?2 "
+ "AND tow.sequenceNumber = ?3 AND tow.ownerVisit.customerId = ?4")
III. Define the DAO
Like that, you are sure all parameter will be defined with correct type.
Final query class example
TypedQuery<TowingMovementData> query = QueryTowingFindBySequenceNumber.createQuery(entityManager,
visitExternalInfo.getIdentifier(), visitExternalInfo.getOriginator(), Integer.parseInt(sequenceNumber),
CustomerIdResolver.getCurrentCustomerId());
IV. Test
Unit Test for every query.