需求:我有一个实体类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版权协议,转载请附上原文出处链接和本声明。