Java tutorial
/* * Computoser is a music-composition algorithm and a website to present the results * Copyright (C) 2012-2014 Bozhidar Bozhanov * * Computoser is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * Computoser is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Computoser. If not, see <http://www.gnu.org/licenses/>. */ package com.music.dao; import java.util.Collection; import java.util.Collections; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.LockModeType; import javax.persistence.PersistenceContext; import javax.persistence.Query; import javax.persistence.TypedQuery; import org.springframework.stereotype.Repository; @Repository("dao") public class Dao { @PersistenceContext private EntityManager entityManager; public <T> void delete(Class<?> clazz, T id) { delete(getById(clazz, id)); } public void delete(Object object) { object = entityManager.merge(object); entityManager.remove(object); } public <T> T getById(Class<T> clazz, Object id) { return getById(clazz, id, false); } public <T> T getById(Class<T> clazz, Object id, boolean lock) { if (lock) { return entityManager.find(clazz, id, LockModeType.PESSIMISTIC_WRITE); } else { return entityManager.find(clazz, id); } } public <T> T persist(T e) { // if e is already in the persistence context (session), no action is // taken, except for cascades // if e is detached, a copy (e') is returned, which is attached // (managed) // if e is transient (new instance), it is saved and a persistent (and // managed) copy is returned e = entityManager.merge(e); return e; } public <T> T getByPropertyValue(Class<T> clazz, String propertyName, Object propertyValue) { String dotlessPropertyName = propertyName.replace(".", ""); List<T> result = findByQuery(new QueryDetails() .setQuery("SELECT ob FROM " + clazz.getName() + " ob WHERE " + propertyName + "=:" + dotlessPropertyName) .setParamNames(new String[] { dotlessPropertyName }) .setParamValues(new Object[] { propertyValue })); return getResult(result); } public <T> List<T> getListByPropertyValue(Class<T> clazz, String propertyName, Object propertyValue) { String dotlessPropertyName = propertyName.replace(".", ""); List<T> result = findByQuery(new QueryDetails() .setQuery("SELECT o FROM " + clazz.getName() + " o WHERE " + propertyName + "=:" + dotlessPropertyName) .setParamNames(new String[] { dotlessPropertyName }) .setParamValues(new Object[] { propertyValue })); return result; } protected int executeQuery(String query, String[] names, Object[] args) { if (names == null) { names = new String[] {}; } if (args == null) { args = new Object[] {}; } Query q = entityManager.createQuery(query); for (int i = 0; i < names.length; i++) { q.setParameter(names[i], args[i]); } return q.executeUpdate(); } @SuppressWarnings("unchecked") protected <T> List<T> findByQuery(QueryDetails details) { Query q = null; if (details.getQueryName() != null) { q = entityManager.createNamedQuery(details.getQueryName()); } else if (details.getQuery() != null) { q = entityManager.createQuery(details.getQuery()); } else { throw new IllegalArgumentException("Either query or query name must be set"); } for (int i = 0; i < details.getParamNames().length; i++) { q.setParameter(details.getParamNames()[i], details.getParamValues()[i]); } if (details.getStart() > -1) { q.setFirstResult(details.getStart()); } if (details.getCount() > -1) { q.setMaxResults(details.getCount()); } if (details.isCacheable()) { setCacheable(q); } return q.getResultList(); } protected void setCacheable(Query query) { //TODO consider if every query should be cached (hibernate advises against it) query.setHint("org.hibernate.cacheable", Boolean.TRUE); } protected Object getDelegate() { return entityManager.getDelegate(); } protected int executeNamedQuery(String name) { return entityManager.createNamedQuery(name).executeUpdate(); } protected <T> T getResult(List<T> result) { if (!result.isEmpty()) { return result.get(0); } return null; } public <T> List<T> listOrdered(Class<T> clazz, String orderField) { return findByQuery(new QueryDetails().setQuery("from " + clazz.getName() + " ORDER BY " + orderField)); } protected EntityManager getEntityManager() { return entityManager; } public <T> List<T> getPagedListByPropertyValue(Class<T> clazz, String propertyName, Object propertyValue, int page, int pageSize) { String queryString = "SELECT o FROM " + clazz.getName() + " o WHERE " + propertyName + "=:" + propertyName; TypedQuery<T> query = getEntityManager().createQuery(queryString, clazz); query.setFirstResult(page * pageSize); query.setMaxResults(pageSize); query.setParameter(propertyName, propertyValue); return query.getResultList(); } public <T> List<T> getOrderedListByPropertyValue(Class<T> clazz, String propertyName, Object propertyValue, String orderField) { List<T> result = findByQuery(new QueryDetails() .setQuery("SELECT o FROM " + clazz.getName() + " o WHERE " + propertyName + "=:" + propertyName + " ORDER BY " + orderField) .setParamNames(new String[] { propertyName }).setParamValues(new Object[] { propertyValue })); return result; } public void lock(Object entity) { if (entity != null) { getEntityManager().lock(entity, LockModeType.PESSIMISTIC_WRITE); } } public <T> List<T> listPaged(Class<T> clazz, int start, int pageSize) { return findByQuery(new QueryDetails().setQuery("FROM " + clazz.getName() + " ORDER BY id").setStart(start) .setCount(pageSize)); } /** * Performs a given operation on all records in batches * @param operation * @param pageSize */ public <T> void performBatched(Class<T> clazz, int pageSize, PageableOperation<T> operation) { int page = 0; while (true) { List<T> data = listPaged(clazz, page * pageSize, pageSize); page++; operation.setData(data); operation.execute(); // final batch if (data.size() < pageSize) { break; } } } public <T> List<T> getByIds(Class<T> clazz, Collection<Long> ids) { if (ids.isEmpty()) { return Collections.emptyList(); } TypedQuery<T> query = getEntityManager().createQuery("SELECT piece FROM Piece piece WHERE id IN (:ids)", clazz); query.setParameter("ids", ids); return query.getResultList(); } }