Java tutorial
/* * Copyright 2013-2016 iNeunet OpenSource and the original author or authors. * * 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 com.ineunet.knife.persist.dao.support; import java.io.Serializable; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.persistence.EntityExistsException; import javax.persistence.Table; import org.hibernate.Criteria; import org.hibernate.Hibernate; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.criterion.Criterion; import org.hibernate.criterion.Restrictions; import org.hibernate.metadata.ClassMetadata; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.ineunet.knife.persist.dao.IGenericDao; import com.ineunet.knife.persist.exception.PersistException; import com.ineunet.knife.util.Asserts; import com.ineunet.knife.util.ClassStrUtils; import com.ineunet.knife.util.ISortedMap; import com.ineunet.knife.util.ReflectionUtils; import com.ineunet.knife.util.StringUtils; /** * * @author Hilbert * */ public class HibernateDaoImpl<T> implements IGenericDao<T> { protected Logger logger = LoggerFactory.getLogger(getClass()); protected SessionFactory sessionFactory; protected Class<T> entityClass = ReflectionUtils.getSuperClassGenricType(getClass()); public HibernateDaoImpl() { } public HibernateDaoImpl(SessionFactory sessionFactory) { Asserts.notNull(sessionFactory); this.sessionFactory = sessionFactory; } /** * ??Session. */ public Session getSession() { return sessionFactory.getCurrentSession(); } public void evict(Object object) { this.getSession().evict(object); } public <X> void evict(List<X> objects) { for (X x : objects) { this.evict(x); } } public void clear() { this.getSession().clear(); } @Override public String tableName() { return tableName(this.entityClass); } @Override public <X> String tableName(Class<X> entityClass) { Table table = entityClass.getAnnotation(Table.class); if (table == null) throw new EntityExistsException("Lack of Annotation @Table"); String name = table.name(); if (StringUtils.isBlank(name)) return ClassStrUtils.hump2Underline(name); return name; } @Override public String entityName() { return this.entityClass.getSimpleName(); } @Override public <X> X create(X entity) { Asserts.notNull(entity, "entity cannot be null."); getSession().save(entity); getSession().flush(); return entity; } @Override public <X> void create(Collection<X> entities) { Asserts.notNull(entities, "entities cannot be null."); for (X entity : entities) this.create(entity); } @Override public <X> X update(X entity) { Asserts.notNull(entity, "entity cannot be null."); getSession().update(entity); getSession().flush(); return entity; } @Override public <X> void update(Collection<X> entities) { Asserts.notNull(entities, "entities cannot be null."); for (X entity : entities) this.update(entity); } @Override public <X> X merge(X entity) { Asserts.notNull(entity, "entity cannot be null."); getSession().merge(entity); getSession().flush(); return entity; } @Override public <X> void saveOrUpdate(X entity) { Asserts.notNull(entity, "entity cannot be null."); getSession().saveOrUpdate(entity); getSession().flush(); } @SuppressWarnings("unchecked") @Override public T get(Object id) { Asserts.notNull(id, "id cannot be null."); return (T) getSession().get(entityClass, (Serializable) id); } @SuppressWarnings("unchecked") @Override public <X> X get(Object id, Class<X> entityClass) { Asserts.notNull(id, "id cannot be null."); return (X) getSession().get(entityClass, (Serializable) id); } @SuppressWarnings("unchecked") @Override public <X> List<X> getByIds(Collection<?> ids, Class<X> entityClass) { if (ids == null || ids.size() == 0) { return Collections.EMPTY_LIST; } return getSession().createQuery("from " + entityClass.getSimpleName() + " where id in(:ids)") .setParameterList("ids", ids).list(); } @Override public List<T> findByProperty(String propertyName, Object propertyValue) { Asserts.notBlank(propertyName, "propertyName cannot be null."); Criterion criterion = Restrictions.eq(propertyName, propertyValue); return find(criterion); } @SuppressWarnings("unchecked") @Override public <X> List<X> findByProperty(Class<X> entityClass, String propertyName, Object propertyValue) { StringBuilder sb = new StringBuilder(); sb.append("select o from ").append(entityClass.getSimpleName()).append(" o where o."); sb.append(propertyName).append("=?"); return this.createQuery(sb.toString(), propertyValue).list(); } @Override public List<T> findByProperty(String propertyName, Object... propertyValues) { return (List<T>) this.findByProperty(propertyName, entityClass, propertyValues); } @SuppressWarnings("unchecked") @Override public <X> List<X> findByProperty(Class<X> entityClass, String propertyName, Object... propertyValues) { StringBuilder sb = new StringBuilder(); sb.append("select o from ").append(entityClass.getSimpleName()).append(" o where "); for (int i = 0; i < propertyValues.length - 1; i++) sb.append("o.").append(propertyName).append("=?").append(" or "); sb.append("o.").append(propertyName).append("=?"); return this.createQuery(sb.toString(), propertyValues).list(); } @Override public <X> Long countByProperty(Class<X> entityClass, String propertyName, Object propertyValue) { StringBuilder jql = new StringBuilder("select count(*) from "); jql.append(entityClass.getSimpleName()).append(" where "); jql.append(propertyName).append("=?"); return this.count(jql.toString(), propertyValue); } @Override public <X> boolean existsByProperty(Class<X> entityClass, String propertyName, Object propertyValue) { return 0 != countByProperty(entityClass, propertyName, propertyValue); } @SuppressWarnings("unchecked") @Override public T findOneByProp(String propertyName, Object propertyValue) { Asserts.notBlank(propertyName, "propertyName cannot be null."); Criterion criterion = Restrictions.eq(propertyName, propertyValue); return (T) createCriteria(criterion).uniqueResult(); } @Override public <X> X findOne(String propertyName, Object propertyValue, Class<X> entityClass) { StringBuilder hql = new StringBuilder(); hql.append("from ").append(entityClass.getSimpleName()).append(" o where o.").append(propertyName) .append("=?"); List<X> list = this.find(hql.toString(), propertyValue); if (list.isEmpty()) return null; else if (list.size() == 1) return list.get(0); else throw new PersistException("too many rows, should be unique in business."); } @Override public <X> X findOne(String jql, Object... values) { List<X> list = this.find(jql, values); if (list.isEmpty()) return null; else if (list.size() == 1) return list.get(0); else throw new PersistException("too many rows, should be unique in business."); } @SuppressWarnings("unchecked") @Override public List<T> find(ISortedMap<String, Object> properties) { Asserts.notEmpty(properties.values(), "properties cannot be null."); StringBuilder sb = new StringBuilder(); sb.append("from ").append(entityClass.getSimpleName()).append(" o where "); for (String key : properties.keyList()) { sb.append("o.").append(key).append("=:").append(key); } return this.createQuery(sb.toString(), properties.asMap()).list(); } @SuppressWarnings("unchecked") @Override public <X> List<X> find(String jql, List<Object> values) { return createQuery(jql, values).list(); } @SuppressWarnings("unchecked") @Override public <X> List<X> find(String jql, Object... values) { return createQuery(jql, values).list(); } @SuppressWarnings("unchecked") @Override public <X> List<X> find(String jql, Map<String, ?> values) { return createQuery(jql, values).list(); } /** * Not support collection parameter, * use <code>count(String jql, Map<String, ?> values)</code> if in need. */ @Override public long count(String jql, Object... values) { return (Long) this.createQuery(jql, values).list().get(0); } @Override public long count(String jql, Map<String, ?> values) { return (Long) this.createQuery(jql, values).list().get(0); } @Override public List<T> findAll() { return find("from " + entityClass.getSimpleName()); } @SuppressWarnings("unchecked") @Override public <X> List<X> findAll(Class<X> entityClass) { return this.createQuery("from " + entityClass.getSimpleName()).list(); } @Override public <X> void delete(X entity) { Asserts.notNull(entity, "entity cannot be null."); getSession().delete(entity); } @Override public void deleteById(Object id) { this.deleteById(id, entityClass); } @Override public void deleteById(Object id, Class<?> entityClass) { Asserts.notNull(id, "id cannot be null."); String hql = "delete from " + entityClass.getSimpleName() + " where id=?"; this.batchExecute(hql, id); } @Override public void deleteByIds(List<Object> ids) { Asserts.notEmpty(ids, "id cannot be null."); StringBuilder sb = new StringBuilder(); sb.append("delete from ").append(this.entityClass.getSimpleName()); sb.append(" where "); for (int i = 0; i < ids.size() - 1; i++) sb.append("id=? or "); sb.append("id=?"); this.batchExecute(sb.toString(), ids.toArray()); } @Override public void deleteByProperties(ISortedMap<String, Object> properties) { Asserts.notEmpty(properties.values(), "properties cannot be null."); StringBuilder sb = new StringBuilder(); sb.append("delete from ").append(entityClass.getSimpleName()).append(" o where "); for (String key : properties.keyList()) { sb.append("o.").append(key).append("=:").append(key); } this.batchExecute(sb.toString(), properties.asMap()); } @Override public void deleteByProperty(String propertyName, Object propertyValue) { this.deleteByProperty(entityClass, propertyName, propertyValue); } @Override public void deleteByProperty(Class<?> entityClass, String propertyName, Object propertyValue) { String ql = "delete from " + entityClass.getSimpleName() + " o where o." + propertyName + "=?"; this.batchExecute(ql, propertyValue); } @Override public void deleteByProperty(String propertyName, Object... propertyValues) { this.deleteByProperty(entityClass, propertyName, propertyValues); } @Override public void deleteByProperty(Class<?> entityClass, String propertyName, Object... propertyValues) { StringBuilder sb = new StringBuilder(); sb.append("delete from ").append(entityClass.getSimpleName()).append(" o where "); for (int i = 0; i < propertyValues.length - 1; i++) sb.append("o.").append(propertyName).append("=?").append(" or "); sb.append("o.").append(propertyName).append("=?"); this.batchExecute(sb.toString(), propertyValues); } @Override public int batchExecute(String hql, Map<String, ?> values) { return createQuery(hql, values).executeUpdate(); } @Override public int batchExecute(String hql, Object... values) { return createQuery(hql, values).executeUpdate(); } public Class<T> getEntityClass() { return this.entityClass; } public void setEntityClass(Class<T> entityClass) { this.entityClass = entityClass; } public SessionFactory getSessionFactory() { return sessionFactory; } /** * SesionFactory??. */ public void setSessionFactory(final SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } /* * =============================== for hibernate * ============================= */ public Criteria createCriteria(final Criterion... criterions) { Criteria criteria = getSession().createCriteria(entityClass); for (Criterion c : criterions) criteria.add(c); return criteria; } @SuppressWarnings("unchecked") public List<T> find(final Criterion... criterions) { return createCriteria(criterions).list(); } @SuppressWarnings("unchecked") public T findUnique(final Criterion... criterions) { return (T) createCriteria(criterions).uniqueResult(); } public Query createQuery(final String queryString, final Object... values) { Asserts.notBlank(queryString, "queryString cannot be null."); Query query = getSession().createQuery(queryString); if (values != null) { for (int i = 0; i < values.length; i++) { query.setParameter(i, values[i]); } } return query; } /** * ?HQL?Query. find()???. * * @param values * ??,?. */ public Query createQuery(final String queryString, final List<Object> values) { Asserts.notBlank(queryString, "queryString cannot be null."); Query query = getSession().createQuery(queryString); if (values != null) { int j = 0; for (Iterator<Object> i = values.iterator(); i.hasNext();) { query.setParameter(j, i.next()); j++; } } return query; } /** * ?HQL?Query. find()???. * * @param values * ???,??. */ public Query createQuery(final String queryString, final Map<String, ?> values) { Asserts.notBlank(queryString, "queryString cannot be null."); Query query = getSession().createQuery(queryString); if (values != null) query.setProperties(values); return query; } /** * ???. */ public String getIdName() { ClassMetadata meta = getSessionFactory().getClassMetadata(entityClass); return meta.getIdentifierPropertyName(); } /** * ?. load()Proxy, View???. entity, * ??entity,????. ??,: * Hibernate.initialize(user.getRoles())?User??. * Hibernate.initialize * (user.getDescription())?UserDescription. */ public void initProxyObject(Object proxy) { Hibernate.initialize(proxy); } /** * Flush?Session. */ public void flush() { getSession().flush(); } /** * ??. * ,(value)?(orgValue)?. */ public boolean isPropertyUnique(final String propertyName, final Object newValue, final Object oldValue) { if (newValue == null || newValue.equals(oldValue)) { return true; } Object object = findOneByProp(propertyName, newValue); return (object == null); } /** * ??. * ,(value)?(orgValue)?. * @since 2.0.1 */ public boolean isPropertyUnique(Class<?> entityClass, final String propertyName, final Object newValue, final Object oldValue) { if (newValue == null || newValue.equals(oldValue)) { return true; } Object object = findOne(propertyName, newValue, entityClass); return (object == null); } }