package org.dayatang.security.domain; import org.dayatang.domain.BaseEntity; import org.dayatang.domain.CriteriaQuery; import org.dayatang.domain.NamedParameters; import org.dayatang.utils.DateUtils; import javax.persistence.*; import java.util.*; /** * 所有实体的基类,定义实体的公共属性和行为。 * Created by yyang on 15/1/6. */ @MappedSuperclass public abstract class AbstractEntity extends BaseEntity { public static final String ID_FIELD = "id"; public static final String VERSION_FIELD = "version"; @Id private String id = UUID.randomUUID().toString(); @Version private int version; //创建时间 @Temporal(TemporalType.TIMESTAMP) private Date created; //最后修改时间 @Temporal(TemporalType.TIMESTAMP) private Date lastModified; //失效时间 @Temporal(TemporalType.TIMESTAMP) private Date expired; //是否已经失效 private boolean disabled; /** * 构造新的实体对象,设置创建时间和最后修改时间为当前时间,失效状态为false */ public AbstractEntity() { this(new Date()); } public AbstractEntity(Date created) { this.created = new Date(created.getTime()); lastModified = new Date(created.getTime()); disabled = false; expired = DateUtils.MAX_DATE; } /** * 获得实体的标识 * * @return 实体的标识 */ @Override public String getId() { return id; } /** * 设置实体的标识 * * @param id 要设置的实体标识 */ public void setId(String id) { this.id = id; } /** * 获得实体的版本号。持久化框架以此实现乐观锁。 * * @return 实体的版本号 */ public int getVersion() { return version; } /** * 设置实体的版本号。持久化框架以此实现乐观锁。 * * @param version 要设置的版本号 */ public void setVersion(int version) { this.version = version; } /** * 获取实体创建时间 * @return 实体的创建时间 */ public Date getCreated() { return new Date(created.getTime()); } /** * 设置实体创建时间 * @param created 要设置的创建时间 */ public void setCreated(Date created) { this.created = new Date(created.getTime()); } /** * 获取实体最后修改的时间 * @return 实体最后修改时间 */ public Date getLastModified() { return new Date(lastModified.getTime()); } /** * 设置实体最后修改时间 * @param lastModified 要设置的最后修改时间 */ public void setLastModified(Date lastModified) { this.lastModified = new Date(lastModified.getTime()); } public Date getExpired() { return expired; } /** * 判断实体是否已经失效 * @return 如果实体已经失效则返回true,否则返回false */ public boolean isDisabled() { return disabled; } /** * 使实体失效,对系统来说,等价于实体已经在逻辑上被删除 */ public void disable(Date date) { disabled = true; expired = date; save(); } /** * 使实体重新生效,等价于恢复实体的有效状态 */ public void enable() { disabled = false; expired = DateUtils.MAX_DATE; save(); } /** * 将实体本身持久化到数据库 */ public void save() { lastModified = new Date(); getRepository().save(this); } /** * 将实体本身从数据库中删除 */ public void remove() { getRepository().remove(this); } /** * 根据ID获取指定类型的实体,所有的属性已填充好 * @param entityClass * @param id * @param <T> * @return */ public static <T extends AbstractEntity> T get(Class<T> entityClass, String id) { return getRepository().get(entityClass, id); } /** * 根据ID获取指定类型的实体,除ID外,其余属性均未填充,实际上没访问数据库。此方法主要为性能考虑 * @param entityClass * @param id * @param <T> * @return */ public static <T extends AbstractEntity> T load(Class<T> entityClass, String id) { return getRepository().load(entityClass, id); } /** * 查找指定类型的所有实体 * @param <T> 实体所属的类型 * @param clazz 实体所属的类 * @return 符合条件的实体列表 */ public static <T extends AbstractEntity> List<T> findAll(Class<T> clazz) { return createCriteriaQuery(clazz).list(); } /** * 根据单个属性值以“属性=属性值”的方式查找符合条件的实体集合 * @param <T> 实体所属的类型 * @param clazz 实体所属的类 * @param propName 属性名 * @param value 匹配的属性值 * @return 符合条件的实体列表 */ public static <T extends AbstractEntity> List<T> findByProperty(Class<T> clazz, String propName, Object value) { Map<String, Object> propValues = new HashMap<String, Object>(); //propValues.put("disabled", false); propValues.put(propName, value); return findByProperties(clazz, propValues); } /** * 根据多个属性值以“属性=属性值”的方式查找符合条件的实体集合,例如查找name="张三", age=35的员工。 * @param <T> 实体所属的类型 * @param clazz 实体所属的类 * @param propValues 属性值匹配条件 * @return 符合条件的实体列表 */ public static <T extends AbstractEntity> List<T> findByProperties(Class<T> clazz, Map<String, Object> propValues) { Map<String, Object> newProps = new HashMap<String, Object>(); //newProps.put("disabled", false); newProps.putAll(propValues); return getRepository().findByProperties(clazz, NamedParameters.create(newProps)); } /** * 根据单个属性值以“属性=属性值”的方式查找符合条件的单个实体,通常用于根据业务主键找到唯一实体 * @param <T> 实体所属的类型 * @param clazz 实体所属的类 * @param propName 属性名 * @param value 匹配的属性值 * @return 符合条件的实体列表 */ public static <T extends AbstractEntity> T getByProperty(Class<T> clazz, String propName, Object value) { List<T> entities = findByProperty(clazz, propName, value); return entities == null || entities.isEmpty() ? null : entities.get(0); } /** * 根据多个属性值以“属性=属性值”的方式查找符合条件的单个实体,通常用于根据业务主键找到唯一实体,例如查找name="张三", age=35的员工。 * @param <T> 实体所属的类型 * @param clazz 实体所属的类 * @param propValues 属性值匹配条件 * @return 符合条件的实体列表 */ public static <T extends AbstractEntity> T getByProperties(Class<T> clazz, Map<String, Object> propValues) { List<T> entities = findByProperties(clazz, propValues); return entities == null || entities.isEmpty() ? null : entities.get(0); } /** * 生成针对某个实体类的条件查询,缺省加入“disabled = false”的条件,以过滤掉已经逻辑删除的实体 * @param entityClass 实体类 * @param <T> 实体的类型 * @return 针对某种实体类的条件查询 */ public static <T extends AbstractEntity> CriteriaQuery createCriteriaQuery(Class<T> entityClass) { return getRepository().createCriteriaQuery(entityClass).isFalse("disabled"); } }