Java tutorial
/* * Copyright (c) 2013 @iSQWEN. All rights reserved. * * 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 org.faster.orm.service.hibernate; import org.faster.orm.model.GenericEntity; import org.faster.orm.option.Options; import org.faster.orm.option.QueryOption; import org.hibernate.Criteria; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; import org.hibernate.criterion.DetachedCriteria; import org.hibernate.criterion.MatchMode; import org.hibernate.criterion.Restrictions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.persistence.Id; import javax.persistence.Transient; import java.io.Serializable; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; /** * @author sqwen */ public class HibernateDaoSupport<PO extends GenericEntity<ID>, ID extends Serializable> { protected final Logger log = LoggerFactory.getLogger(getClass()); protected SessionFactory sessionFactory; protected Class<PO> persistClass; protected final String persistClassName; private volatile List<Field> persistentFields; protected boolean cacheEnabled = false; protected String cacheRegion; protected int maxBatchQuerySize = 1000; protected String idFieldName; @SuppressWarnings("unchecked") public HibernateDaoSupport() { persistClass = getPersistClass(); if (persistClass == null) { Type genericSuperClass = getClass().getGenericSuperclass(); if (getClass().getName().contains("$$EnhancerBy")) { genericSuperClass = getClass().getSuperclass().getGenericSuperclass(); } persistClass = (Class<PO>) ((ParameterizedType) genericSuperClass).getActualTypeArguments()[0]; } Cache cache = persistClass.getAnnotation(Cache.class); cacheEnabled = cache != null && cache.usage() != CacheConcurrencyStrategy.NONE; persistClassName = persistClass.getSimpleName(); parsePersistentFields(); } protected Class getPersistClass() { return null; } public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } public void setCacheEnabled(boolean cacheEnabled) { this.cacheEnabled = cacheEnabled; } public void setCacheRegion(String cacheRegion) { this.cacheRegion = cacheRegion; } public void setMaxBatchQuerySize(int maxBatchQuerySize) { this.maxBatchQuerySize = maxBatchQuerySize; } protected Session getSession() { return sessionFactory.getCurrentSession(); } protected String getCacheDisplay(boolean isCacheEnabled) { return isCacheEnabled ? "enabled" : "disabled"; } // ============================= // ? // ============================= protected void beforeCreate(PO po) { } protected void beforeUpdate(PO po) { } protected boolean isDistinctRootEntity() { return false; } protected boolean isInitialRequired() { return false; } /** * ???? */ protected void renderCriteria(DetachedCriteria criteria) { if (isDistinctRootEntity()) { criteria.setResultTransformer(DetachedCriteria.DISTINCT_ROOT_ENTITY); } } /** * ?? * * @return ? */ protected DetachedCriteria buildCriteria() { return DetachedCriteria.forClass(persistClass); } protected int getIntValue(Object count) { if (count instanceof Long) { return ((Long) count).intValue(); } return (Integer) count; } private void parsePersistentFields() { persistentFields = new LinkedList<Field>(); Class<?> superClass = persistClass; while (superClass != null) { Field[] superFields = superClass.getDeclaredFields(); for (Field f : superFields) { if (Modifier.isStatic(f.getModifiers())) { continue; } if (f.isAnnotationPresent(Transient.class)) { continue; } f.setAccessible(true); persistentFields.add(f); if (f.isAnnotationPresent(Id.class)) { idFieldName = f.getName(); } } superClass = superClass.getSuperclass(); } } protected void flush() { getSession().flush(); } protected Object fetchSingle(final DetachedCriteria criteria) { return fetchSingle(criteria, Options.getCacheEnabledQueryOption(cacheEnabled)); } @SuppressWarnings("rawtypes") protected Object fetchSingle(final DetachedCriteria criteria, QueryOption queryOption) { List list = fetchPage(criteria, 1, 1, queryOption); return list.isEmpty() ? null : list.get(0); } @SuppressWarnings("rawtypes") protected List fetchAll(final DetachedCriteria criteria) { return fetchPage(criteria, -1, -1, Options.getCacheEnabledQueryOption(cacheEnabled)); } @SuppressWarnings("rawtypes") protected List fetchAll(final DetachedCriteria criteria, QueryOption queryOption) { if (queryOption.isPaginationEnabled()) { return fetchPage(criteria, queryOption.getPage(), queryOption.getLimit(), queryOption); } else { return fetchPage(criteria, -1, -1, queryOption); } } @SuppressWarnings("rawtypes") protected List fetchPage(final DetachedCriteria criteria, final int page, final int limit) { return fetchPage(criteria, page, limit, Options.getCacheEnabledQueryOption(cacheEnabled)); } @SuppressWarnings("rawtypes") protected List fetchPage(final DetachedCriteria criteria, final int page, final int limit, QueryOption queryOption) { renderCriteria(criteria); Criteria executableCriteria = criteria.getExecutableCriteria(getSession()); if (queryOption != null) { executableCriteria.setCacheable(queryOption.isCacheEnabled()); if (cacheRegion != null) { executableCriteria.setCacheRegion(cacheRegion); } } if (page >= 1) { executableCriteria.setFirstResult((page - 1) * limit); } if (limit > 0) { executableCriteria.setMaxResults(limit); } return executableCriteria.list(); } protected DetachedCriteria buildCriteriaByExample(PO example) { Map<String, Object> map = buildPersistPropertyValueMap(example); return buildCriteriaByPropertyValueMap(map); } protected DetachedCriteria buildCriteriaByPropertyAndValue(String propertyName, Object propertyValue) { return buildCriteriaByPropertyValueMap(Collections.singletonMap(propertyName, propertyValue)); } protected DetachedCriteria buildCriteriaByPropertyAndValueLike(String propertyName, String likeValue, boolean isIlike, MatchMode matchMode) { DetachedCriteria dc = buildCriteria(); if (matchMode == null) { matchMode = MatchMode.START; } if (isIlike) { dc.add(Restrictions.ilike(propertyName, likeValue, matchMode)); } else { dc.add(Restrictions.like(propertyName, likeValue, matchMode)); } return dc; } protected DetachedCriteria buildCriteriaByPropertyValueMap(Map<String, Object> propertyValueMap) { DetachedCriteria dc = buildCriteria(); if (propertyValueMap != null) { for (String propertyName : propertyValueMap.keySet()) { Object propertyValue = propertyValueMap.get(propertyName); dc.add(Restrictions.eqOrIsNull(propertyName, propertyValue)); } } return dc; } protected Map<String, Object> buildPersistPropertyValueMap(PO example) { Map<String, Object> map = new HashMap<String, Object>(); try { for (Field f : persistentFields) { Object value = f.get(example); if (value != null) { map.put(f.getName(), value); } } } catch (IllegalArgumentException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } return map; } // ?? protected void logBegin(String actionName, Object obj) { log.info("{} {} by {}...", new Object[] { actionName, persistClassName, obj }); } protected void logComplete(String actionName, long elapsed) { log.info("{} a {}. ({} ms)", new Object[] { actionName, persistClassName, elapsed }); } protected void logComplete(String actionName, ID id, long elapsed) { log.info("{} {}#{}. ({} ms)", new Object[] { actionName, persistClassName, id, elapsed }); } protected void logMultiBegin(String actionName, int count) { log.info("{} {} {}...", new Object[] { actionName, count, persistClassName }); } protected void logMultiComplete(String actionName, int count, long elapsed) { log.info("{} {} {}. ({} ms)", new Object[] { actionName, count, persistClassName, elapsed }); } }