package org.easyframe.enterprise.spring; import java.io.Serializable; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Map.Entry; import javax.persistence.EntityManagerFactory; import jef.common.log.LogUtil; import jef.common.wrapper.Page; import jef.database.DbClient; import jef.database.DbUtils; import jef.database.Field; import jef.database.IQueryableEntity; import jef.database.NativeQuery; import jef.database.PagingIterator; import jef.database.PojoWrapper; import jef.database.QB; import jef.database.RecordHolder; import jef.database.RecordsHolder; import jef.database.dialect.type.ColumnMapping; import jef.database.jpa.JefEntityManagerFactory; import jef.database.meta.EntityType; import jef.database.meta.ITableMetadata; import jef.database.meta.MetaHolder; import jef.database.query.Query; import jef.database.wrapper.ResultIterator; import jef.tools.Assert; import jef.tools.reflect.BeanWrapper; /** * 一个通用的DAO实现,涵盖了Session()对象中大部分数据库操作的方法。。<br> * 考虑到一般项目命名习惯等因素,建议有需要的同学自行继承BaseDao来编写通用的DAO,本类可当做是参考实现。 * * @see CommonDao * @author Administrator * */ public class CommonDaoImpl extends BaseDao implements CommonDao { public void persist(Object entity) { super.getEntityManager().persist(entity); } public <T> T merge(T entity) { return super.getEntityManager().merge(entity); } public int remove(Object entity) { try { return getSession().delete(entity); } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } public int removeCascade(Object entity) { try { return getSession().deleteCascade(entity); } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } /** * 空构造,一般用于在SpringFramework中初始化此Bean */ public CommonDaoImpl() { } public CommonDaoImpl(EntityManagerFactory emf) { this.setEntityManagerFactory(emf); } /** * 构造 * * @param db */ public CommonDaoImpl(DbClient db) { this.setEntityManagerFactory(new JefEntityManagerFactory(db)); } @SuppressWarnings("unchecked") public <T> int removeByExample(T entity, String... properties) { try { if (entity instanceof IQueryableEntity) { return getSession().delete(DbUtils.populateExampleConditions((IQueryableEntity) entity, properties)); } else { ITableMetadata meta = MetaHolder.getMeta(entity.getClass()); Query<PojoWrapper> q; if (properties.length == 0) { q = (Query<PojoWrapper>) meta.transfer(entity, true).getQuery(); } else { q = DbUtils.populateExampleConditions(meta.transfer(entity, false), properties); } return getSession().delete(q); } } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } public <T> T loadByPrimaryKey(Class<T> entityClass, Serializable primaryKey) { try { return getSession().load(entityClass, primaryKey); } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } @Override public <T> List<T> loadByPrimaryKeys(Class<T> entityClass, List<? extends Serializable> primaryKey) { try { return getSession().batchLoad(entityClass, primaryKey); } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } @SuppressWarnings("unchecked") public <T> List<T> find(T obj) { if (obj == null) return Collections.emptyList(); try { if (obj instanceof IQueryableEntity) { return (List<T>) getSession().select((IQueryableEntity) obj); } else { ITableMetadata meta = MetaHolder.getMeta(obj); PojoWrapper pojo = meta.transfer(obj, true); if (!pojo.hasQuery() && pojo.getUpdateValueMap().isEmpty()) { pojo.getQuery().setAllRecordsCondition(); } List<PojoWrapper> result = getSession().select(pojo); return PojoWrapper.unwrapList(result); } } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } public <T> int updateCascade(T entity) { if (entity == null) return 0; try { return getSession().updateCascade(entity); } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } /* * (non-Javadoc) * @see org.easyframe.enterprise.spring.CommonDao#update(java.lang.Object) */ public <T> int update(T entity) { if (entity == null) return 0; try { return getSession().update(entity); } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } /* * (non-Javadoc) * @see org.easyframe.enterprise.spring.CommonDao#updateByProperty(java.lang.Object, java.lang.String[]) */ public <T> int updateByProperty(T entity, String... property) { if (entity == null) return 0; if (property.length == 0) { return update(entity); } try { IQueryableEntity ent; if (!(entity instanceof IQueryableEntity)) { ITableMetadata meta = MetaHolder.getMeta(entity); ent = meta.transfer(entity, true); } else { ent = (IQueryableEntity) entity; } if (ent.getUpdateValueMap() == null || ent.getUpdateValueMap().isEmpty()) { DbUtils.fillUpdateMap(ent); } BeanWrapper bw = BeanWrapper.wrap(ent); Query<?> qq = ent.getQuery(); ITableMetadata meta = qq.getMeta(); for (String s : property) { ColumnMapping field = meta.findField(s); if (field == null) { throw new IllegalArgumentException(s + " not found database field in entity " + bw.getClassName()); } ent.getUpdateValueMap().remove(field.field()); qq.addCondition(field.field(), bw.getPropertyValue(s)); } return getSession().update(qq.getInstance()); } catch (SQLException e) { LogUtil.exception(e); throw DbUtils.toRuntimeException(e); } } /* * (non-Javadoc) * @see org.easyframe.enterprise.spring.CommonDao#update(java.lang.Object, java.util.Map, java.lang.String[]) */ public <T> int update(T entity, Map<String, Object> setValues, String... property) { try { IQueryableEntity ent; if (!(entity instanceof IQueryableEntity)) { ITableMetadata meta = MetaHolder.getMeta(entity); ent = meta.transfer(entity, true); } else { ent = (IQueryableEntity) entity; } Query<?> qq = ent.getQuery(); ITableMetadata meta = qq.getMeta(); ent.clearUpdate(); for (Entry<String, Object> entry : setValues.entrySet()) { ColumnMapping field = meta.findField(entry.getKey()); if (field == null) { throw new IllegalArgumentException(entry.getKey() + " not found database field in entity " + meta.getName()); } ent.prepareUpdate(field.field(), entry.getValue()); } if (property.length == 0) { return update(entity); } // 准备where条件 BeanWrapper bw = BeanWrapper.wrap(ent); for (String s : property) { ColumnMapping field = meta.findField(s); if (field == null) { throw new IllegalArgumentException(s + " not found database field in entity " + bw.getClassName()); } qq.addCondition(field.field(), bw.getPropertyValue(s)); } return getSession().update(qq.getInstance()); } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } public <T> T insert(T entity) { try { getSession().insert(entity); return entity; } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } public <T> T insertCascade(T entity) { try { getSession().insertCascade(entity); return entity; } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } public <T> T load(T entity) { return load(entity, true); } public <T> T load(T entity, boolean unique) { if (entity == null) return null; try { return getSession().load(entity, unique); } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } public <T> Page<T> findAndPage(T entity, int start, int limit) { if (entity == null) return null; try { return getSession().selectPage(entity, start, limit); } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } public <T> Page<T> findAndPageByQuery(String sql, Class<T> retutnType, Map<String, Object> params, int start, int limit) { try { NativeQuery<T> query = this.getSession().createNativeQuery(sql, retutnType); query.setParameterMap(params); return getSession().pageSelect(query, limit).setOffset(start).getPageData(); } catch (Exception ex) { throw DbUtils.toRuntimeException(ex); } } public <T> Page<T> findAndPageByQuery(String sql, ITableMetadata retutnType, Map<String, Object> params, int start, int limit) { try { NativeQuery<T> query = this.getSession().createNativeQuery(sql, retutnType); query.setParameterMap(params); return getSession().pageSelect(query, limit).setOffset(start).getPageData(); } catch (Exception ex) { throw DbUtils.toRuntimeException(ex); } } public <T> List<T> findByNq(String nqName, Class<T> type, Map<String, Object> params) { try { NativeQuery<T> nQuery = getSession().createNamedQuery(nqName, type); nQuery.setParameterMap(params); return nQuery.getResultList(); } catch (Exception ex) { throw DbUtils.toRuntimeException(ex); } } public <T> Page<T> findAndPageByNq(String nqName, Class<T> type, Map<String, Object> params, int start, int limit) { try { NativeQuery<T> query = this.getSession().createNamedQuery(nqName, type); query.setParameterMap(params); PagingIterator<T> i = getSession().pageSelect(query, limit); return i.setOffset(start).getPageData(); } catch (Exception ex) { throw DbUtils.toRuntimeException(ex); } } public <T> List<T> findByNq(String nqName, ITableMetadata meta, Map<String, Object> params) { try { @SuppressWarnings("unchecked") NativeQuery<T> query = (NativeQuery<T>) getSession().createNamedQuery(nqName, meta); query.setParameterMap(params); return query.getResultList(); } catch (Exception ex) { throw DbUtils.toRuntimeException(ex); } } public <T> Page<T> findAndPageByNq(String nqName, ITableMetadata meta, Map<String, Object> params, int start, int limit) { try { @SuppressWarnings("unchecked") NativeQuery<T> query = (NativeQuery<T>) getSession().createNamedQuery(nqName, meta); query.setParameterMap(params); PagingIterator<T> i = getSession().pageSelect(query, limit); return i.setOffset(start).getPageData(); } catch (Exception ex) { throw DbUtils.toRuntimeException(ex); } } /* * (non-Javadoc) * * @see * org.easyframe.enterprise.spring.CommonDao#findByExample(java.lang.Object, * java.lang.String[]) */ public <T> List<T> findByExample(T entity, String... propertyName) { if (entity == null) { return Collections.emptyList(); } try { return getSession().selectByExample(entity, propertyName); } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } /* * (non-Javadoc) * * @see * com.ailk.easyframe.web.common.dal.IDaoCrudSupport#executeNq(java.lang * .String, java.util.Map) */ public int executeNq(String nqName, Map<String, Object> param) { NativeQuery<?> query = getSession().createNamedQuery(nqName); return query.executeUpdate(); } public int executeQuery(String sql, Map<String, Object> param) { if (sql == null) { return 0; } NativeQuery<?> query = getSession().createNativeQuery(sql); query.setParameterMap(param); return query.executeUpdate(); } public <T> List<T> findByQuery(String sql, Class<T> type, Map<String, Object> params) { if (sql == null || type == null) { return Collections.emptyList(); } NativeQuery<T> query = getSession().createNativeQuery(sql, type); query.setParameterMap(params); return query.getResultList(); } public <T> List<T> findByQuery(String sql, ITableMetadata retutnType, Map<String, Object> params) { if (sql == null || retutnType == null) { return Collections.emptyList(); } NativeQuery<T> query = getSession().createNativeQuery(sql, retutnType); query.setParameterMap(params); return query.getResultList(); } public void removeByProperty(ITableMetadata meta, String propertyName, List<?> values) { if (meta == null || propertyName == null || values == null || values.isEmpty()) return; Assert.notNull(meta); List<IQueryableEntity> objs = new ArrayList<IQueryableEntity>(); for (Object o : values) { IQueryableEntity t; try { t = meta.newInstance(); t.startUpdate(); } catch (Exception e) { throw new IllegalArgumentException(e); } BeanWrapper bw = BeanWrapper.wrap(t); bw.setPropertyValue(propertyName, o); objs.add(t); } try { getSession().executeBatchDeletion(objs); } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } public void removeAll(ITableMetadata meta) { if (meta == null) return; try { this.getSession().delete(QB.create(meta)); } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } @SuppressWarnings("unchecked") public <T> T loadByPrimaryKey(ITableMetadata meta, Object id) { if (meta == null || id == null) return null; try { if (meta.getType() == EntityType.POJO) { IQueryableEntity bean = meta.newInstance(); DbUtils.setPrimaryKeyValue(bean, id); PojoWrapper wrapper = (PojoWrapper) getSession().load(bean, true); return (T) wrapper.get(); } else { return (T) getSession().load(meta, (Serializable) id); } } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } public List<?> findByField(ITableMetadata meta, String propertyName, Object value) { try { return getSession().selectByField(meta, propertyName, value); } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } public <T> List<T> findByField(Class<T> meta, String propertyName, Object value) { try { return getSession().selectByField(meta, propertyName, value); } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } @SuppressWarnings("unchecked") public <T> ResultIterator<T> iterate(T obj) { if (obj == null) return null; try { if (obj instanceof IQueryableEntity) { return (ResultIterator<T>) getSession().iteratedSelect((IQueryableEntity) obj, null); } else { ITableMetadata meta = MetaHolder.getMeta(obj); PojoWrapper pojo = meta.transfer(obj, true); if (!pojo.hasQuery() && pojo.getUpdateValueMap().isEmpty()) { pojo.getQuery().setAllRecordsCondition(); } ResultIterator<PojoWrapper> result = getSession().iteratedSelect(pojo, null); return PojoWrapper.unwrapIterator(result); } } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } public <T> ResultIterator<T> iterateByQuery(String sql, Class<T> returnType, Map<String, Object> params) { if (sql == null || returnType == null) return null; NativeQuery<T> query = getSession().createNativeQuery(sql, returnType); query.setParameterMap(params); return query.getResultIterator(); } public <T> ResultIterator<T> iterateByQuery(String sql, ITableMetadata returnType, Map<String, Object> params) { if (sql == null || returnType == null) return null; NativeQuery<T> query = getSession().createNativeQuery(sql, returnType); query.setParameterMap(params); return query.getResultIterator(); } public DbClient getNoTransactionSession() { return getSession().getNoTransactionSession(); } public <T> int batchInsert(List<T> entities) { return batchInsert(entities, null); } public <T> int extremeInsert(List<T> entities) { try { getSession().extremeInsert(entities, null); return entities.size(); } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } public <T> int batchInsert(List<T> entities, Boolean doGroup) { try { getSession().batchInsert(entities, doGroup); return entities.size(); } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } public <T> int batchDelete(List<T> entities) { return batchDelete(entities, null); } public <T> int batchDelete(List<T> entities, Boolean doGroup) { try { return getSession().batchDelete(entities, doGroup == null ? false : doGroup); } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } public <T> int batchUpdate(List<T> entities) { return batchUpdate(entities, null); } public <T> int batchUpdate(List<T> entities, Boolean doGroup) { try { return getSession().batchUpdate(entities, doGroup); } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } @Override public List<?> findByField(ITableMetadata meta, String propertyName, List<? extends Serializable> value) { Field field = meta.getField(propertyName); if (field == null) { throw new IllegalArgumentException("There's no property named " + propertyName + " in type of " + meta.getName()); } try { return (List<?>) getSession().batchLoadByField(field, value); } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } @Override public <T> T load(Class<T> entityClass, Serializable... id) { try { return getSession().load(entityClass, id); } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } @Override public <T extends IQueryableEntity> List<T> find(Query<T> data) { try { return getSession().select(data); } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } @SuppressWarnings("unchecked") @Override public <T> T loadByField(ITableMetadata meta, String field, Serializable value, boolean unique) { try { return (T) getSession().loadByField(meta, field, value, unique); } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } @SuppressWarnings("unchecked") @Override public <T extends IQueryableEntity> T loadByField(Field field, Object value) { try { return (T) getSession().loadByField(field, value); } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } @SuppressWarnings("unchecked") @Override public <T extends IQueryableEntity> T loadByField(Field field, Object value, boolean unique) { try { return (T) getSession().loadByField(field, value, unique); } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } @SuppressWarnings("unchecked") @Override public <T> T loadByField(Class<T> clz, String field, Serializable value, boolean unique) { if (clz == null || field == null) { return null; } ITableMetadata meta = MetaHolder.getMeta(clz); ColumnMapping def = meta.findField(field); if (def == null) { throw new IllegalArgumentException("There's no field [" + field + "] in " + clz.getName()); } try { return (T) getSession().loadByField(def.field(), value, unique); } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } @Override public <T> int removeByField(Class<T> clz, String field, Serializable value) { if (clz == null || field == null) { return 0; } ITableMetadata meta = MetaHolder.getMeta(clz); ColumnMapping def = meta.findField(field); if (def == null) { throw new IllegalArgumentException("There's no field [" + field + "] in " + clz.getName()); } try { return getSession().deleteByField(def.field(), value); } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } public int removeByKey(ITableMetadata meta, String fieldname, Serializable key) { if (meta == null || fieldname == null) return 0; Field field = meta.getField(fieldname); if (field == null) { throw new IllegalArgumentException("There's no property named " + fieldname + " in type of " + meta.getName()); } Query<?> query = QB.create(meta); query.addCondition(field, key); try { return getSession().delete(query); } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } @Override public int removeByField(ITableMetadata meta, String field, Serializable value) { if (meta == null || field == null) { return 0; } ColumnMapping def = meta.findField(field); if (def == null) { throw new IllegalArgumentException("There's no field [" + field + "] in " + meta.getName()); } try { return getSession().deleteByField(def.field(), value); } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } @Override public <T extends IQueryableEntity> RecordsHolder<T> selectForUpdate(Query<T> query) { try { return getSession().selectForUpdate(query.getInstance()); } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } @Override public <T extends IQueryableEntity> RecordHolder<T> loadForUpdate(Query<T> query) { try { return getSession().loadForUpdate(query.getInstance()); } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } public <T extends IQueryableEntity> RecordHolder<T> loadForUpdate(T query) { try { return getSession().loadForUpdate(query); } catch (SQLException e) { throw DbUtils.toRuntimeException(e); } } }