> 技术文档 > [尚庭公寓]14-找房模块

[尚庭公寓]14-找房模块


地区信息

对于找房模块,地区信息共需三个接口,分别是**查询省份列表**、**根据省份ID查询城市列表**、**根据城市ID查询区县列表**,具体实现如下

package com.atguigu.lease.web.app.controller.region;@Tag(name = \"地区信息\")@RestController@RequestMapping(\"/app/region\")public class RegionController { @Autowired private ProvinceInfoService provinceInfoService; @Autowired private CityInfoService cityInfoService; @Autowired private DistrictInfoService districtInfoService; @Operation(summary=\"查询省份信息列表\") @GetMapping(\"province/list\") public Result<List> listProvince(){ List list = provinceInfoService.list(); return Result.ok(list); } @Operation(summary=\"根据省份id查询城市信息列表\") @GetMapping(\"city/listByProvinceId\") public Result<List> listCityInfoByProvinceId(@RequestParam Long id){ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper(); queryWrapper.eq(CityInfo::getProvinceId,id); List list = cityInfoService.list(queryWrapper); return Result.ok(list); } @GetMapping(\"district/listByCityId\") @Operation(summary=\"根据城市id查询区县信息\") public Result<List> listDistrictInfoByCityId(@RequestParam Long id){ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper(); queryWrapper.eq(DistrictInfo::getCityId,id); List list = districtInfoService.list(queryWrapper); return Result.ok(list); }}

支付方式

package com.atguigu.lease.web.app.controller.payment;@Tag(name = \"支付方式接口\")@RestController@RequestMapping(\"/app/payment\")public class PaymentTypeController { @Autowired private PaymentTypeService paymentTypeService; @Operation(summary = \"获取全部支付方式列表\") @GetMapping(\"list\") public Result<List> list() { List list = paymentTypeService.list(); return Result.ok(list); }}

房间信息

根据条件分页查询房间列表

package com.atguigu.lease.web.app.controller.room;@Tag(name = \"房间信息\")@RestController@RequestMapping(\"/app/room\")public class RoomController { @Autowired RoomInfoService roomInfoService; @Operation(summary = \"分页查询房间列表\") @GetMapping(\"pageItem\") public Result<IPage> pageItem(@RequestParam long current, @RequestParam long size, RoomQueryVo queryVo) { IPage page = new Page(current, size); IPage list = roomInfoService.pageItem(page, queryVo); return Result.ok(); }}
package com.atguigu.lease.web.app.service.impl;/** * @author liubo * @description 针对表【room_info(房间信息表)】的数据库操作Service实现 * @createDate 2023-07-26 11:12:39 */@Service@Slf4jpublic class RoomInfoServiceImpl extends ServiceImpl implements RoomInfoService { @Autowired private RoomInfoMapper roomInfoMapper; @Override public IPage pageItem(IPage page, RoomQueryVo queryVo) { return roomInfoMapper.pageRoomItemByQuery(page, queryVo); }}
             select ri.id as room_id,  ri.room_number,  ri.rent,  ai.id,  ai.name,  ai.introduction,  ai.district_id,  ai.district_name,  ai.city_id,  ai.city_name,  ai.province_id,  ai.province_name,  ai.address_detail,  ai.latitude,  ai.longitude,  ai.phone,  ai.is_release from room_info ri  left join apartment_info ai on ri.apartment_id = ai.id and ai.is_deleted = 0  ri.is_deleted = 0 and ri.is_release = 1  and ai.province_id = #{queryVo.provinceId}   and ai.city_id = #{queryVo.cityId}   and ai.district_id = #{queryVo.districtId}   and ri.rent >= #{queryVo.minRent}   and ri.rent <= #{queryVo.maxRent}    order by ri.rent desc ${queryVo.orderType}    select id,  name,  url from graph_info where is_deleted = 0 and item_type = 2 and item_id = #{id};   select id, type, name from label_info where is_deleted = 0 and type = 2 and id in ( select label_id from room_label where room_id = #{id} and is_deleted = 1 ) 

知识点

xml文件``的转义

由于xml文件中的``是特殊符号,需要转义处理。

Mybatis-Plus分页插件注意事项

  1. 使用Mybatis-Plus的分页插件进行分页查询时,如果结果需要使用``进行映射,只能使用**[嵌套查询(Nested Select for Collection)](https://mybatis.org/mybatis-3/sqlmap-xml.html#nested-select-for-collection)**,而不能使用**[嵌套结果映射(Nested Results for Collection)](https://mybatis.org/mybatis-3/sqlmap-xml.html#nested-results-for-collection)**。
  2. **嵌套查询**和**嵌套结果映射**是Collection映射的两种方式,下面通过一个案例进行介绍
  3. 例如有`room_info`和`graph_info`两张表,其关系为一对多,如下

  1. 现需要查询房间列表及其图片信息,期望返回的结果如下
 [ {  \"id\": 1,  \"number\": 201,  \"rent\": 2000,  \"graphList\": [  {\"id\": 1,\"url\": \"http://\",\"roomId\": 1  },  {\"id\": 2,\"url\": \"http://\",\"roomId\": 1  }  ] }, {  \"id\": 2,  \"number\": 202,  \"rent\": 3000,  \"graphList\": [  {\"id\": 3,\"url\": \"http://\",\"roomId\": 2  },  {\"id\": 4,\"url\": \"http://\",\"roomId\": 2  }  ] } ]
  1. 为得到上述结果,可使用以下两种方式
嵌套结果映射  select ri.id room_id,  ri.number,  ri.rent,  gi.id graph_id,  gi.url,  gi.room_id from room_info ri  left join graph_info gi on ri.id=gi.room_id       

这种方式的执行原理如下图所示

嵌套查询  select id,  number,  rent from room_info       select id,  url,  room_id from graph_info where room_id = #{id} 

 这种方法使用两个独立的查询语句来获取一对多关系的数据。首先,Mybatis会执行主查询来获取`room_info`列表,然后对于每个`room_info`,Mybatis都会执行一次子查询来获取其对应的`graph_info`。

  1. 若现在使用MybatisPlus的分页插件进行分页查询,假如查询的内容是第**1**页,每页**2**条记录,则上述两种方式的查询结果分别是

  1. 显然**嵌套结果映射**的分页逻辑是存在问题的(数据条数少)

根据ID查询房间详细信息

package com.atguigu.lease.web.app.controller.room;@Tag(name = \"房间信息\")@RestController@RequestMapping(\"/app/room\")public class RoomController { @Autowired RoomInfoService roomInfoService; @Operation(summary = \"根据id获取房间的详细信息\") @GetMapping(\"getDetailById\") public Result getDetailById(@RequestParam Long id) { RoomDetailVo roomInfo = roomInfoService.getDetailById(id); return Result.ok(roomInfo); }}
package com.atguigu.lease.web.app.service.impl;/** * @author liubo * @description 针对表【room_info(房间信息表)】的数据库操作Service实现 * @createDate 2023-07-26 11:12:39 */@Service@Slf4jpublic class RoomInfoServiceImpl extends ServiceImpl implements RoomInfoService { @Autowired private RoomInfoMapper roomInfoMapper; @Autowired GraphInfoMapper graphInfoMapper; @Autowired LeaseTermMapper leaseTermMapper; @Autowired FacilityInfoMapper facilityInfoMapper; @Autowired LabelInfoMapper labelInfoMapper; @Autowired PaymentTypeMapper paymentTypeMapper; @Autowired AttrValueMapper attrValueMapper; @Autowired FeeValueMapper feeValueMapper; @Autowired ApartmentInfoService apartmentInfoService; @Override public RoomDetailVo getDetailById(Long id) { RoomInfo roomInfo = roomInfoMapper.selectById(id); if (roomInfo == null) { return null; } //2.查询图片 List graphVoList = graphInfoMapper.selectListByItemTypeAndId(ItemType.ROOM, id); //3.查询租期 List leaseTermList = leaseTermMapper.selectListByRoomId(id); //4.查询配套 List facilityInfoList = facilityInfoMapper.selectListByRoomId(id); //5.查询标签 List labelInfoList = labelInfoMapper.selectListByRoomId(id); //6.查询支付方式 List paymentTypeList = paymentTypeMapper.selectListByRoomId(id); //7.查询基本属性 List attrValueVoList = attrValueMapper.selectListByRoomId(id); //8.查询杂费信息 List feeValueVoList = feeValueMapper.selectListByApartmentId(roomInfo.getApartmentId()); //9.查询公寓信息 ApartmentItemVo apartmentItemVo = apartmentInfoService.selectApartmentItemVoById(roomInfo.getApartmentId()); RoomDetailVo roomDetailVo = new RoomDetailVo(); BeanUtils.copyProperties(roomInfo, roomDetailVo); roomDetailVo.setGraphVoList(graphVoList); roomDetailVo.setLeaseTermList(leaseTermList); roomDetailVo.setFacilityInfoList(facilityInfoList); roomDetailVo.setLabelInfoList(labelInfoList); roomDetailVo.setPaymentTypeList(paymentTypeList); roomDetailVo.setAttrValueVoList(attrValueVoList); roomDetailVo.setFeeValueVoList(feeValueVoList); roomDetailVo.setApartmentItemVo(apartmentItemVo); return roomDetailVo; }}
  select id, name, url from graph_info where item_type = #{room} and item_id = #{id} and is_deleted = 0 
  select * from lease_term where is_deleted = 0 and id in (select lease_term_id  from room_lease_term  where room_id = #{id} and is_deleted = 0) 
  select * from facility_info where id in ( select facility_id from room_facility where room_id = #{id}  and is_deleted = 0 ) and is_deleted = 0 
  select * from label_info where is_deleted = 0 and id in ( select label_id from room_label where room_id = #{id}  and is_deleted = 0 ) 
  select * from payment_type where id in ( select payment_type_id from room_payment_type where room_id = #{id}  and is_deleted = 0 ) and is_deleted = 0 
  select av.id,  av.name,  ak.id as attr_key_id,  ak.name as attr_key_name from attr_value av  left join attr_key ak on av.attr_key_id = ak.id and ak.is_deleted = 0 where av.id in ( select attr_value_id from room_attr_value where room_id = #{id}  and is_deleted = 0 ) and av.is_deleted = 0 
  select * from fee_value fv where fv.id in ( select fee_value_id from apartment_fee_value where apartment_id = #{apartmentId}  and is_deleted = 0 ) and fv.is_deleted = 0 
package com.atguigu.lease.web.app.service.impl;/** * @author liubo * @description 针对表【apartment_info(公寓信息表)】的数据库操作Service实现 * @createDate 2023-07-26 11:12:39 */@Servicepublic class ApartmentInfoServiceImpl extends ServiceImpl implements ApartmentInfoService { @Autowired private ApartmentInfoMapper apartmentInfoMapper; @Autowired private LabelInfoMapper labelInfoMapper; @Autowired private GraphInfoMapper graphInfoMapper; @Autowired private RoomInfoMapper roomInfoMapper; @Override public ApartmentItemVo selectApartmentItemVoById(Long apartmentId) { ApartmentInfo apartmentInfo = apartmentInfoMapper.selectById(apartmentId); List labelInfoList = labelInfoMapper.selectListByApartmentId(apartmentId); List graphVoList = graphInfoMapper.selectListByItemTypeAndId(ItemType.APARTMENT, apartmentId); BigDecimal minRent = roomInfoMapper.selectMinRentByApartmentId(apartmentId); ApartmentItemVo apartmentItemVo = new ApartmentItemVo(); BeanUtils.copyProperties(apartmentInfo, apartmentItemVo); apartmentItemVo.setLabelInfoList(labelInfoList); apartmentItemVo.setGraphVoList(graphVoList); apartmentItemVo.setMinRent(minRent); return apartmentItemVo; }}

根据公寓ID分页查询房间列表

package com.atguigu.lease.web.app.controller.room;@Tag(name = \"房间信息\")@RestController@RequestMapping(\"/app/room\")public class RoomController { @Autowired RoomInfoService roomInfoService; @Operation(summary = \"根据公寓id分页查询房间列表\") @GetMapping(\"pageItemByApartmentId\") public Result<IPage> pageItemByApartmentId(@RequestParam long current, @RequestParam long size, @RequestParam Long id) { IPage page = new Page(current, size); IPage result =roomInfoService.pageItemByApartmentId(page, id); return Result.ok(result); }}
package com.atguigu.lease.web.app.service.impl;/** * @author liubo * @description 针对表【room_info(房间信息表)】的数据库操作Service实现 * @createDate 2023-07-26 11:12:39 */@Service@Slf4jpublic class RoomInfoServiceImpl extends ServiceImpl implements RoomInfoService { @Autowired private RoomInfoMapper roomInfoMapper; @Override public IPage pageItemByApartmentId(IPage page, Long id) { IPage res = roomInfoMapper.pageItemByApartmentId(page,id); return res; }}
             select id,  name,  url from graph_info where is_deleted = 0 and item_type = 2 and item_id = #{id};   select id, type, name from label_info where is_deleted = 0 and type = 2 and id in ( select label_id from room_label where room_id = #{id}  and is_deleted = 1 )   select min(rent) from room_info where apartment_id = #{id} and is_deleted = 0 and is_release = 1   select ri.id as room_id,  ri.room_number,  ri.rent,  ai.id,  ai.name,  ai.introduction,  ai.district_id,  ai.district_name,  ai.city_id,  ai.city_name,  ai.province_id,  ai.province_name,  ai.address_detail,  ai.latitude,  ai.longitude,  ai.phone,  ai.is_release from room_info ri left join apartment_info ai on ri.apartment_id = ai.id and ai.is_deleted = 0 where ri.is_deleted = 0 and ri.is_release = 1 

公寓信息

公寓信息只需一个接口,即**根据ID查询公寓详细信息**,具体实现如下

package com.atguigu.lease.web.app.controller.apartment;@RestController@Tag(name = \"公寓信息\")@RequestMapping(\"/app/apartment\")public class ApartmentController { @Autowired ApartmentInfoService apartmentInfoService; @Operation(summary = \"根据id获取公寓信息\") @GetMapping(\"getDetailById\") public Result getDetailById(@RequestParam Long id) { ApartmentDetailVo vo = apartmentInfoService.selectApartmentDetailById(id); return Result.ok(vo); }}
package com.atguigu.lease.web.app.service.impl;/** * @author liubo * @description 针对表【apartment_info(公寓信息表)】的数据库操作Service实现 * @createDate 2023-07-26 11:12:39 */@Servicepublic class ApartmentInfoServiceImpl extends ServiceImpl implements ApartmentInfoService { @Autowired private ApartmentInfoMapper apartmentInfoMapper; @Autowired private LabelInfoMapper labelInfoMapper; @Autowired private GraphInfoMapper graphInfoMapper; @Autowired private RoomInfoMapper roomInfoMapper; @Autowired private FacilityInfoMapper facilityInfoMapper; @Override public ApartmentDetailVo selectApartmentDetailById(Long id) { ApartmentInfo apartmentInfo = apartmentInfoMapper.selectById(id); List graphVoList = graphInfoMapper.selectListByItemTypeAndId(ItemType.APARTMENT, id); List labelInfoList = labelInfoMapper.selectListByApartmentId(id); BigDecimal minRent = roomInfoMapper.selectMinRentByApartmentId(id); List facilityInfoList = facilityInfoMapper.selectListFacilityInfoByApartmentId(id); ApartmentDetailVo apartmentDetailVo = new ApartmentDetailVo(); BeanUtils.copyProperties(apartmentInfo, apartmentDetailVo); apartmentDetailVo.setGraphVoList(graphVoList); apartmentDetailVo.setLabelInfoList(labelInfoList); apartmentDetailVo.setMinRent(minRent); apartmentDetailVo.setFacilityInfoList(facilityInfoList); return apartmentDetailVo; }}
  select * from facility_info where id in ( select facility_id from apartment_facility where apartment_id = #{id}  and is_deleted = 0 ) and is_deleted = 0 

铁三角麦克风