jpa 联表查询 返回自定义对象 hql语法 原生sql 语法 1.11.9版本
-----业务场景中经常涉及到联查,jpa的hql语法提供了内连接的查询方式(不支持复杂hql,比如left join ,right join). 上代码了
1.我们要联查房屋和房屋用户中间表,通过房屋id关联 homeInfo是房屋表,homeUser是房屋用户中间表.
homeInfo
1 package management.entity.carandhome; 2 3 import java.io.Serializable; 4 import java.math.BigDecimal; 5 import java.util.ArrayList; 6 import java.util.Date; 7 import java.util.HashSet; 8 import java.util.List; 9 import java.util.Set; 10 11 import javax.persistence.Entity; 12 import javax.persistence.FetchType; 13 import javax.persistence.GeneratedValue; 14 import javax.persistence.Id; 15 import javax.persistence.JoinColumn; 16 import javax.persistence.JoinTable; 17 import javax.persistence.ManyToMany; 18 import javax.persistence.OneToMany; 19 import javax.persistence.OneToOne; 20 import javax.persistence.Table; 21 22 import org.hibernate.annotations.NotFound; 23 import org.hibernate.annotations.NotFoundAction; 24 25 import com.alibaba.fastjson.annotation.JSONField; 26 import management.entity.paymentfee.LifeFee; 27 import management.entity.paymentfee.ManageFee; 28 29 @Entity 30 @Table(name = "t_ss_w_home") 31 // 房屋信息表 32 public class HomeInfo implements Serializable { 33 34 /** 35 * 36 */ 37 private static final long serialVersionUID = 1L; 38 39 public HomeInfo() { 40 super(); 41 // TODO Auto-generated constructor stub 42 } 43 44 45 @Id 46 @GeneratedValue 47 // 房屋ID 48 private Long homeID; 49 50 // 用户id,这个是标识房主的用户id,关联表查询出来的房主不靠谱 51 private Long userID; 52 53 // @NotNull 54 // @Size(min = 3, max = 16) 55 // 房屋面积 56 private BigDecimal grossArea; 57 58 // 实际面积 59 private BigDecimal realArea; 60 61 // 户型 62 private String houseType; 63 64 // 朝向 65 private String orientaion; 66 67 // 入住时间 68 @JSONField(format = "yyyy-MM-dd") 69 private Date chechTime; 70 71 // 楼号 72 private String homeNo; 73 74 // 单元号 75 private String homeUnit; 76 77 // 房间号 78 private String homeRoom; 79 80 // 手机号 81 private String mobileNo; 82 83 // 备注 84 private String homeRemark; 85 86 // 房屋状态 87 private String homeState; 88 89 // 房产性质 90 private String homeNature; 91 92 // 楼层 93 private String homeFloor; 94 95 // 房屋位置 96 private String homeLo; 97 98 public Long getUserID() { 99 return userID; 100 } 101 102 public void setUserID(Long userID) { 103 this.userID = userID; 104 } 105 // 106 107 @OneToMany(fetch = FetchType.EAGER, mappedBy = "homeInfo") 108 @NotFound(action = NotFoundAction.IGNORE) 109 private Set<HomeUser> homeUserList = new HashSet<>(); 110 111 @OneToMany(mappedBy = "homeInfo", fetch = FetchType.EAGER) 112 @NotFound(action = NotFoundAction.IGNORE) 113 private Set<ManageFee> manageFeeList = new HashSet<>(); 114 115 @OneToMany(mappedBy = "homeInfo", fetch = FetchType.EAGER) 116 @NotFound(action = NotFoundAction.IGNORE) 117 private Set<LifeFee> lifeFeeList = new HashSet<>(); 118 119 @NotFound(action = NotFoundAction.IGNORE) 120 @OneToOne(fetch = FetchType.EAGER) 121 @JoinColumn(name = "homeID", referencedColumnName = "homeID", insertable = false, updatable = false) 122 private HouseConfirm houseConfirm; 123 124 public List<HomeUser> getHomeUserList() { 125 return new ArrayList<>(homeUserList); 126 } 127 128 public void setHomeUserList(Set<HomeUser> homeUserList) { 129 this.homeUserList = homeUserList; 130 } 131 132 public Long getHomeID() { 133 return homeID; 134 } 135 136 public void setHomeID(Long homeID) { 137 this.homeID = homeID; 138 } 139 140 public BigDecimal getGrossArea() { 141 return grossArea; 142 } 143 144 public void setGrossArea(BigDecimal grossArea) { 145 this.grossArea = grossArea; 146 } 147 148 public BigDecimal getRealArea() { 149 return realArea; 150 } 151 152 public void setRealArea(BigDecimal realArea) { 153 this.realArea = realArea; 154 } 155 156 public String getHouseType() { 157 return houseType; 158 } 159 160 public void setHouseType(String houseType) { 161 this.houseType = houseType; 162 } 163 164 public String getOrientaion() { 165 return orientaion; 166 } 167 168 public void setOrientaion(String orientaion) { 169 this.orientaion = orientaion; 170 } 171 172 public Date getChechTime() { 173 return chechTime; 174 } 175 176 public void setChechTime(Date chechTime) { 177 this.chechTime = chechTime; 178 } 179 180 public String getMobileNo() { 181 return mobileNo; 182 } 183 184 public void setMobileNo(String mobileNo) { 185 this.mobileNo = mobileNo; 186 } 187 188 public String getHomeRemark() { 189 return homeRemark; 190 } 191 192 public void setHomeRemark(String homeRemark) { 193 this.homeRemark = homeRemark; 194 } 195 196 public String getHomeState() { 197 return homeState; 198 } 199 200 public void setHomeState(String homeState) { 201 this.homeState = homeState; 202 } 203 204 public String getHomeNature() { 205 return homeNature; 206 } 207 208 public void setHomeNature(String homeNature) { 209 this.homeNature = homeNature; 210 } 211 212 public String toString() { 213 return "{homeState:" + this.homeState + "}"; 214 } 215 216 public String getHomeLo() { 217 return homeLo; 218 } 219 220 public void setHomeLo(String homeLo) { 221 this.homeLo = homeLo; 222 } 223 224 public List<ManageFee> getManageFeeList() { 225 return new ArrayList<>(manageFeeList); 226 } 227 228 public void setManageFeeList(Set<ManageFee> manageFeeList) { 229 this.manageFeeList = manageFeeList; 230 } 231 232 public List<LifeFee> getLifeFeeList() { 233 return new ArrayList<>(lifeFeeList); 234 } 235 236 public void setLifeFeeList(Set<LifeFee> lifeFeeList) { 237 this.lifeFeeList = lifeFeeList; 238 } 239 240 public String getHomeNo() { 241 return homeNo; 242 } 243 244 public void setHomeNo(String homeNo) { 245 this.homeNo = homeNo; 246 } 247 248 public String getHomeUnit() { 249 return homeUnit; 250 } 251 252 public void setHomeUnit(String homeUnit) { 253 this.homeUnit = homeUnit; 254 } 255 256 public String getHomeRoom() { 257 return homeRoom; 258 } 259 260 public void setHomeRoom(String homeRoom) { 261 this.homeRoom = homeRoom; 262 } 263 264 public String getHomeFloor() { 265 return homeFloor; 266 } 267 268 public void setHomeFloor(String homeFloor) { 269 this.homeFloor = homeFloor; 270 } 271 272 public HouseConfirm getHouseConfirm() { 273 return houseConfirm; 274 } 275 276 public void setHouseConfirm(HouseConfirm houseConfirm) { 277 this.houseConfirm = houseConfirm; 278 } 279 280 }
homeUser
1 package management.entity.carandhome; 2 3 import com.alibaba.fastjson.annotation.JSONField; 4 import com.fasterxml.jackson.annotation.JsonIgnore; 5 import org.hibernate.annotations.NotFound; 6 import org.hibernate.annotations.NotFoundAction; 7 8 import javax.persistence.*; 9 import java.io.Serializable; 10 11 @Entity 12 @Table(name = "t_ss_w_home_user") 13 public class HomeUser implements Serializable { 14 15 /** 16 * 17 */ 18 private static final long serialVersionUID = 1L; 19 20 21 @Id 22 @GeneratedValue 23 private Long homeUserID; 24 25 private Long userID; 26 27 private Long homeID; 28 29 @JSONField 30 @JsonIgnore 31 @ManyToOne 32 @JoinColumn(name = "homeID", insertable = false, updatable = false) 33 @NotFound(action = NotFoundAction.IGNORE) 34 private HomeInfo homeInfo; 35 36 public HomeUser() { 37 super(); 38 } 39 40 public HomeInfo getHomeInfo() { 41 return homeInfo; 42 } 43 44 public void setHomeInfo(HomeInfo homeInfo) { 45 this.homeInfo = homeInfo; 46 } 47 48 public Long getHomeUserID() { 49 return homeUserID; 50 } 51 52 public void setHomeUserID(Long homeUserID) { 53 this.homeUserID = homeUserID; 54 } 55 56 public Long getUserID() { 57 return userID; 58 } 59 60 public void setUserID(Long userID) { 61 this.userID = userID; 62 } 63 64 public Long getHomeID() { 65 return homeID; 66 } 67 68 public void setHomeID(Long homeID) { 69 this.homeID = homeID; 70 } 71 72 @Override 73 public String toString() { 74 return "HomeUser [homeUserID=" + homeUserID + ", userID=" + userID + ", homeID=" + homeID + "]"; 75 } 76 77 }
自定义的联查结果实体类
1 package management.entity.carandhome; 2 3 import java.io.Serializable; 4 import java.math.BigDecimal; 5 import java.util.ArrayList; 6 import java.util.Date; 7 import java.util.HashSet; 8 import java.util.List; 9 import java.util.Set; 10 11 import javax.persistence.Entity; 12 import javax.persistence.FetchType; 13 import javax.persistence.GeneratedValue; 14 import javax.persistence.Id; 15 import javax.persistence.JoinColumn; 16 import javax.persistence.JoinTable; 17 import javax.persistence.ManyToMany; 18 import javax.persistence.OneToMany; 19 import javax.persistence.OneToOne; 20 import javax.persistence.Table; 21 22 import org.hibernate.annotations.NotFound; 23 import org.hibernate.annotations.NotFoundAction; 24 25 import com.alibaba.fastjson.annotation.JSONField; 26 import management.entity.paymentfee.LifeFee; 27 import management.entity.paymentfee.ManageFee;
31 public class HomeUserAppVO implements Serializable { 32 33 /** 34 * 35 */ 36 private static final long serialVersionUID = 1L; 37 38 public HomeUserAppVO() { 39 super(); 40 }
// 这个构造方法必须有, 且要与后面的联查hql语句对应 41 public HomeUserAppVO(Long homeID, String homeNo, String homeUnit, String homeRoom, String mobileNo, 42 String homeState, String homeNature, String homeFloor, String homeLo) { 43 super(); 44 this.homeID = homeID; 45 this.homeNo = homeNo; 46 this.homeUnit = homeUnit; 47 this.homeRoom = homeRoom; 48 this.mobileNo = mobileNo; 49 this.homeState = homeState; 50 this.homeNature = homeNature; 51 this.homeFloor = homeFloor; 52 this.homeLo = homeLo; 53 } 54 private Long homeID; 55 56 // 楼号 57 private String homeNo; 58 59 // 单元号 60 private String homeUnit; 61 62 // 房间号 63 private String homeRoom; 64 65 // 手机号 66 private String mobileNo; 67 68 69 // 房屋状态 70 private String homeState; 71 72 // 房产性质 73 private String homeNature; 74 75 // 楼层 76 private String homeFloor; 77 78 // 房屋位置 79 private String homeLo; 80 // 用户角色(房主,家人,租客) 81 private String familyRelationship; 82 public Long getHomeID() { 83 return homeID; 84 } 85 public void setHomeID(Long homeID) { 86 this.homeID = homeID; 87 } 88 public String getHomeNo() { 89 return homeNo; 90 } 91 public void setHomeNo(String homeNo) { 92 this.homeNo = homeNo; 93 } 94 public String getHomeUnit() { 95 return homeUnit; 96 } 97 public void setHomeUnit(String homeUnit) { 98 this.homeUnit = homeUnit; 99 } 100 public String getHomeRoom() { 101 return homeRoom; 102 } 103 public void setHomeRoom(String homeRoom) { 104 this.homeRoom = homeRoom; 105 } 106 public String getMobileNo() { 107 return mobileNo; 108 } 109 public void setMobileNo(String mobileNo) { 110 this.mobileNo = mobileNo; 111 } 112 public String getHomeState() { 113 return homeState; 114 } 115 public void setHomeState(String homeState) { 116 this.homeState = homeState; 117 } 118 public String getHomeNature() { 119 return homeNature; 120 } 121 public void setHomeNature(String homeNature) { 122 this.homeNature = homeNature; 123 } 124 public String getHomeFloor() { 125 return homeFloor; 126 } 127 public void setHomeFloor(String homeFloor) { 128 this.homeFloor = homeFloor; 129 } 130 public String getHomeLo() { 131 return homeLo; 132 } 133 public void setHomeLo(String homeLo) { 134 this.homeLo = homeLo; 135 } 136 public String getFamilyRelationship() { 137 return familyRelationship; 138 } 139 public void setFamilyRelationship(String familyRelationship) { 140 familyRelationship = familyRelationship; 141 } 142 @Override 143 public String toString() { 144 return "HomeUserAppVO [homeID=" + homeID + ", homeNo=" + homeNo + ", homeUnit=" + homeUnit + ", homeRoom=" 145 + homeRoom + ", mobileNo=" + mobileNo + ", homeState=" + homeState + ", homeNature=" + homeNature 146 + ", homeFloor=" + homeFloor + ", homeLo=" + homeLo + ", FamilyRelationship=" + familyRelationship 147 + "]"; 148 } 149 150 }
2.实体类建好,这里我们直接写持久层代码
package management.dao.carandhome; import java.math.BigDecimal; import java.util.Date; import java.util.List; import java.util.Set; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; import management.dao.BaseDao; import management.entity.carandhome.HomeInfo; import management.entity.carandhome.HomeUserAppVO; import management.vo.carHome.HomeInfoVO; @Repository public interface HomeInfoDao extends BaseDao<HomeInfo> { //联查,返回自定义对象,使用hql语句. 这里需要注意三点【1.new 全类路径名(属性1,属性2) 2.属性名称要与实体类一一对应,大小写都不能差,否则会报异常 3.自定义类的构造方法里的字段要与这里一一对应】 @Query( value = "select new management.entity.carandhome.HomeUserAppVO(h.homeID,h.homeNo,h.homeUnit,h.homeRoom," + "h.mobileNo,h.homeState,h.homeNature,h.homeFloor,h.homeLo) from HomeInfo h , HomeUser hu where h.homeID=hu.homeID" + " and hu.userID=:id") List<HomeUserAppVO> findHomeInfoByUserId(@Param("id") Long id); // 原生sql联查语句写法,但是返回对象是一个object【】,因为使用了原生语句,只能自己再去一一对应,然后封装到自己的业务bean中。 @Query( value = "SELECT " + " h.*, t.countUser " + "FROM " + " ( " + " SELECT " + " hu.HomeID homeID, " + " count(hu.UserID) countUser " + " FROM " + " ( " + " SELECT " + " hu.HomeID homeID " + " FROM " + " t_ss_w_home_user hu " + " WHERE " + " hu.UserID = :userID " + " ) t " + " LEFT JOIN t_ss_w_home_user hu ON hu.HomeID = t.homeID " + " GROUP BY " + " hu.HomeID " + " ) t " + "LEFT JOIN t_ss_w_home h ON t.homeID = h.HomeID", nativeQuery = true) List<Object[]> findByUserIdAndCountUser(@Param("userID") Long userID); }
4.再写原生的sql时,别名 如果不能使用,需要在连接mysql配置时 增加 useOldAliasMetadataBehavior=true(有此问题的需要加,没有的就不用,我的版本不用,这里顺带提一下)
url: jdbc:mysql://mysql:3306/property_manager?useUnicode=true&characterEncoding=utf-8&useOldAliasMetadataBehavior=true