added basic JPAQL support (not tested yet)

This commit is contained in:
Timo Westkämper 2008-12-16 15:03:34 +00:00
parent 64077c475d
commit 4abb99d1e4
7 changed files with 187 additions and 123 deletions

View File

@ -6,11 +6,20 @@
package com.mysema.query.grammar;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.mysema.query.CascadingBoolean;
import com.mysema.query.JoinExpression;
import com.mysema.query.JoinType;
import com.mysema.query.QueryBase;
import com.mysema.query.grammar.types.Expr;
import com.mysema.query.grammar.types.Path;
import com.mysema.query.grammar.types.PathMetadata;
import com.mysema.query.grammar.types.Expr.Entity;
import com.mysema.query.hql.QueryModifiers;
/**
* HqlQueryBase is a base Query class for HQL
@ -18,24 +27,23 @@ import com.mysema.query.grammar.types.Expr.Entity;
* @author tiwe
* @version $Id$
*/
public class HqlQueryBase<A extends HqlQueryBase<A>> extends QueryBase<JoinMeta,A>{
private static final HqlOps OPS_DEFAULT = new HqlOps();
private final HqlOps ops;
public abstract class HqlQueryBase<A extends HqlQueryBase<A>> extends QueryBase<JoinMeta,A>{
private static final Logger logger = LoggerFactory
.getLogger(HqlQueryBase.class);
private List<Object> constants;
private String countRowsString, queryString;
protected Integer limit, offset;
private final HqlOps ops;
public HqlQueryBase(HqlOps ops){
this.ops = ops;
}
public HqlQueryBase(){
this.ops = OPS_DEFAULT;
}
private String buildQueryString(boolean forCountRow) {
if (joins.isEmpty()){
throw new IllegalArgumentException("No where clause given");
@ -46,22 +54,6 @@ public class HqlQueryBase<A extends HqlQueryBase<A>> extends QueryBase<JoinMeta,
return serializer.toString();
}
@SuppressWarnings("unchecked")
public A innerJoin(JoinMeta meta, Entity<?> o) {
joins.add(new JoinExpression<JoinMeta>(JoinType.INNERJOIN, o, meta));
return (A) this;
}
@SuppressWarnings("unchecked")
public A leftJoin(JoinMeta meta, Entity<?> o) {
joins.add(new JoinExpression<JoinMeta>(JoinType.LEFTJOIN, o, meta));
return (A) this;
}
public List<Object> getConstants() {
return constants;
}
@Override
protected void clear(){
super.clear();
@ -69,14 +61,63 @@ public class HqlQueryBase<A extends HqlQueryBase<A>> extends QueryBase<JoinMeta,
countRowsString = null;
}
@Override
public String toString(){
if (queryString == null){
queryString = buildQueryString(false);
}
return queryString;
protected Expr.Boolean createQBECondition(Path.Entity<?> entity,
Map<String, Object> map) {
CascadingBoolean expr = new CascadingBoolean();
for (Map.Entry<String, Object> entry : map.entrySet()){
PathMetadata<String> md = PathMetadata.forProperty(entity, entry.getKey());
Path.Simple<Object> path = new Path.Simple<Object>(Object.class, md);
if (entry.getValue() != null){
expr.and(path.eq(entry.getValue()));
}else{
expr.and(path.isnull());
}
}
return expr.self();
}
public A forExample(Path.Entity<?> entity, Map<String, Object> map) {
select(entity).from(entity);
try {
where(createQBECondition(entity,map));
return (A)this;
} catch (Exception e) {
String error = "Caught " + e.getClass().getName();
logger.error(error, e);
throw new RuntimeException(error, e);
}
}
public List<Object> getConstants() {
return constants;
}
@SuppressWarnings("unchecked")
public A innerJoin(JoinMeta meta, Entity<?> o) {
joins.add(new JoinExpression<JoinMeta>(JoinType.INNERJOIN, o, meta));
return (A) this;
}
@SuppressWarnings("unchecked")
public A leftJoin(JoinMeta meta, Entity<?> o) {
joins.add(new JoinExpression<JoinMeta>(JoinType.LEFTJOIN, o, meta));
return (A) this;
}
public A limit(int limit) {
this.limit = limit;
return (A)this;
}
public A offset(int offset) {
this.offset = offset;
return (A)this;
}
public A restrict(QueryModifiers mod) {
return limit(mod.getLimit()).offset(mod.getOffset());
}
public String toCountRowsString(){
if (countRowsString == null){
countRowsString = buildQueryString(true);
@ -84,4 +125,12 @@ public class HqlQueryBase<A extends HqlQueryBase<A>> extends QueryBase<JoinMeta,
return countRowsString;
}
@Override
public String toString(){
if (queryString == null){
queryString = buildQueryString(false);
}
return queryString;
}
}

View File

@ -5,8 +5,8 @@
*/
package com.mysema.query.hql;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.hibernate.Query;
import org.hibernate.Session;
@ -16,7 +16,6 @@ import org.slf4j.LoggerFactory;
import com.mysema.query.grammar.HqlOps;
import com.mysema.query.grammar.HqlQueryBase;
import com.mysema.query.grammar.types.Expr;
import com.mysema.query.grammar.types.Path;
/**
* HqlQuery provides a fluent statically typed interface for creating HQL queries.
@ -28,12 +27,14 @@ public class HqlQuery extends HqlQueryBase<HqlQuery>{
private static final Logger logger = LoggerFactory.getLogger(HqlQuery.class);
private static final HqlOps OPS_DEFAULT = new HqlOps();
private Integer limit, offset;
private final Session session;
public HqlQuery(Session session) {
this.session = session;
this(session, OPS_DEFAULT);
}
public HqlQuery(Session session, HqlOps ops) {
@ -43,30 +44,29 @@ public class HqlQuery extends HqlQueryBase<HqlQuery>{
private Query createQuery(String queryString, Integer limit, Integer offset) {
Query query = session.createQuery(queryString);
QueryUtil.setConstants(query, getConstants());
setConstants(query, getConstants());
if (limit != null) query.setMaxResults(limit);
if (offset != null) query.setFirstResult(offset);
return query;
}
public HqlQuery forExample(Path.Entity<?> entity, Map<String, Object> map) {
select(entity).from(entity);
try {
where(QueryUtil.createQBECondition(entity,map));
return this;
} catch (Exception e) {
String error = "Caught " + e.getClass().getName();
logger.error(error, e);
throw new RuntimeException(error, e);
public static void setConstants(Query query, List<?> constants){
for (int i=0; i < constants.size(); i++){
String key = "a"+(i+1);
Object val = constants.get(i);
if (val instanceof Collection<?>){
// NOTE : parameter types should be given explicitly
query.setParameterList(key,(Collection<?>)val);
}else if (val.getClass().isArray()){
// NOTE : parameter types should be given explicitly
query.setParameterList(key,(Object[])val);
}else{
// NOTE : parameter types should be given explicitly
query.setParameter(key,val);
}
}
}
public HqlQuery limit(int limit) {
this.limit = limit;
return this;
}
@SuppressWarnings("unchecked")
public <RT> List<RT> list(Expr<RT> expr){
select(expr);
@ -113,15 +113,6 @@ public class HqlQuery extends HqlQueryBase<HqlQuery>{
return (RT)query.uniqueResult();
}
public HqlQuery offset(int offset) {
this.offset = offset;
return this;
}
public HqlQuery restrict(QueryModifiers mod) {
this.limit = mod.getLimit();
this.offset = mod.getOffset();
return this;
}
}

View File

@ -0,0 +1,79 @@
/*
* Copyright (c) 2008 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.hql;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.mysema.query.grammar.HqlOps;
import com.mysema.query.grammar.HqlQueryBase;
import com.mysema.query.grammar.types.Expr;
/**
* JpaqlQuery provides
*
* @author tiwe
* @version $Id$
*/
public class JpaqlQuery extends HqlQueryBase<JpaqlQuery>{
private static final Logger logger = LoggerFactory.getLogger(JpaqlQuery.class);
private static final HqlOps OPS_DEFAULT = new HqlOps();
private final EntityManager em;
public JpaqlQuery(EntityManager em) {
this(em, OPS_DEFAULT);
}
public JpaqlQuery(EntityManager em, HqlOps ops) {
super(ops);
this.em = em;
}
private Query createQuery(String queryString, Integer limit, Integer offset) {
Query query = em.createQuery(queryString);
setConstants(query, getConstants());
if (limit != null) query.setMaxResults(limit);
if (offset != null) query.setFirstResult(offset);
return query;
}
public static void setConstants(Query query, List<Object> constants) {
for (int i=0; i < constants.size(); i++){
String key = "a"+(i+1);
Object val = constants.get(i);
query.setParameter(key,val);
}
}
@SuppressWarnings("unchecked")
public <RT> List<RT> list(Expr<RT> expr){
select(expr);
String queryString = toString();
logger.debug("query : {}", queryString);
Query query = createQuery(queryString, limit, offset);
return query.getResultList();
}
@SuppressWarnings("unchecked")
public List<Object[]> list(Expr<?> expr1, Expr<?> expr2, Expr<?>...rest){
select(expr1, expr2);
select(rest);
String queryString = toString();
logger.debug("query : {}", queryString);
Query query = createQuery(queryString, limit, offset);
return query.getResultList();
}
}

View File

@ -1,60 +0,0 @@
/*
* Copyright (c) 2008 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.hql;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.hibernate.Query;
import com.mysema.query.CascadingBoolean;
import com.mysema.query.grammar.types.Expr;
import com.mysema.query.grammar.types.Path;
import com.mysema.query.grammar.types.PathMetadata;
/**
* QueryUtil provides.
*
* @author tiwe
* @version $Id$
*/
public class QueryUtil {
public static void setConstants(Query query, List<?> constants){
for (int i=0; i < constants.size(); i++){
String key = "a"+(i+1);
Object val = constants.get(i);
if (val instanceof Collection<?>){
// NOTE : parameter types should be given explicitly
query.setParameterList(key,(Collection<?>)val);
}else if (val.getClass().isArray()){
// NOTE : parameter types should be given explicitly
query.setParameterList(key,(Object[])val);
}else{
// NOTE : parameter types should be given explicitly
query.setParameter(key,val);
}
}
}
public static Expr.Boolean createQBECondition(Path.Entity<?> entity,
Map<String, Object> map) {
CascadingBoolean expr = new CascadingBoolean();
for (Map.Entry<String, Object> entry : map.entrySet()){
PathMetadata<String> md = PathMetadata.forProperty(entity, entry.getKey());
Path.Simple<Object> path = new Path.Simple<Object>(Object.class, md);
if (entry.getValue() != null){
expr.and(path.eq(entry.getValue()));
}else{
expr.and(path.isnull());
}
}
return expr.self();
}
}

View File

@ -35,6 +35,8 @@ import com.mysema.query.grammar.types.Expr;
*/
public class FeaturesTest extends HqlQueryBase<FeaturesTest>{
public FeaturesTest(){super(new HqlOps());}
// AuditLog
QAuditLog log = new QAuditLog("log");

View File

@ -12,7 +12,6 @@ import org.junit.runner.RunWith;
import antlr.RecognitionException;
import antlr.TokenStreamException;
import com.mysema.query.hql.QueryUtil;
import com.mysema.query.util.CustomNamingStrategy;
import com.mysema.query.util.Hibernate;
import com.mysema.query.util.HibernateTestRunner;
@ -33,9 +32,10 @@ public class HqlIntegrationTest extends HqlParserTest{
@Override
protected void parse() throws RecognitionException, TokenStreamException{
System.out.println("query : " + toString().replace('\n', ' '));
// create Query and execute it
Query query = session.createQuery(toString());
QueryUtil.setConstants(query, getConstants());
HqlQuery.setConstants(query, getConstants());
try{
query.list();
}catch(Exception e){

View File

@ -5,6 +5,7 @@
*/
package com.mysema.query.hql;
import com.mysema.query.grammar.HqlOps;
import com.mysema.query.grammar.HqlQueryBase;
/**
@ -16,6 +17,8 @@ import com.mysema.query.grammar.HqlQueryBase;
public abstract class QueryBaseWithDomain<A extends QueryBaseWithDomain<A>>
extends HqlQueryBase<A>{
public QueryBaseWithDomain(){super(new HqlOps());}
QAccount account = new QAccount("account");
QAnimal an = new QAnimal("an");