Spring Boot -- Spring Data Jpa(6)

来源:互联网 发布:少女漫画软件下载 编辑:程序博客网 时间:2024/06/05 19:18

实体类的公共父类

import java.io.Serializable;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.MappedSuperclass;@SuppressWarnings("serial")@MappedSuperclasspublic class BaseEntity<ID extends Serializable> implements Serializable {    @Id    @GeneratedValue    protected ID id;    public ID getId() {        return id;    }    public void setId(ID id) {        this.id = id;    }   }

Repository公共接口

import java.lang.reflect.ParameterizedType;public abstract class EnumDao<T> {    protected Class<T> entityClass;    @SuppressWarnings("unchecked")    public EnumDao() {        this.entityClass = ((Class<T>)((ParameterizedType)this.getClass().getGenericSuperclass()).getActualTypeArguments()[0]);    }}import java.io.Serializable;import java.util.List;import org.springframework.data.domain.Page;import org.springframework.data.domain.Pageable;import org.springframework.data.jpa.domain.Specification;import com.yucoang.demo_spring_data_jpa.entity.BaseEntity;public interface JpaDao<T extends BaseEntity<ID>,ID extends Serializable> {    /**     * 添加     * 当实体类存在createTime字段时,自动填入当前时间戳     * @param t     * @return     * @throws Exception     */    T add(T t) throws Exception;    /**     * 修改     * 遍历传入对象的属性,不为空的属性写入数据库     * @param id     * @param t     * @return     * @throws Exception     */    T update(ID id,T t) throws Exception;    /**     * 删除     * 当实体类存在enable字段时,将enable改为false即为删除     * 不存在enable字段,则删除数据     * @param id     * @throws Exception     */    void delete(ID id) throws Exception;    /**     * 取消删除(实体类拥有enable属性)     * 当实体类存在enable字段时,将enable改为true即为取消删除     * @param id     * @throws Exception     */    void undelete(ID id) throws Exception;    /**     * ID对象是否存在     * @param id     * @return     * @throws Exception     */    Boolean exist(ID id) throws Exception;    /**     * 读取对象信息     * @param id     * @return     * @throws Exception     */    T findOne(ID id) throws Exception;    /**     * 读取对象信息,指定返回属性     * @param id 对象id     * @param fields 所要返回的属性     * @return     * @throws Exception     */    T findOne(ID id,String[] fields) throws Exception;    /**     * 条件查询     * @param spec     * @return     * @throws Exception     */    T findOne(Specification<T> spec) throws Exception;    /**     * 读取全部     * @return     * @throws Exception     */    List<T> findAll() throws Exception;    /**     * 读取全表记录数     * @return     * @throws Exception     */    Long number() throws Exception;    /**     * 条件查询记录数     * Long total = super.count(new Specification<User>() {     *  public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {     *      return query     *          .where(cb.like((root.get("name")), "陈%"))     *          .getGroupRestriction();     *  }     * });     * @param spec     * @return     * @throws Exception     */    Long number(Specification<T> spec) throws Exception;    /**     * 列表</br>        * List<User> userList = super.findAll(new Specification<User>(){     *  public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {     *      query        *          .multiselect(root.get("id"))                //查询字段,不带此方法则查询全部字段     *          .orderBy(cb.desc(root.get("id")));          //排序字段,不带此方法则不进行排序     *      return cb.equal(root.get("id"), 1L);            //查询条件,不带此方法则无筛选条件     *  }     * });     * @param spec     * @return     * @throws Exception     */    List<T> findAll(Specification<T> spec) throws Exception;    /**     * 分页列表</br>     * 用法</br>     * Page<User> userPage = super.findAll(new Specification<User>(){     *  public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {     *      query     *          .multiselect(root.get("id"))                //查询字段,不带此方法则查询全部字段     *          .orderBy(cb.desc(root.get("id")));          //排序字段,不带此方法则不进行排序     *      return cb.equal(root.get("id"), 1L)             //查询条件     *  }     * },new PageRequest(0, 10));                           //分页条件     * @param spec     * @param pageable     * @return     * @throws Exception     */    Page<T> findAll(Specification<T> spec,Pageable pageable) throws Exception;}

Repository实现类

import java.beans.IntrospectionException;import java.beans.PropertyDescriptor;import java.io.Serializable;import java.lang.reflect.Field;import java.util.ArrayList;import java.util.List;import javax.persistence.EntityManager;import javax.persistence.PersistenceContext;import javax.persistence.criteria.CriteriaBuilder;import javax.persistence.criteria.CriteriaQuery;import javax.persistence.criteria.Predicate;import javax.persistence.criteria.Root;import javax.persistence.criteria.Selection;import javax.transaction.Transactional;import org.hibernate.jpa.criteria.path.SingularAttributePath;import org.springframework.data.domain.Page;import org.springframework.data.domain.PageImpl;import org.springframework.data.domain.Pageable;import org.springframework.data.jpa.domain.Specification;import org.springframework.data.jpa.repository.support.SimpleJpaRepository;import com.yucoang.demo_spring_data_jpa.entity.BaseEntity;@SuppressWarnings("unchecked")@Transactionalpublic abstract class JpaDaoImpl<T extends BaseEntity<ID>,ID extends Serializable> extends EnumDao<T> implements JpaDao<T, ID> {    @PersistenceContext    EntityManager em;    SimpleJpaRepository<T,ID> repository;    public JpaDaoImpl(){        super();    }    private SimpleJpaRepository<T,ID> getRepository(){        if(this.repository == null){            this.repository = new SimpleJpaRepository<T,ID>(super.entityClass, em);        }        return this.repository;    }    @Override    public T add(T t) throws Exception {        for (Class<?> clazz = super.entityClass; clazz != BaseEntity.class; clazz = clazz.getSuperclass()) {            try{                PropertyDescriptor pd = new PropertyDescriptor("createTime", super.entityClass);                pd.getWriteMethod().invoke(t, System.currentTimeMillis());            }catch(IntrospectionException e){                continue;            }        }           return this.getRepository().save(t);    }    @Override    public T update(ID id, T t) throws Exception {        T t_old = this.getRepository().findOne(id);        for (Class<?> clazz = super.entityClass; clazz != BaseEntity.class; clazz = clazz.getSuperclass()) {            for (Field field : clazz.getDeclaredFields()) {                if("serialVersionUID".equals(field.getName())){                    continue;                }                PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz);                if(pd.getReadMethod().invoke(t) != null){                    pd.getWriteMethod().invoke(t_old, pd.getReadMethod().invoke(t));                }            }        }        return this.getRepository().save(t_old);    }    @Override    public void delete(ID id) throws Exception {        /*         * 遍历实体类与实体类父类的属性,当存在enable时,将enable设为false即视为删除         */        for (Class<?> clazz = super.entityClass; clazz != BaseEntity.class; clazz = clazz.getSuperclass()) {            try{                PropertyDescriptor pd = new PropertyDescriptor("enable", super.entityClass);                T t = this.getRepository().findOne(id);                pd.getWriteMethod().invoke(t, false);                this.getRepository().save(t);                return;            }catch(IntrospectionException e){                continue;            }        }        /*         * 无enable属性,则删除记录         */        this.getRepository().delete(id);;    }       @Override    public void undelete(ID id) throws Exception {        for (Class<?> clazz = super.entityClass; clazz != Object.class && clazz != BaseEntity.class; clazz = clazz.getSuperclass()) {            try{                PropertyDescriptor pd = new PropertyDescriptor("enable", super.entityClass);                T t = this.getRepository().findOne(id);                pd.getWriteMethod().invoke(t, true);                this.getRepository().save(t);                return;            }catch(IntrospectionException e){                continue;            }        }    }     @Override    public Boolean exist(ID id) throws Exception {        return this.getRepository().exists(id);    }     @Override    public T findOne(ID id) throws Exception {        return this.getRepository().findOne(id);    }    @Override    public T findOne(ID id,String[] fields) throws Exception{        CriteriaBuilder cb = em.getCriteriaBuilder();        CriteriaQuery<?> query = cb.createQuery();        Root<T> root = query.from(super.entityClass);        query.where(cb.equal(root.get("id"), id));        //查询字段        if(fields == null || fields.length == 0){            query.multiselect(root);            return (T) em.createQuery(query.multiselect(root)).getSingleResult();        }else{            List<Selection<?>> sList = new ArrayList<>();            for (String field : fields) {                sList.add(root.get(field));            }            query.multiselect(sList);            Object obj = em.createQuery(query).getSingleResult();            //取得查询字段列表            T t = this.createEntity(fields, obj);            return t;        }    }    @Override    public T findOne(Specification<T> spec) throws Exception{        CriteriaBuilder cb = em.getCriteriaBuilder();        CriteriaQuery<?> query = cb.createQuery();        Root<T> root = query.from(super.entityClass);        Predicate predicate = spec.toPredicate(root, query, cb);        if(predicate != null){            query.where(predicate);        }        Selection<?> selection = query.getSelection();        if(selection == null){            return (T) em.createQuery(query.multiselect(root)).getSingleResult();        }else{            Object obj = em.createQuery(query).getSingleResult();            //取得查询字段列表            String[] fields = this.findFields(query);            T t = this.createEntity(fields, obj);            return t;        }    }    @Override    public Long number() throws Exception{        return this.repository.count();    }       @Override    public Long number(Specification<T> spec) throws Exception{        CriteriaBuilder cb = em.getCriteriaBuilder();        CriteriaQuery<Long> query = cb.createQuery(Long.class);        Root<T> root = query.from(super.entityClass);        Predicate predicate = spec.toPredicate(root, query, cb);        if(predicate != null){            query.where(predicate);        }        Long total = em.createQuery(query.multiselect(cb.count(root))).getSingleResult();        return total;    }    @Override    public List<T> findAll() throws Exception {        return this.getRepository().findAll();    }    @Override    public List<T> findAll(Specification<T> spec) throws Exception{        CriteriaBuilder cb = em.getCriteriaBuilder();        CriteriaQuery<?> query = cb.createQuery();        Root<T> root = query.from(super.entityClass);        Predicate predicate = spec.toPredicate(root, query, cb);        if(predicate != null){            query.where(predicate);        }        Selection<?> selection = query.getSelection();        if(selection == null){            return (List<T>) em.createQuery(query.multiselect(root)).getResultList();        }else{            //得到Object[]值列表            List<Object> list = (List<Object>) em.createQuery(query).getResultList();            //取得查询字段列表            String[] fields = this.findFields(query);            //通过字段列表对应值列表创建实体对象            List<T> content = new ArrayList<>();            for (Object obj : list) {                T t = this.createEntity(fields, obj);                content.add(t);            }            return content;        }    }    @Override    public Page<T> findAll(Specification<T> spec,Pageable pageable) throws Exception{        CriteriaBuilder cb = em.getCriteriaBuilder();        CriteriaQuery<?> query = cb.createQuery();        Root<T> root = query.from(super.entityClass);        Predicate predicate = spec.toPredicate(root, query, cb);        if(predicate != null){            query.where(predicate);        }        Selection<?> selection = query.getSelection();        List<T> content = null;        Long total = null;        if(selection == null){            content =  (List<T>) em.createQuery(query.multiselect(root)).getResultList();            total = (Long) em.createQuery(query.multiselect(cb.count(root))).getSingleResult();        }else{            content = new ArrayList<>();            //得到Object[]值列表            List<Object> list = (List<Object>) em.createQuery(query)                    .setFirstResult(pageable.getOffset()*pageable.getPageSize())                    .setMaxResults(pageable.getPageSize())                    .getResultList();            String[] fields = findFields(query);            //通过字段列表对应值列表创建实体对象            for (Object obj : list) {                T t = this.createEntity(fields, obj);                content.add(t);            }            //取得总数            total = (Long) em.createQuery(query.multiselect(cb.count(root))).getSingleResult();        }        return new PageImpl<>(content, pageable, total);    }    private T createEntity(String[] fields, Object obj) throws Exception{        T t = super.entityClass.newInstance();        if(obj instanceof Object[]){            Object[] objs = (Object[])obj;            for (int i = 0; i < objs.length; i++) {                PropertyDescriptor pd = new PropertyDescriptor(fields[i], super.entityClass);                pd.getWriteMethod().invoke(t, objs[i]);            }        }else{            PropertyDescriptor pd = new PropertyDescriptor(fields[0], super.entityClass);            pd.getWriteMethod().invoke(t, obj);        }        return t;    }    private String[] findFields(CriteriaQuery<?> query ) throws Exception{        List<String> fields = new ArrayList<>();        Selection<?> selection = query.getSelection();        if(selection.isCompoundSelection()){            List<Selection<?>> selectionList = query.getSelection().getCompoundSelectionItems();            for (Selection<?> selection2 : selectionList) {                SingularAttributePath<T> path = (SingularAttributePath<T>)selection2;                fields.add(path.getAttribute().getName());            }        }else{            SingularAttributePath<T> path = (SingularAttributePath<T>)selection;            fields.add(path.getAttribute().getName());        }        return fields.toArray(new String[fields.size()]);    }}