All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.tri.persistence.jpql.QueryBuilder Maven / Gradle / Ivy

Go to download

Create dynamic JPQL queries with a fluent API without cluttering code with String concatenations

The newest version!
package com.tri.persistence.jpql;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.persistence.TemporalType;
import javax.persistence.TypedQuery;

import com.tri.persistence.jpql.utils.StringUtils;

/**
 * 

* {@literal JPQL} query builder for building complex dynamic database queries * and statements in {@literal JPQL} without getting cluttered with complex * String building-If-Else fragments. The builder has a fluent {@literal API} to * provide for more readable code. It is just an query/statement string builder * and has no knowledge of any {@literal SQL} semantic. *

*

* Usage *

*

* Simple query: *

* *
 * QueryBuilder builder = new QueryBuilder();
 * builder.select.add("e");
 * builder.from.add("Entity e");
 * builder.where.add("e.fieldname=:fieldname");
 * builder.setParameter("fieldname", "xyz");
 * TypedQuery<Long> query = builder.createQuery(entityManager, Entity.class)
 * return query.getResultList();
 * 
*

* Same query using fluent api: *

* *
 * QueryBuilder builder = new QueryBuilder().select.add("e");
 * 	.from.add("Entity e").where.add("e.fieldname1=:fieldname2")
 * 	.add("e.fieldname2=:fieldname2");
 * return builder.setParameter("fieldname1", "xyz")
 * 	.setParameter("fieldname2", "xyz")
 * 	.createQuery(entityManager, Entity.class).getResultList();
 * 
* *

* A dynamic query: *

* *
 * String searchCriteria = "xyz";
 * QueryBuilder builder = QueryBuilder().select.add("e");
 * 	.from.add("Entity e").where.add("e.fieldname1=:fieldname2");
 * builder.setParameter("fieldname1", "xyz");
 * if (searchCriteria != null) {
 * 	builder.where.add("e.fieldname2=:fieldName2")
 * 	builder.setParameter("fieldname2", searchCriteria);
 * }
 * return builder.createQuery(entityManager, Entity.class).getResultList();
 * 
*

* Also check the helper methods of class {@link WhereItems}, as these methods * are most needed to build the Where Clause of an {@literal SQL} statement. *

* * @author [email protected] */ public class QueryBuilder implements Cloneable { public SelectQueryClause select; public StatementItem update; public StatementItem deleteFrom; public QueryClause set; public QueryClause from; public WhereAnd where; public QueryClause order; public QueryClause group; private List> parameters; private QueryBuilder parent; /** * Constructor */ public QueryBuilder() { select = new SelectQueryClause(this); update = new StatementItem(this); deleteFrom = new StatementItem(this); set = new QueryClause(this); from = new QueryClause(this); where = new WhereAnd(this); order = new QueryClause(this); group = new QueryClause(this); parameters = new ArrayList>(); } @Override public Object clone() throws CloneNotSupportedException { final QueryBuilder clone = (QueryBuilder) super.clone(); // TODO: Evaluate: Implement: null-out parent // deep copy clone.select = (SelectQueryClause) select.clone(); clone.select.setBuilder(this); clone.update = (StatementItem) update.clone(); clone.update.setBuilder(this); clone.deleteFrom = (StatementItem) deleteFrom.clone(); clone.deleteFrom.setBuilder(this); clone.set = (QueryClause) set.clone(); clone.set.setBuilder(this); clone.from = (QueryClause) from.clone(); clone.from.setBuilder(this); clone.where = (WhereAnd) where.clone(); clone.where.setBuilder(this); clone.order = (QueryClause) order.clone(); clone.order.setBuilder(this); clone.group = (QueryClause) group.clone(); clone.group.setBuilder(this); clone.parameters = new ArrayList>(parameters); return clone; } protected void setParent(final QueryBuilder parent) { this.parent = parent; } /** * Returns the parent builder. * * @return parent builder or null if there is none */ public QueryBuilder parent() { return parent; } /** * Returns a JPA Query with all previously specified parameters added. * * @param manager * JPA EntityManager * @return JPA Query */ public Query createQuery(final EntityManager manager) { if (manager == null) { throw new NullPointerException("Entity Manager required"); } final Query query = manager.createQuery(render()); for (Parameter parameter : parameters) { parameter.apply(query); } return query; } /** * Returns a JPA TypedQuery with all previously specified parameters added. * * @param manager * JPA EntityManager * @param type * the type of the query result * @return JPA Query */ public TypedQuery createQuery(final EntityManager manager, Class type) { if (manager == null) { throw new NullPointerException("Entity Manager required"); } TypedQuery result = manager.createQuery(render(), type); for (Parameter parameter : parameters) { parameter.apply(result); } return result; } /** * Adds the given parameter to the builder. All parameters will added to the * JPA Query returned by a call to {@link #createQuery(EntityManager)} or * {@link #createQuery(EntityManager, Class)}. * * @param name * parameter name * @param value * parameter value * @param temporalType * temporal type * @return builder reference, fluent api support */ public QueryBuilder setParameter(final String name, final Calendar value, TemporalType temporalType) { return setParameter(new ParameterCalendar(name, value, temporalType)); } /** * Adds the given parameter to the builder. All parameters will added to the * JPA Query returned by a call to {@link #createQuery(EntityManager)} or * {@link #createQuery(EntityManager, Class)}. * * @param name * parameter name * @param value * parameter value * @param temporalType * temporal type * @return builder reference, fluent api support */ public QueryBuilder setParameter(final String name, final Date value, final TemporalType temporalType) { return setParameter(new ParameterDate(name, value, temporalType)); } /** * Adds the given parameter to the builder. All parameters will added to the * JPA Query returned by a call to {@link #createQuery(EntityManager)} or * {@link #createQuery(EntityManager, Class)}. * * @param name * parameter name * @param value * parameter value * @return builder reference, fluent api support */ public QueryBuilder setParameter(final String name, final Object value) { return setParameter(new ParameterObject(name, value)); } /** * Adds given parameter to the builder. All parameters will added to the JPA * Query returned by a call to {@link #createQuery(EntityManager)} or * {@link #createQuery(EntityManager, Class)}. * * @param parameter * parameter to add * @return builder reference, fluent api support */ public QueryBuilder setParameter(final Parameter parameter) { if (parent == null) { parameters.add(parameter); } else { parent.setParameter(parameter); } return this; } /** * Adds all given parameters to the builder. All parameters will added to * the JPA Query returned by a call to {@link #createQuery(EntityManager)} * or {@link #createQuery(EntityManager, Class)}. * * @param parameters * parameters to add * @return builder reference, fluent api support */ public QueryBuilder setParameters(final List> parameters) { if (parent == null) { this.parameters.addAll(parameters); } else { parent.setParameters(parameters); } return this; } /** * Returns all previously set parameters * * @return list of parameters */ public List> getParameters() { return parameters; } /** * Renders this object as JPQL query string. * * @return the query as string */ public String render() { StringBuilder query = new StringBuilder(); if (!select.isEmpty()) { query.append("SELECT "); query.append(StringUtils.join(select.items)); } if (!deleteFrom.isEmpty()) { query.append("DELETE FROM "); query.append(deleteFrom.item); } if (!update.isEmpty()) { query.append("UPDATE "); query.append(update.item); if (!set.isEmpty()) { query.append(" SET "); query.append(StringUtils.join(set.items)); } } if (!from.isEmpty()) { query.append(" FROM "); query.append(StringUtils.join(from.items)); } if (!where.isEmpty()) { query.append(" WHERE "); query.append(where.render()); } if (!group.isEmpty()) { query.append(" GROUP BY "); query.append(StringUtils.join(group.items)); } if (order.isEmpty() == false) { query.append(" ORDER BY "); query.append(StringUtils.join(order.items)); } return query.toString(); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy