JPA实体与DTO与实体图:最适合使用的时间和

时间:2018-06-19 10:21:52

标签: java hibernate jpa

Father.java

package com.jpalearn.model;

import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.NamedAttributeNode;
import javax.persistence.NamedEntityGraph;
import javax.persistence.NamedEntityGraphs;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.PreRemove;
import javax.persistence.Table;

import org.hibernate.annotations.GenericGenerator;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.jpalearn.utils.JpaLearnMethodUtils;
import com.jpalearn.utils.JpaLearnVariableUtils;

@NamedQueries({ 
    @NamedQuery(name = "father.findAll", query = "SELECT f FROM Father f") 
  })

@NamedEntityGraphs({
    @NamedEntityGraph(
            name = "graph.father.setOfChildrens", 
            attributeNodes = @NamedAttributeNode(value = "setOfChildrens")),
})

@Entity
@Table(name = JpaLearnVariableUtils.TABLE_NAME_FOR_FATHER)
@JsonInclude(Include.NON_EMPTY)
public class Father {

    @Id
    @GeneratedValue(generator = "system-uuid")
    @GenericGenerator(name = "system-uuid", strategy = "uuid")
    @Column(name = "fatherId", nullable = false, insertable = false, updatable = false)
    private String id;

    @Column(name = "name", columnDefinition = "varchar(300)")
    private String name;

    public Father() {}

    public Father(String name) {
        super();
        this.name = name;
    }

    public Father(String id, String name) {
        super();
        this.id = id;
        this.name = name;
    }

    public Father(String id, String name, Set<Children> setOfChildrens) {
        super();
        this.id = id;
        this.name = name;
        this.setOfChildrens = setOfChildrens;
    }

    @OneToMany(mappedBy = "father") // children
    private Set<Children> setOfChildrens;

    @PreRemove
    protected void preRemove() {
        Set<Children> setOfChildrens = getSetOfChildrens();
        if (!JpaLearnMethodUtils.isSetIsNullOrEmpty(setOfChildrens)) {
            setOfChildrens.forEach(children -> {
                children.setFather(null);
            });
        }
    }

    getter()
    setter()
}

Children.java

package com.jpalearn.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.PreRemove;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.hibernate.annotations.GenericGenerator;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.jpalearn.utils.JpaLearnMethodUtils;
import com.jpalearn.utils.JpaLearnVariableUtils;

@Entity
@Table(name = JpaLearnVariableUtils.TABLE_NAME_FOR_CHILDREN)
@JsonInclude(Include.NON_EMPTY)
public class Children {

    @Id
    @GeneratedValue(generator = "system-uuid")
    @GenericGenerator(name = "system-uuid", strategy = "uuid")
    @Column(name = "childrenId", nullable = false, insertable = false, updatable = false)
    private String id;

    @Column(name = "name", columnDefinition = "varchar(300)")
    private String name;

    public Children() {
    }

    public Children(String id, String name) {
        super();
        this.id = id;
        this.name = name;
    }

    public Children(String name, Father father) {
        super();
        this.name = name;
        this.father = father;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JsonIgnore
    private Father father;
    @Transient
    private String idOfFather;

    @PreRemove
    protected void preRemove() {
        Father father = getFather();
        if (!JpaLearnMethodUtils.isObjectisNullOrEmpty(father)) {
            father.getSetOfChildrens().remove(this);
        }
    }

    getter()
    setter()
}

FatherDTO.java

package com.jpalearn.dto;
import java.util.Set;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;

@JsonInclude(Include.NON_EMPTY)
public class FatherDTO {

    private String id;
    private String name;
    private Set<ChildrenDTO> setOfChildrens;

    public FatherDTO() {}

    public FatherDTO(String id, String name) {
        super();
        this.id = id;
        this.name = name;
    }

    getter()
    setter()
}

ChildrenDTO.java

package com.jpalearn.dto;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;

@JsonInclude(Include.NON_EMPTY)
public class ChildrenDTO {

    private String id;
    private String name;

    public ChildrenDTO() {
    }

    public ChildrenDTO(String id, String name) {
        super();
        this.id = id;
        this.name = name;
    }
    getter()
    setter()
}

FatherDao.java

package com.jpalearn.dao;

import java.util.List;
import com.jpalearn.dto.FatherDTO;
import com.jpalearn.model.Father;

public interface FatherDao extends GenericModelDao<Father> {

    // get all fathers Using Entity
    public List<Father> getAllFathersWithChildrensUsingEntity();

    // get all fathers using DTO
    public List<FatherDTO> getAllFathersWithChildrensUsingDTO();

