Java tutorial
/* * Copyright 2009 The Corner Team. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package corner.orm.gae.impl; import java.util.Iterator; import java.util.regex.Pattern; import javax.persistence.EntityManager; import javax.persistence.PersistenceException; import javax.persistence.Query; import org.apache.tapestry5.ioc.services.TypeCoercer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.orm.jpa.JpaCallback; import org.springframework.orm.jpa.JpaTemplate; import corner.orm.EntityConstants; import corner.orm.hibernate.impl.PaginatedEntityService; import corner.orm.model.PaginationList; import corner.orm.model.PaginationOptions; /** * paginated jpa entity service * @author <a href="mailto:jun.tsai@gmail.com">Jun Tsai</a> * @version $Revision$ * @since 0.1 */ public class PaginatedJapEntityService { private Logger logger = LoggerFactory.getLogger(PaginatedEntityService.class); private TypeCoercer typeCoercer; private JpaTemplate template; public PaginatedJapEntityService(final JpaTemplate template, final TypeCoercer typeCoercer) { this.template = template; this.typeCoercer = typeCoercer; } /** * * magic paginate method. * eg: * <code> * options.setPage(2); * * * paginate(Member.class,new Object[]{"email=?","asdf@asdf.net"},"userName desc",options) * paginate(Member.class,"email='asdf@asdf.net'","userName desc",options) * * List conditions = new ArrayList(); * conditions.add("userName=? and password=?"); * conditions.add(userName); * conditions.add(password); * paginate(Member.class,conditions,"userName desc",options) * * </code> * Magic conditions query criteria * @param persistClass persistence class * @param conditions query criteria * @param order order by sql * @param options pagination options. * @return include result and totalRecord. */ public PaginationList paginate(final Class<?> persistClass, final Object conditions, final String order, final PaginationOptions options) { final Iterable con = typeCoercer.coerce(conditions, Iterable.class); return (PaginationList) this.template.execute(new JpaCallback() { @Override public Object doInJpa(EntityManager entityManager) throws PersistenceException { final Iterator it = con == null ? null : con.iterator(); String conditionJPQL = buildConditionJPQL(persistClass, it).toString(); //query list final StringBuffer queryJPQL = new StringBuffer(conditionJPQL); appendOrder(queryJPQL, order); queryJPQL.insert(0, "select root." + EntityConstants.ID_PROPERTY_NAME); Query query = entityManager.createQuery(queryJPQL.toString()); //count query final StringBuffer countJPQL = new StringBuffer(conditionJPQL); countJPQL.insert(0, "select count(root) "); Query countQuery = entityManager.createQuery(countJPQL.toString()); if (it != null) { int i = 0; while (it.hasNext()) { i++; Object obj = it.next(); query.setParameter(String.valueOf(i), obj); countQuery.setParameter(String.valueOf(i), obj); } } //get perpage int perPage = options.getPerPage(); int page = options.getPage(); if (page < 1) { page = 1; } query.setFirstResult((page - 1) * perPage); query.setMaxResults(perPage); PaginationList list = new PaginationList(query.getResultList().iterator(), options); //query total record number //beacause jpa rowCount is integer type.so convert as long options.setTotalRecord(Long.parseLong(countQuery.getSingleResult().toString())); return list; } }); } public Iterator find(final Class<?> persistClass, final Object conditions, final String order, final int start, final int offset) { return (Iterator) this.template.execute(new JpaCallback() { @Override public Object doInJpa(EntityManager entityManager) throws PersistenceException { Iterable con = typeCoercer.coerce(conditions, Iterable.class); final Iterator it = con == null ? null : con.iterator(); final StringBuffer sb = buildConditionJPQL(persistClass, it); appendOrder(sb, order); sb.insert(0, "select root." + EntityConstants.ID_PROPERTY_NAME); Query query = entityManager.createQuery(sb.toString()); if (it != null) { int i = 0; while (it.hasNext()) { query.setParameter(String.valueOf(++i), it.next()); } } query.setFirstResult(start); query.setMaxResults(offset); return query.getResultList().iterator(); } }); } void appendOrder(StringBuffer sb, String order) { if (order != null) { if (!Pattern.compile("^order\\s+").matcher(order.trim()).find()) { //no order keywords sb.append(" order by"); } sb.append(" ").append(order.trim()); } } public long count(final Class<?> persistClass, final Object conditions) { return (Long) this.template.execute(new JpaCallback() { @Override public Object doInJpa(EntityManager entityManager) throws PersistenceException { Iterable con = typeCoercer.coerce(conditions, Iterable.class); final Iterator it = con == null ? null : con.iterator(); final StringBuffer sb = buildConditionJPQL(persistClass, it); sb.insert(0, "select count(root) "); Query query = entityManager.createQuery(sb.toString()); if (it != null) { int i = 0; while (it.hasNext()) { query.setParameter(i++, it.next()); } } return Long.parseLong(query.getSingleResult().toString()); } }); } private StringBuffer buildConditionJPQL(Class<?> persistClass, Iterator conditions) { final StringBuffer sb = new StringBuffer(); sb.append(" from ").append(persistClass.getName()).append(" as root "); if (conditions != null && conditions.hasNext()) { String where = String.valueOf(conditions.next()).trim(); if (!Pattern.compile("^where\\s+").matcher(where).find()) {//no where keywords sb.append(" where"); } sb.append(" ").append(where); } if (logger.isDebugEnabled()) { logger.debug("construct JPQL:[" + sb.toString() + "]"); } return sb; } }