hibernate+jpa 联表查询

需求:我有一个实体类WarningConfig,其中的sceneId,checkItemId为外键,分别关联Scene和CheckItem实体类的主键,现在要查询WarningConfig其中几个字段和Scene的name字段、CheckItem的name字段。 如何利用hibernate+jpa进行联表查询?

第一种:比较蠢的就是在WarningConfig类中加两个字段

    @Transient
	private String sceneName;
	@Transient
	private String checkItemName;

@Transient 表示在进行增删改查的时候,不操作该注解下的字段。

然后查询 WarningConfig的数据,放在集合中,然后再遍历这个集合,对应的拿到sceneId,checkItemId再去查,然后赋给WarningConfig

private void setProperties(WarningConfig warningConfig){
        if(warningConfig.getCheckItemId()!=null)
        {
            Map<Object,Object> checkMap=(Map<Object, Object>) dataSearchClient.getCheckitemById(warningConfig.getCheckItemId()).getData();
            warningConfig.setCheckItemName((String)checkMap.get("name"));
        }
        if(warningConfig.getSceneId()!=null) {
            Map<Object, Object> sceneMap = (Map<Object, Object>) collequipmentClient.getSceneById(warningConfig.getSceneId()).getData();

            warningConfig.setSceneName((String)sceneMap.get("name"));
        }
    }

我们都是追求效率和整洁的程序猿啦,对于这种方法绝不随意!
第二种:就是利用hibernate的联表查询了

@Entity
@Table(name="ift_warning_config")
//注意关联的表都要加这个注解@JsonIgnoreProperties,否则会报下面的错
//No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer
@JsonIgnoreProperties({"hibernateLazyInitializer","handler"})
public class WarningConfig implements Serializable{

	@Id
	private String id;//编号

	private String sceneId;//所属场景编号
	private String checkItemId;//检测项目
	.....

	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "sceneId",referencedColumnName="id",insertable = false,updatable = false)
	private Scene scene;

	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "checkItemId",referencedColumnName="id",insertable = false,updatable = false)
	private CheckItem checkItem;
	
//setter、getter、constructor省略  
//  特别是链联表的对象,必需要有set方法,不然数据不会放进去

但这样的查询会把关联的几个表的所有字段都查询出来。

{
      "id": "24887c3f52754235b3c1b23704e4de06",
      "sceneId": "11cebf3299c14105a5ee4071a349da77",
      "checkItemId": "2",
      ......
     
      "scene": {
        "id": "11cebf3299c14105a5ee4071a349da77",
        "name": "hhh",
        ......
      },
      "checkItem": {
        "id": "2",
        "name": "PH",
       ....
      }
    },

如果数据一多,查询全部字段肯定很慢。我们不随意!
第三种:自己再创建一个类,里面装需要查询的字段

@Entity
public class WarningVo implements Serializable{
    @Id
    private String id;// WarningConfig 编号

    private String sceneId;
    private String checkItemId;
    private String sceneName;
 	private String checkItemName;

实现dao

public interface WarningConfigVoDao extends JpaRepository<WarningVo,String>,JpaSpecificationExecutor<WarningVo>{
    String sql="SELECT ift_warning_config.id,ift_warning_config.checkItemId,ift_warning_config.sceneId,ift_warning_config.maxValue,ift_warning_config.`minValue`,ift_warning_config.isUse,item.`name` as checkItemName,scene.`name` as sceneName " +
            " from ift_warning_config,ift_check_item as item,ift_scene as scene " +
            "where ift_warning_config.sceneId=scene.id and ift_warning_config.checkItemId=item.id";

    @Query(value =sql,nativeQuery = true)
    List<WarningVo> getWarningVoList();
    @Query(value = sql,nativeQuery = true)
    Page<WarningVo> getWarningVoPageByCondition(Specification specification,Pageable pageRequest);
}

查询后返回的数据

{
      "id": "24887c3f52754235b3c1b23704e4de06",
      "sceneId": "11cebf3299c14105a5ee4071a349da77",
      "checkItemId": "2",
      "sceneName": "hhh",
      "checkItemName": "PH"
      ....
    },

这样效率快,不用加那么多注解,代码也整洁,返回的字段也只是自己想要的字段,完美!


版权声明:本文为yd_mmfly原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。