    // get all fathers using Entity Graph
    public List<Father> getAllFathersWithChildrensUsingEntityGraph();
}

FatherDaoImpl.java

package com.jpalearn.dao.impl;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import javax.inject.Named;
import javax.persistence.EntityGraph;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import com.jpalearn.dao.FatherDao;
import com.jpalearn.dto.ChildrenDTO;
import com.jpalearn.dto.FatherDTO;
import com.jpalearn.model.Children;
import com.jpalearn.model.Children_;
import com.jpalearn.model.Father;
import com.jpalearn.model.Father_;
import com.jpalearn.utils.JpaLearnMethodUtils;

@Named
public class FatherDaoImpl extends GenericModelDaoImpl<Father> implements FatherDao {

    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public List<Father> getAllFathersWithChildrensUsingEntity() {
        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
        CriteriaQuery<Father> criteriaQueryForFather = criteriaBuilder.createQuery(Father.class);
        Root<Father> rootForFather = criteriaQueryForFather.from(Father.class);
        Path<String> pathForId = rootForFather.get(Father_.id);
        Path<String> pathForName = rootForFather.get(Father_.name);
        criteriaQueryForFather.multiselect(pathForId, pathForName);
        TypedQuery<Father> typedQuery = entityManager.createQuery(criteriaQueryForFather);
        List<Father> listOFFathers = typedQuery.getResultList();

        if (!JpaLearnMethodUtils.isListIsNullOrEmpty(listOFFathers)) {
            listOFFathers.forEach(father -> {

                CriteriaQuery<Children> criteriaQueryForChildren = criteriaBuilder.createQuery(Children.class);
                Root<Children> rootForChildren = criteriaQueryForChildren.from(Children.class);
                Join<Children, Father> joinChildrenWithFather = rootForChildren.join(Children_.father);
                Predicate predicateForFatherId = criteriaBuilder.equal(joinChildrenWithFather.get(Father_.id),
                        father.getId());
                Path<String> pathForChildId = rootForChildren.get(Children_.id);
                Path<String> pathForChildName = rootForChildren.get(Children_.name);
                criteriaQueryForChildren.multiselect(pathForChildId, pathForChildName);
                criteriaQueryForChildren.where(predicateForFatherId);
                TypedQuery<Children> typedQueryForChildren = entityManager.createQuery(criteriaQueryForChildren);
                List<Children> listOFChildrens = typedQueryForChildren.getResultList();
                father.setSetOfChildrens(new HashSet<>(listOFChildrens));
            });
        }

        return JpaLearnMethodUtils.isListIsNullOrEmpty(listOFFathers) ? new ArrayList<>() : listOFFathers;
    }

    @Override
    public List<FatherDTO> getAllFathersWithChildrensUsingDTO() {

        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
        CriteriaQuery<FatherDTO> criteriaQueryForFatherDTO = criteriaBuilder.createQuery(FatherDTO.class);
        Root<Father> rootForFather = criteriaQueryForFatherDTO.from(Father.class);
        Path<String> pathForId = rootForFather.get(Father_.id);
        Path<String> pathForName = rootForFather.get(Father_.name);
        criteriaQueryForFatherDTO.multiselect(pathForId, pathForName);
        TypedQuery<FatherDTO> typedQuery = entityManager.createQuery(criteriaQueryForFatherDTO);
        List<FatherDTO> listOFFatherDTOs = typedQuery.getResultList();

        if (!JpaLearnMethodUtils.isListIsNullOrEmpty(listOFFatherDTOs)) {
            listOFFatherDTOs.forEach(fatherDto -> {

                CriteriaQuery<ChildrenDTO> criteriaQueryForChildrenDTO = criteriaBuilder.createQuery(ChildrenDTO.class);
                Root<Children> rootForChildren = criteriaQueryForChildrenDTO.from(Children.class);
                Join<Children, Father> joinChildrenWithFather = rootForChildren.join(Children_.father);
                Predicate predicateForFatherId = criteriaBuilder.equal(joinChildrenWithFather.get(Father_.id),
                        fatherDto.getId());
                Path<String> pathForChildId = rootForChildren.get(Children_.id);
                Path<String> pathForChildName = rootForChildren.get(Children_.name);
                criteriaQueryForChildrenDTO.multiselect(pathForChildId, pathForChildName);
                criteriaQueryForChildrenDTO.where(predicateForFatherId);
                TypedQuery<ChildrenDTO> typedQueryForChildrenDTO = entityManager
                        .createQuery(criteriaQueryForChildrenDTO);
                List<ChildrenDTO> listOFChildrenDTOs = typedQueryForChildrenDTO.getResultList();
                fatherDto.setSetOfChildrens(new HashSet<>(listOFChildrenDTOs));
            });
        }

        return JpaLearnMethodUtils.isListIsNullOrEmpty(listOFFatherDTOs) ? new ArrayList<>() : listOFFatherDTOs;
    }

