前言

为入门srm系统开发,我3天内借助ai,开发了某企业级srm系统的供应商银行信息模块的简单crud功能。额外功能包括

  1. 页面分页查询
  2. 模糊搜索
  3. 点击表头触发顺逆排序
  4. 字段合法性校验

其中我参照了该系统中一个相似的模板代码库,前端采用了easyUI+freemaker做页面创建和布局处理,具体的交互逻辑已经实现在通用的common.js和common.ftl中

(刚开始做java系统开发时其实完全搞不懂Controller→Service→Mapper分别为什么要有存在的意义和到底为什么要这样设计,又不想花精力花时间去研究和思考,就只好照猫画虎再借助ai,只模仿规范和逻辑,不思考存在意义更不知道优化思路。现在再次拾起开发,对后端分层
“Controller对接前端Http请求,并传参到Service层 ,收到Service层结果后再返回到前端(只依赖Service接口,不依赖具体实现)<->
Service实现api具体逻辑,调用<->
Mapper对DATABASE做实际操作并向Service返回结果”)

同时对代码开发规范做了温习(好久没java开发过):

代码好坏判断标准

目录

代码好坏判断标准:① 命名是否清晰

② 结构是否分层(Controller→Service→Mapper)

③ 是否有异常处理

④ 是否可复用、不重复

⑤ 是否易读、简洁


① 命名是否清晰

好:getSupplierByIdupdateSupplierInfo

坏:getSupdate1test()

② 结构是否分层(Controller→Service→Mapper)

好代码一定是:

  • Controller 接收参数
  • Service 写业务逻辑
  • Mapper 操作数据库

混乱代码:Controller 直接写 SQL。

③ 是否有异常处理

好代码:

  • try-catch
  • 全局异常处理
  • 友好提示

坏代码:报错直接崩,前端看不到原因。

④ 是否可复用、不重复

好代码:工具类、公共方法抽离坏代码:复制粘贴到处都是

⑤ 是否易读、简洁

好代码:别人一眼看懂坏代码:嵌套很深、逻辑绕、变量乱

基础关键词复习

1. extends = 继承

意思:儿子继承父亲的全部能力

  • 父亲有的方法、功能,儿子直接能用
  • 不用自己再写一遍
  • 可以对父亲的功能重写、增强
2. implements = 实现

意思:承诺遵守接口的规矩,必须实现里面规定的方法

  • 接口只定义 “要做什么”
  • 实现类必须 “真的去做”
MyBatis-Plus常见父类:

ServiceImpl <M,T>是 MyBatis-Plus 官方写好的父类,它自带了所有常用方法

  • list () —— 查询所有
  • getById (id) —— 根据 ID 查询
  • save (entity) —— 新增
  • updateById (entity) —— 修改
  • removeById (id) —— 删除
  • 分页、批量操作……

点击该方法的实现可以看到反编译文件里的官方声明为:

public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T>

M 必须是继承自 BaseMapper<T> 的 Mapper

spring常见注解:
@Autowired:字段注入依赖,简单,可触发spring三级缓存的循环依赖防御。告诉 Spring:这个变量 / 构造器 / 方法,你帮我自动赋值!

找 Spring 要一个已经造好的对象Spring 管理生命周期、事务、依赖、数据库连接。
@RequiredArgsConstructor:构造器注入依赖;最安全,不可变,测试方便,但不可解决循环依赖
上述两个都能实现依赖注入

    如何解决循环依赖:

    1. *拆除公共类:把互相调用的方法抽出来,放到一个公共类里
      // 公共工具/逻辑类
      @Component
      public class CommonLogic {
          // 抽出来的公共方法
      }
      
      @Service
      public class SupplierService {
          @Autowired
          private CommonLogic common;
      }
      
      @Service
      public class SupplierBankService {
          @Autowired
          private CommonLogic common;
      }

      解决原理:最优选择,但需要对代码逻辑有全局思想来提取公共方法
      使用情况:开发者有分层思想(或者逻辑清晰)的所有情况

    2. @Lazy 懒加载
      @Service
      public class AService {
          @Autowired
          @Lazy  // 关键
          private BService bService;
      }
      
      @Service
      public class BService {
          @Autowired
          private AService aService;
      }

      解决原理:仅解决创建死锁,不在编译时创建对象而是用‘代理对象’代替,只在调用时创建注入真实对象
      适用情况:害怕依赖循环但是没时间改,只好先‘逻辑注释’掉且保留对象在此不会引起更大缺漏

    3. 采用适配spring三级缓存创建的构造方式创建对象,如字段注入,setter注入(构造器注入不适配,创建时需要完整对象)

      @Service
      public class AService {
          @Autowired
          private BService bService;
      }

      解决原理:spring单例Bean的三级缓存创建防止循环依赖机制,但是官方不推荐,因为必须当构造方法触发三级缓存创建才能生效且因为同样只能防止创建时死锁。
      适用场景:只是spring创建对象防御性编程的自带优点,如果不了解原理(是否三级构造)且不想提取公共类的话可以祈祷能生效哈哈。


    spring三级缓存在构造对象时的机制:

    spring Bean即为spring管理的已创建的对象


    final关键字:让字段不可再赋值,和指向其他对象;。

    Logo

    AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

    更多推荐