• SpringBoot+JPA实现DDD(六)


    润色一下

    记录sql语句及sql的执行时间

    <properties>
        <p6spy.version>3.9.0</p6spy.version>
    </properties>
    <dependency>
        <groupId>p6spy</groupId>
        <artifactId>p6spy</artifactId>
        <version>${p6spy.version}</version>
    </dependency>
    

    src/main/resources下新建spy.properties配置文件:

    driverlist=com.mysql.cj.jdbc.Driver
    logfile=spy.log
    dateformat=yyyy-MM-dd HH:mm:ss.SS
    logMessageFormat=com.p6spy.engine.spy.appender.CustomLineFormat
    customLogMessageFormat=- %(currentTime) | took %(executionTime)ms | connection %(connectionId) 
    EXPLAIN %(sql);
    
    filter=true
    exclude=select 1 from dual
    

    application.properties修改成:

    #spring.datasource.url=jdbc:mysql://localhost:3306/product_center? useSSL=false&serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF-8
    spring.datasource.url=jdbc:p6spy:mysql://localhost:3306/product_center? useSSL=false&serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF-8
    spring.datasource.username=<your username>
    spring.datasource.password=<your password>
    #spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    spring.datasource.driver-class-name=com.p6spy.engine.spy.P6SpyDriver
    

    增加全局异常处理

    @ControllerAdvice
    @ResponseBody
    public class GlobalDefaultExceptionHandler {
        private static final String UNKNOWN_ERROR_CODE = "unknown-error";
        private static final String SYSTEM_ERROR_INFO = "系统异常,请联系管理员";
        private static final String ILLEGAL_PARAM_CODE = "illegal-param";
    
        @ExceptionHandler(value = IllegalArgumentException.class)
        public ApiResult illegalParamExceptionHandler(IllegalArgumentException e) throws Exception {
            // log todo
            return ApiResult.error(ILLEGAL_PARAM_CODE, e.getMessage());
        }
    
        @ExceptionHandler(value = BusinessException.class)
        public ApiResult businessExceptionHandler(BusinessException e) throws Exception {
            // log todo
            return ApiResult.error(e.getCode(), e.getMessage());
        }
    
        @ExceptionHandler(value = Exception.class)
        public ApiResult defaultErrorHandler(Exception e) throws Exception {
            // log todo
            e.printStackTrace();
            return ApiResult.error(UNKNOWN_ERROR_CODE, SYSTEM_ERROR_INFO);
        }
    }
    

    数据库添加自定义的审计字段

    domain.common.model:

    @MappedSuperclass
    @Data
    public abstract class AuditEntity implements Serializable {
        @Column(name = "is_delete", columnDefinition = "TINYINT(1) DEFAULT 0")
        protected Boolean isDelete;
        @Column(name = "created_by", length = 11, nullable = false)
        protected Integer createdBy;
        @Temporal(TemporalType.TIMESTAMP)
        @Column(name = "created_at", columnDefinition = "DATETIME NULL DEFAULT CURRENT_TIMESTAMP")
        protected Date createdAt;
        @Column(name = "updated_by", length = 11, nullable = false)
        protected Integer updatedBy;
        @Temporal(TemporalType.TIMESTAMP)
        @Column(name = "updated_at", columnDefinition = "DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
        protected Date updatedAt;
    
        @PrePersist
        protected void onCreate() {
            updatedAt = createdAt = new Date();
            isDelete = false;
        }
    
        @PreUpdate
        protected void onUpdate() {
            updatedAt = new Date();
        }
    }
    
    public class Product extends AuditEntity implements Serializable {
          ...
    }
    

    确定需求->构建模型->实现模型->调整模型->实现模型...,走完这个过程,相信你对DDD的玩法已经有了一定的了解,而且我相信你大概能领略到DDD代码的优美之处。好的代码应该是高内聚低耦合的,DDD的代码就是要让高内聚低耦合落地。

    高内聚体现在业务代码都集中在领域对象里了(聚合根,实体,值对象,域服务)。业务规则在代码里都有非常清楚的对应关系。代码真正体现了面向对象的思想。
    低耦合体现在聚合根不直接引用其它聚合根。 低耦合还有一个很关键的点是领域事件。 这个跟DDD事件驱动的架构风格分不开。

    说起DDD的架构风格,最常用的就是CQRS(读写分离)和事件驱动。
    事件驱动又分 event storming和event sourcing(个人理解,不对请指正),event sourcing看起来比较极端,似乎应用场景针对性太强,也就是说比较少见。

    如果你的业务很复杂,事件比较多,可以使用event storming。商品中心相对比较简单,用读写分离就差不多了。本人水平有限,本系列文章旨在抛砖引玉,希望大家能留言讨论。

    demo下载地址: productcenter6.zip

  • 相关阅读:
    mysql 中将汉字(中文)按照拼音首字母排序
    数据库连接客户端 dbeaver 程序包以及使用说明
    maven 项目在 tomcat 中启动报错:Caused by: java.util.zip.ZipException: invalid LOC header (bad signature)
    iPadOS 更新日志
    iOS 更新日志
    mybatis 中 if else 用法
    Chrome 地址栏如何设置显示 http/https 和 www
    Windows 常用工具 & 开发工具 & Chrome插件 & Firefox 插件 & 办公软件
    elasticsearch安装ik分词器
    js关闭浏览器
  • 原文地址:https://www.cnblogs.com/ahau10/p/13524644.html
Copyright © 2020-2023  润新知