• 22-07-04 西安 尚好房-项目经验总结(01)


    尚好房是一个二手房管理服务平台,开放优质资源和线上能力,聚合线上线下二手房产资源,打造一个全方位二手房服务生态市场,为消费者提供优质房产服务资源。

    根据演示了解项目业务

    尚好房后台管理系统:权限管理系统

    尚好房前端:找房网


    惊讶一:抽取公共的模块

    BaseController,里面真的很简单,但是考虑到以后每一个Controller都要用到封装的那俩行代码,

    在新增,修改添加成功会用得到。是用来给消费者的Controller继承的。

    1. public class BaseController {
    2. private final static String PAGE_SUCCESS = "common/successPage";
    3. public String successPage(Model model, String successMessage){
    4. model.addAttribute("messagePage",successMessage);
    5. return PAGE_SUCCESS;
    6. }
    7. }

     BaseService是用来给中间商“service-api”来继承的,

     它里面的内容是下面这样子的,继承了它就相当于Service里写了五个通用的增删改查方法

    1. public interface BaseService<T> {
    2. void insert(T t);
    3. T getById(Long id);
    4. /**
    5. * 逻辑删除
    6. * @param id
    7. */
    8. void delete(Long id);
    9. /**
    10. * 修改信息
    11. * @param t
    12. */
    13. void update(T t);
    14. /**
    15. * 分页查询信息
    16. * @param filters
    17. * @return
    18. */
    19. PageInfo<T> findPage(Map<String, Object> filters);
    20. }

    BaseServiceImpl和BaseMapper就是让服务的提供者去使用继承的。一个写具体的业务逻辑,一个写对数据库的操作。

    这里BaseServiceImpl是一个抽象类,它里面有一个抽象方法getEntityMapper(),这个方法就是为了让继承它的子类去重写它,把正真的mapper接口送给他,他好帮你去调用方法呐

    1. public abstract class BaseServiceImpl<T> {
    2. /**
    3. * 该抽象方法用来获取真实的mapper接口
    4. * @return
    5. */
    6. protected abstract BaseMapper<T> getEntityMapper();
    7. public void insert(T t) {
    8. getEntityMapper().insert(t);
    9. }
    10. @Transactional(propagation = Propagation.SUPPORTS)
    11. public T getById(Long id) {
    12. return getEntityMapper().getById(id);
    13. }
    14. public void delete(Long id) {
    15. getEntityMapper().delete(id);
    16. }
    17. public void update(T t) {
    18. getEntityMapper().update(t);
    19. }
    20. @Transactional(propagation = Propagation.SUPPORTS)
    21. public PageInfo<T> findPage(Map<String, Object> filters) {
    22. //将pageSize和pageNum强转成int类型
    23. //第二个参数表示如果强转失败给默认值
    24. int pageNum = CastUtil.castInt(filters.get("pageNum"),1);
    25. int pageSize = CastUtil.castInt(filters.get("pageSize"),10);
    26. //开启分页
    27. PageHelper.startPage(pageNum,pageSize);
    28. //调用持久层的方法查询数据集
    29. //封装返回结果,老师这里没有传第二个参数
    30. return new PageInfo<>(getEntityMapper().findPage(filters),10);
    31. }
    32. }

    最后就是这BaseMapper了,我们创建的每一个mapper接口都要去继承这个接口,这样我们的mapper接口就可以省略掉这五个最常用的方法不写了

    1. public interface BaseMapper<T> {
    2. /**
    3. * 保存一个实体
    4. * @param t
    5. */
    6. void insert(T t);
    7. /**
    8. * 通过一个标识ID 获取一个唯一实体
    9. * @param id
    10. * @return
    11. */
    12. T getById(Long id);
    13. /**
    14. *修改
    15. * @param t
    16. */
    17. void update(T t);
    18. /**
    19. * 删除
    20. * @param id
    21. */
    22. void delete(Long id);
    23. /**
    24. * 分页查询
    25. * @param filters
    26. * @return
    27. */
    28. Page<T> findPage(Map<String, Object> filters);
    29. }

    惊讶2、字典

    这个字典表本身就设计的巧妙

    这个页面的视觉效果也很nice:这种树形的目录看着很高级,实际上后端返给前端的也只是一个json数组。

    java后端代码:

    后端逻辑就很简单,根据父节点的id去查询所有的子节点,把查出来的数据用Stream流做整理。

    2021/11/12 北京 stream流,内部类,lambda表达式_£小羽毛的博客-CSDN博客

    1. public List<Map<String, Object>> findZnodes(Long id) {
    2. //1. 调用持久层方法,根据父节点id查询List<Dict>
    3. List<Dict> dictList = dictMapper.findListByParentId(id);
    4. //使用Stream流
    5. List<Map<String, Object>> znodes = dictList.stream()
    6. .map(dict -> {
    7. Map<String, Object> znode = new HashMap<>();
    8. //往znode中存放id
    9. znode.put("id", dict.getId());
    10. //往znode中存放name
    11. znode.put("name", dict.getName());
    12. //往znode中存放isParent
    13. znode.put("isParent", dictMapper.countIsParent(dict.getId()) > 0);
    14. return znode;
    15. })
    16. .collect(Collectors.toList());
    17. return znodes;
    18. }

     在SQlyog中执行如下sql:

    1. -- 根据父节点的id去查询所有的子节点
    2. SELECT * FROM hse_dict WHERE parent_id =1


    点击全部分类

    观察network,发送了这样一个请求,那不就是咱上面分析的那种情况嘛 

    http://139.198.152.148:8001/dict/findZnodes?id=1

    返给前端的json数据:实际上返回的还是json数组。

    1. {
    2. "code": 200,
    3. "data": [
    4. {
    5. "isParent": true,
    6. "name": "户型",
    7. "id": 10000
    8. },
    9. {
    10. "isParent": true,
    11. "name": "楼层",
    12. "id": 20000
    13. },
    14. {
    15. "isParent": true,
    16. "name": "建筑结构",
    17. "id": 30000
    18. },
    19. {
    20. "isParent": true,
    21. "name": "装修情况",
    22. "id": 40000
    23. },
    24. {
    25. "isParent": true,
    26. "name": "朝向",
    27. "id": 50000
    28. },
    29. {
    30. "isParent": true,
    31. "name": "房屋用途",
    32. "id": 60000
    33. },
    34. {
    35. "isParent": true,
    36. "name": "省",
    37. "id": 100000
    38. }
    39. ],
    40. "message": "成功",
    41. "ok": true
    42. }

    我们再点击户型,此时再发送请求去查询

    http://139.198.152.148:8001/dict/findZnodes?id=10000

     返给前端的json数组如下:

    1. {
    2. "code": 200,
    3. "data": [
    4. {
    5. "isParent": false,
    6. "name": "一室",
    7. "id": 10001
    8. },
    9. {
    10. "isParent": false,
    11. "name": "两室",
    12. "id": 10002
    13. },
    14. {
    15. "isParent": false,
    16. "name": "三室",
    17. "id": 10003
    18. },
    19. {
    20. "isParent": false,
    21. "name": "四室",
    22. "id": 10004
    23. },
    24. {
    25. "isParent": false,
    26. "name": "四室以上",
    27. "id": 10005
    28. }
    29. ],
    30. "message": "成功",
    31. "ok": true
    32. }

    枚举的俩种用法:

    用法1:房源的发布状态HouseStatus

    1. public enum HouseStatus {
    2. //未发布表示用户看不到,但是后台管理系统可以看得到
    3. PUBLISHED(1,"已发布"), UNPUBLISHED(0,"未发布");
    4. public int code;
    5. public String message;
    6. HouseStatus(int code, String message) {
    7. this.code = code;
    8. this.message = message;
    9. }
    10. }

    在添加房源信息的时候使用:

    1. @PostMapping("/save")
    2. public String save(House house,Model model){
    3. //未发布
    4. house.setStatus(HouseStatus.UNPUBLISHED.code);
    5. houseService.insert(house);
    6. return successPage(model,"添加房源信息成功");
    7. }

    枚举用法2:定义为私有变量。

    1. public enum DictCode {
    2. HOUSETYPE("houseType"),FLOOR("floor"),BUILDSTRUCTURE("buildStructure"),
    3. DECORATION("decoration"),DIRECTION("direction"),HOUSEUSE("houseUse");
    4. private String message;
    5. DictCode(String message) {
    6. this.message = message;
    7. }
    8. public String getMessage() {
    9. return message;
    10. }
    11. }

    使用:

    1. //3. 查询各种初始化列表:户型列表、楼层列表、装修情况列表....
    2. List<Dict> houseTypeList =
    3. dictService.findDictListByParentDictCode(DictCode.HOUSETYPE.getMessage());

    getListingDateString() House类

    在thymeleaf语法中,在请求域中是用get方法拿到值的

  • 相关阅读:
    雅马哈伺服器TS-S系列说明具体详情内容可参看PDF目录内容
    Nginx 配置Nextjs和SpringBoot项目的https并解决跨域问题
    27 | Ubuntu18.04.5 安装python3.7及卸载
    TypeScript 学习笔记(四):装饰器与高级编程技巧
    HTTP协议【网络基础/应用层】
    Docker 启动容器
    8、SpringBoot整合hikari连接池
    第十三届蓝桥杯大赛湖南中医药大学第1场选拔赛总结
    【代码随想录算法训练Day65】卡码网47.参加科学大会、卡码网94. 城市间货物运输 I
    Using VSCode git extensition to access Gitee on CentOS 7
  • 原文地址:https://blog.csdn.net/m0_56799642/article/details/125602536