下面列出了怎么用org.hibernate.annotations.QueryHints的API类实例代码及写法,或者点击链接到github查看源代码。
@Override
public UserCredentials getUserCredentialsByUsername( String username )
{
if ( username == null )
{
return null;
}
String hql = "from UserCredentials uc where uc.username = :username";
TypedQuery<UserCredentials> typedQuery = sessionFactory.getCurrentSession().createQuery( hql, UserCredentials.class );
typedQuery.setParameter( "username", username );
typedQuery.setHint( QueryHints.CACHEABLE, true );
return QueryUtils.getSingleResult( typedQuery );
}
@Override
@Transactional(readOnly = true)
public Post findByDetailsCreatedByAndTitle(String userName, String title) {
return doInJPA(entityManager -> {
List<Post> _post = entityManager.createQuery(
"SELECT p FROM Post p LEFT JOIN FETCH p.comments JOIN FETCH p.details d where d.createdBy = :user and p.title = :title ",
Post.class).setParameter("user", userName).setParameter("title", title)
.setHint(QueryHints.PASS_DISTINCT_THROUGH, false).getResultList();
return entityManager.createQuery(
"SELECT distinct p FROM Post p LEFT JOIN FETCH p.tags pt LEFT JOIN FETCH pt.tag JOIN p.details where p in :posts",
Post.class).setParameter("posts", _post).setHint(QueryHints.PASS_DISTINCT_THROUGH, false)
.getSingleResult();
});
}
public <T> T getCacheableEntity(
Class<T> entityClass,
String identifierName,
Object identifierValue) {
return doInJPA(entityManager -> {
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<T> criteria = builder.createQuery(entityClass);
Root<T> fromClause = criteria.from(entityClass);
criteria.where(builder.equal(fromClause.get(identifierName), identifierValue));
return entityManager
.createQuery(criteria)
.setHint(QueryHints.CACHEABLE, true)
.getSingleResult();
});
}
public CacheMode getCacheMode(String query) {
String hitName = QueryHints.CACHE_MODE;
String value =(String) hintsMap.get( hitName );
if ( value == null ) {
return null;
}
try {
return CacheMode.interpretExternalSetting( value );
}
catch ( MappingException e ) {
throw new AnnotationException( "Unknown CacheMode in hint: " + query + ":" + hitName, e );
}
}
public FlushMode getFlushMode(String query) {
String hitName = QueryHints.FLUSH_MODE;
String value =(String) hintsMap.get( hitName );
if ( value == null ) {
return null;
}
try {
return FlushMode.interpretExternalSetting( value );
}
catch ( MappingException e ) {
throw new AnnotationException( "Unknown FlushMode in hint: " + query + ":" + hitName, e );
}
}
public LockMode getLockMode(String query) {
String hitName = QueryHints.NATIVE_LOCKMODE;
String value =(String) hintsMap.get( hitName );
if ( value == null ) {
return null;
}
try {
return LockMode.fromExternalForm( value );
}
catch ( MappingException e ) {
throw new AnnotationException( "Unknown LockMode in hint: " + query + ":" + hitName, e );
}
}
public Integer getTimeout(String queryName) {
Integer timeout = getInteger( queryName, QueryHints.TIMEOUT_JPA );
if ( timeout != null ) {
// convert milliseconds to seconds
timeout = (int) Math.round( timeout.doubleValue() / 1000.0 );
}
else {
// timeout is already in seconds
timeout = getInteger( queryName, QueryHints.TIMEOUT_HIBERNATE );
}
return timeout;
}
public LockOptions determineLockOptions(NamedQuery namedQueryAnnotation) {
LockModeType lockModeType = namedQueryAnnotation.lockMode();
Integer lockTimeoutHint = getInteger( namedQueryAnnotation.name(), "javax.persistence.lock.timeout" );
Boolean followOnLocking = getBoolean( namedQueryAnnotation.name(), QueryHints.FOLLOW_ON_LOCKING );
return determineLockOptions(lockModeType, lockTimeoutHint, followOnLocking);
}
public static void bindQuery(
NamedQuery queryAnn,
MetadataBuildingContext context,
boolean isDefault) {
if ( queryAnn == null ) return;
if ( BinderHelper.isEmptyAnnotationValue( queryAnn.name() ) ) {
throw new AnnotationException( "A named query must have a name when used in class or package level" );
}
//EJBQL Query
QueryHintDefinition hints = new QueryHintDefinition( queryAnn.hints() );
String queryName = queryAnn.query();
NamedQueryDefinition queryDefinition = new NamedQueryDefinitionBuilder( queryAnn.name() )
.setLockOptions( hints.determineLockOptions( queryAnn ) )
.setQuery( queryName )
.setCacheable( hints.getBoolean( queryName, QueryHints.CACHEABLE ) )
.setCacheRegion( hints.getString( queryName, QueryHints.CACHE_REGION ) )
.setTimeout( hints.getTimeout( queryName ) )
.setFetchSize( hints.getInteger( queryName, QueryHints.FETCH_SIZE ) )
.setFlushMode( hints.getFlushMode( queryName ) )
.setCacheMode( hints.getCacheMode( queryName ) )
.setReadOnly( hints.getBoolean( queryName, QueryHints.READ_ONLY ) )
.setComment( hints.getString( queryName, QueryHints.COMMENT ) )
.setParameterTypes( null )
.createNamedQueryDefinition();
if ( isDefault ) {
context.getMetadataCollector().addDefaultQuery( queryDefinition );
}
else {
context.getMetadataCollector().addNamedQuery( queryDefinition );
}
if ( LOG.isDebugEnabled() ) {
LOG.debugf( "Binding named query: %s => %s", queryDefinition.getName(), queryDefinition.getQueryString() );
}
}
@Override
public Collection<MCRCategLinkReference> getReferences(String type) {
EntityManager em = MCREntityManagerProvider.getCurrentEntityManager();
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<MCRCategLinkReference> query = cb.createQuery(MCRCategLinkReference.class);
Root<MCRCategoryLinkImpl> li = query.from(LINK_CLASS);
Path<MCRCategLinkReference> objectReferencePath = li.get(MCRCategoryLinkImpl_.objectReference);
return em
.createQuery(
query.select(objectReferencePath)
.where(cb.equal(objectReferencePath.get(MCRCategLinkReference_.type), type)))
.setHint(QueryHints.READ_ONLY, "true")
.getResultList();
}
/**
* Creates a Query for given HQL query string. Return type is casted
* to generic type T of the Store class.
*
* @param hql the HQL query.
* @return a Query instance with return type is the object type T of the store class
*/
@SuppressWarnings( "unchecked" )
protected final Query<T> getQuery( String hql )
{
return getSession()
.createQuery( hql )
.setCacheable( cacheable ).setHint( QueryHints.CACHEABLE, cacheable );
}
/**
* Creates a Query for given HQL query string. Must specify the return
* type of the Query variable.
*
* @param hql the HQL query.
* @return a Query instance with return type specified in the Query<Y>
*/
@SuppressWarnings( "unchecked" )
protected final <V> Query<V> getTypedQuery( String hql )
{
return getSession()
.createQuery( hql )
.setCacheable( cacheable ).setHint( QueryHints.CACHEABLE, cacheable );
}
/**
* Get executable Typed Query from Criteria Query.
* Apply cache if needed.
*
* @return executable TypedQuery
*/
private TypedQuery<T> getExecutableTypedQuery(CriteriaQuery<T> criteriaQuery)
{
return getSession()
.createQuery( criteriaQuery )
.setCacheable( cacheable ).setHint( QueryHints.CACHEABLE, cacheable );
}
/**
* Get executable TypedQuery from JpaQueryParameter.
*
* @return executable TypedQuery
*/
protected final TypedQuery<T> getTypedQuery( CriteriaBuilder builder, JpaQueryParameters<T> parameters )
{
List<Function<Root<T>, Predicate>> predicateProviders = parameters.getPredicates();
List<Function<Root<T>, Order>> orderProviders = parameters.getOrders();
preProcessPredicates( builder, predicateProviders );
CriteriaQuery<T> query = builder.createQuery( getClazz() );
Root<T> root = query.from( getClazz() );
query.select( root );
if ( !predicateProviders.isEmpty() )
{
List<Predicate> predicates = predicateProviders.stream().map( t -> t.apply( root ) ).collect( Collectors.toList() );
query.where( predicates.toArray( new Predicate[0] ) );
}
if ( !orderProviders.isEmpty() )
{
List<Order> orders = orderProviders.stream().map( o -> o.apply( root ) ).collect( Collectors.toList() );
query.orderBy( orders );
}
TypedQuery<T> typedQuery = getExecutableTypedQuery( query );
if ( parameters.hasFirstResult() )
{
typedQuery.setFirstResult( parameters.getFirstResult() );
}
if ( parameters.hasMaxResult() )
{
typedQuery.setMaxResults( parameters.getMaxResults() );
}
return typedQuery
.setHint( QueryHints.CACHEABLE, parameters.isCacheable( cacheable ) );
}
/**
* Count number of objects based on given parameters
*
* @param parameters JpaQueryParameters
* @return number of objects
*/
protected final Long getCount( CriteriaBuilder builder, JpaQueryParameters<T> parameters )
{
CriteriaQuery<Long> query = builder.createQuery( Long.class );
Root<T> root = query.from( getClazz() );
List<Function<Root<T>, Predicate>> predicateProviders = parameters.getPredicates();
List<Function<Root<T>, Expression<Long>>> countExpressions = parameters.getCountExpressions();
if ( !countExpressions.isEmpty() )
{
if ( countExpressions.size() > 1 )
{
query.multiselect( countExpressions.stream().map( c -> c.apply( root ) ).collect( Collectors.toList() ) );
}
else
{
query.select( countExpressions.get( 0 ).apply( root ) );
}
}
else
{
query.select( parameters.isUseDistinct() ? builder.countDistinct( root ) : builder.count( root ) );
}
if ( !predicateProviders.isEmpty() )
{
List<Predicate> predicates = predicateProviders.stream().map( t -> t.apply( root ) ).collect( Collectors.toList() );
query.where( predicates.toArray( new Predicate[0] ) );
}
return getSession().createQuery( query )
.setHint( QueryHints.CACHEABLE, parameters.isCacheable( cacheable ) )
.getSingleResult();
}
/**
* Creates a SqlQuery.
*
* @param sql the SQL query String.
* @return a NativeQuery<T> instance.
*/
@SuppressWarnings( "unchecked" )
protected final NativeQuery<T> getSqlQuery( String sql )
{
return getSession().createNativeQuery( sql )
.setCacheable( cacheable ).setHint( QueryHints.CACHEABLE, cacheable );
}
@Test
public void testReadOnly() {
doInJPA(entityManager -> {
List<Post> posts = entityManager
.createQuery(
"select p " +
"from Post p", Post.class)
.setHint(QueryHints.READ_ONLY, true)
.getResultList();
});
}
protected void setTimeout(JPAQuery<?> query, int timeoutMs) {
if (timeoutMs > 0) {
query.setHint(QueryHints.TIMEOUT_JPA, timeoutMs);
}
}
/**
* Creates a untyped SqlQuery.
*
* @param sql the SQL query String.
* @return a NativeQuery<T> instance.
*/
protected final NativeQuery<?> getUntypedSqlQuery( String sql )
{
return getSession().createNativeQuery( sql )
.setCacheable( cacheable ).setHint( QueryHints.CACHEABLE, cacheable );
}