    @SuppressWarnings({ "rawtypes" })
    @Override
    public List<Father> getAllFathersWithChildrensUsingEntityGraph() {

        CriteriaBuilder builder = entityManager.getCriteriaBuilder();
        CriteriaQuery<Father> criteriaQueryForFatherDTOs = builder.createQuery(Father.class);
        Root<Father> rootForFather = criteriaQueryForFatherDTOs.from(Father.class);
        criteriaQueryForFatherDTOs.select(rootForFather).distinct(true);
        TypedQuery<Father> typedQuery = entityManager.createQuery(criteriaQueryForFatherDTOs);
        EntityGraph graph = entityManager.getEntityGraph("graph.father.setOfChildrens");
        typedQuery.setHint("javax.persistence.fetchgraph", entityManager.getEntityGraph("graph.father.setOfChildrens"));
        List<Father> listOfFathers = typedQuery.getResultList();
        return listOfFathers;
    }

}

FatherService.java

package com.jpalearn.service;

import java.util.List;
import com.jpalearn.dto.FatherDTO;
import com.jpalearn.model.Father;

public interface FatherService {

    public void saveFather(Father father);

    // get all fathers using Entity
    public List<Father> getAllFathersWithChildrensUsingEntity();

    // get all fathers using DTO
    public List<FatherDTO> getAllFathersWithChildrensUsingDTO();

    // get all fathers using Entity Graph
    public List<Father> getAllFathersWithChildrensUsingEntityGraph();
}

FatherServiceImpl.java

package com.jpalearn.service.impl;

import java.util.List;
import javax.inject.Inject;
import javax.inject.Named;
import org.springframework.transaction.annotation.Transactional;
import com.jpalearn.dao.FatherDao;
import com.jpalearn.dto.FatherDTO;
import com.jpalearn.model.Father;
import com.jpalearn.service.FatherService;

@Named
public class FatherServiceImpl implements FatherService {

    @Inject
    private FatherDao fatherDao;

    @Transactional
    @Override
    public void saveFather(Father father) {
        fatherDao.save(father);
    }

    @Override
    public List<Father> getAllFathersWithChildrensUsingEntity() {
        return fatherDao.getAllFathersWithChildrensUsingEntity();
    }

    @Override
    public List<FatherDTO> getAllFathersWithChildrensUsingDTO() {
        return fatherDao.getAllFathersWithChildrensUsingDTO();
    }

    @Override
    public List<Father> getAllFathersWithChildrensUsingEntityGraph() {
        return fatherDao.getAllFathersWithChildrensUsingEntityGraph();
    }

}

FatherController.java

package com.jpalearn.controller;

import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.jpalearn.dto.FatherDTO;
import com.jpalearn.model.Father;
import com.jpalearn.service.FatherService;

@Controller
public class FatherController {

    @Inject
    private FatherService fatherService;


    @CrossOrigin
    @RequestMapping(value = "/getAllFathersWithChildrensUsingEntity", method = RequestMethod.GET)
    @ResponseBody
    public List<Father> getAllFathersWithChildrensUsingEntity() {
        try {
            return fatherService.getAllFathersWithChildrensUsingEntity();

        } catch (Exception e) {
            e.printStackTrace();
            return new ArrayList<>();
        }
    }

    @CrossOrigin
    @RequestMapping(value = "/getAllFathersWithChildrensUsingDTO", method = RequestMethod.GET)
    @ResponseBody
    public List<FatherDTO> getAllFathersWithChildrensUsingDTO() {
        try {
            return fatherService.getAllFathersWithChildrensUsingDTO();

        } catch (Exception e) {
            e.printStackTrace();
            return new ArrayList<>();
        }
    }

    @CrossOrigin
    @RequestMapping(value = "/getAllFathersWithChildrensUsingEntityGraph", method = RequestMethod.GET)
    @ResponseBody
    public List<Father> getAllFathersWithChildrensUsingEntityGraph() {

        try {
            return fatherService.getAllFathersWithChildrensUsingEntityGraph();
        } catch (Exception e) {
            e.printStackTrace();
            return new ArrayList<>();
        }
    }
}

  1. 这里有一个父亲有多个孩子

  2. 我和其子女一起使用了3种查询

    2.1使用实体

    2.2使用DTO

    2.3使用实体图

  3. 在任何项目中,都有很多像Apis一样的

    &#39;保存&#39;,&#39;更新&#39; ,&#39;删除&#39; , &#39;获取所有记录&#39;, &#39;通过id&#39;来 &#39;获取具体记录&#39;, &#39;通过多个连接获取所有记录&#39; , &#39;通过单一加入获得所有记录&#39;等。

    所以何时使用实体,dto或实体图????

0 个答案:

没有答案