lemon框架开发笔记

lemon框架开发笔记

JudgeUtils.isBlank() 字符串为 null 或者 "" ----返回true
JudgeUtils.isNotBlankAll() 字符串全部不为 null 或者 "" ----返回true
JudgeUtils.isBlankAll() 字符串全部为 null 或者 "" ----返回true

// isBlank 是在isEmpty的基础上进行了为空(字符串都为空格、制表符、tab 的情况)的判断。因此isBlank层次更高。
  1. Controller 自定义RequestMapping访问路径

  2. 注意service 上的分布式事务处理 查询操作开启事务打开事务消耗性能

  3. lemon 框架处理 id — MonitorIdGenUtils类定义方法,bootstrap.yml 中配置 id

  4. 注意static使用场景

  5. 注意判断 循环 等规范 如下代码:

    // 如果 e.getCertificateExpiryTime() 为空 那么会报错 就算你可以前面做了判断保证数据不为空 
    // 我们也这样书写代码就规范一点                                                         
    if (e.getCertificateExpiryTime().isAfter(LocalDate.now())) {
       BusinessException.throwBusinessException("到期时间应大于当前时间);
    }
                                                             
    // 规范书写 LocalDate.now() 获取当前时间 就绝对不会为空 
    if (LocalDate.now().isAfter(e.getCertificateExpiryTime())) {
       BusinessException.throwBusinessException("到期时间应大于当前时间);
    }
    
  6. 实体类规范

    1、lemon 框架对 @dataobject 有单独定义,DO是最好不允许出现@DATA的,都用@dataobject,然后自己set/get/tostring。
    2、能用自动生成的DO都不允许修改,需要增加字段,新增DO类继承。
    3BO DTO@data 
    4BO 中基本不允许出现 逻辑代码(据业务情况而定)
    5DO 中是不允许出现 json 注解的
    - Controller	DTO Controller 的数据交互
    - Service		BO Service数据交换
    - Dao		    DO 数据库查出来的都是DO
    
  7. 注意 lambda 表达式 处理完得到的数据要不要判空

  8. git 提交代码的时候 需要注意提交时的注释要与devops需求一致 否则无法push

  9. mysql 可以使用 <> 表示不等于

  10. 大屏的生产数据特别庞大 多表联查会在页面展示的时候造成响应超时。目前最大有700万条数据。

  11. id 判断空的时候 返回null 要考虑其他地方会不会被影响 不判断看代码,你前端必传的话,可以不判断

  12. 特殊情况下拿不到生产的数据、可以打印日志、去日志查询这个数据是什么

  13. 下拉框选择时、数据库存储英文、前端可以通过查询字典配置渲染数据。

  14. 正常、异常、等等。数据库存英文,后台使用枚举、前台可以拿到key、value进行数据渲染

    // 多个List 拼接成一个List 
    public List<String> ListIntegration (List<String>... list) {
            return Arrays.stream(list).flatMap(List::stream).collect(Collectors.toList());
    }
    // 只要List中包含一个equals()方法需要比较的值、即返回true 注意:List中不可以存在null 否则会报错
    List.stream().anyMatch(list -> list.getInspectionResult().equals(xxx));
    
  15. 异步 – 多个线程之前进行一个通信 – 巡检方面

    java中的异步是指一种编程模型,它允许程序在某个操作执行期间继续执行其他操作,而不是等待该操作完成再继续执行。Java中实现异步的方式有很多,比如使用回调、FutureCompletableFuture等。
    具体来说,Java中的异步操作通常通过多线程实现。在执行异步操作时,程序会创建一个新的线程来执行该操作,而主线程则可以继续执行其他任务,从而提高程序的执行效率和吞吐量。与同步操作相比,异步操作可以避免程序的阻塞等待,从而提高程序的响应速度和用户体验。
    
    Java中的线程是指程序并发执行的多个执行线程。Java中创建线程有两种方式:继承Thread类和实现Runnable接口。继承Thread类需要重写run方法,而实现Runnable接口需要实现run方法。使用Runnable接口的方式更加常用,因为它可以避免单继承带来的限制。
    
    Java中保证线程安全可以采取多种方式,比如使用synchronized关键字、使用Lock接口、使用volatile关键字等。其中,synchronized关键字是最常用的方式,它可以确保同一时间只有一个线程访问共享资源,从而避免了多线程竞争导致的数据不一致等问题。而volatile关键字则可以确保多个线程之间对于同一变量的修改和读取操作是可见的,从而避免了多线程竞争导致的线程安全问题。
    
  16. 使用lemon 框架啊 mq 走异步(当两个进程进行通信的时候)、操作枚举赋值会抛出异常、需要使用枚举反序列器

    public class 类名 extends JsonDeserializer<枚举类> {
        @Override
        public 枚举类 deserialize(
                final JsonParser jp,
                final DeserializationContext ctxt) throws IOException {
            final JsonNode jsonNode = jp.readValueAsTree();
            return 枚举类.fromValue(jsonNode);
        }
    }
    
    1. Mysql 判断一个字段是否等于 null或者空的时候,需要跟据字段类型来做过滤;假设要count(1) 不为空的金额总数。金额字段是decimal类型。那么就不可以用 ! = ‘ ’、<> ‘ ’ 来过滤 ;可以用 is not null ; 用 !=、<> 的话、就不会count(1) 金额为 0的数据、主要需要根据字段类型来使用合适的方法过滤数据

      mysql函数 
      date_format(字段名称,'%Y-%m-%d') datetimedate
      
常见错误

超出建表最大长度
com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: Data too long for column 

转换出错
cannot be cast to 
  1. mybatis 编写sql的时候、需要注意传参是否取别名、字段是否正常、表字段是否正常、映射是否可以取出数据。动态sql拼接时注意and、or 有没有添加

  2. 设计表字段时,如果有些字段跟尽量根据以前的表来设计。比如现在新表设计用户名字段。这个用户名字段在以前用户表是存在的,那需要注意长度、命名、表是在生产还是测试环境

  3. 开发代码时新的代码都要往下编写

    @Deprecated 可以用来注解类、接口、成员方法和成员变量等,用于表示某个元素(类、方法等)已过时。当其他程序使用已过时的元素时,编译器将会给出警告。
    
  4. 涉及优化的时候 改动字段 不要动以前的逻辑

  5. 定时任务cron表达式

  6. 大屏 定时任务处理数据、数据校验、手动调用接口

  7. 写sql的时候用分组查询出数据、方便

  8. toDateTime(x) yyyy-MM-dd HH:mm:ss时间函数
    clickhouse 
    toDateTime()`时间函数返回的时间格式为`yyyy-MM-dd HH:mm:ss
    toDateTime(x)`参数x可以是字符串类型也可以是数字类型
    
  9. parseDateTimeBestEffort
    cliskhouse 
    说明:把String类型的时间日期转换为DateTime数据类型
    
  10. 当需要返回一个空的集合、减少内存开销

    使用 Collections.emptyList();
    
    

28.写代码的时候不要太局限于list,map的数据处理。想一想,遇到复杂数据加工的时候,可不可以把map和list相互套着用。

29.RedisTemplate的两种序列化实践方案

方案一:(内存开销较大,会存储多余的字节码)
1.自定义RedisTemplate
2.修改RedisTemplate的序列化器为GenericJackson2JsonRedisSerializer(bean注入)
方案二:(节省内存空间、步骤麻烦需要手动处理数据)
1.使用StringRedisTemplate
2.写入Redis时,手动把对象序列化为JSON
3.读取Redis时,手动把读取到的JSON反序列化为对象

30.编写代码时、要注意返回值、返回类型是否包装类;避免自动拆箱的风险。

// 避免    
@Override
    public boolean getLock() {
        Boolean aBoolean = stringRedisTemplate.opsForValue()
                .setIfAbsent("key", "value", 120, TimeUnit.SECONDS);
        // 如果直接返回aBoolean有自动拆箱的风险 
        // 通过下面这种方法返回
        return Boolean.TRUE.equals(aBoolean);
    }

31.有关于字符串的操作,频繁的对String对象进行修改,会造成很大的内存开销。此时应该用StringBuffer或StringBuilder来代替String。

而new String()更加不适合,因为每一次创建对象都会调用构造器在堆中产生新的对象,性能低下且内存更加浪费

性能、安全方面存在区别。一般来说,如果在单线程环境下进行字符串操作,建议使用StringBuilder,它的性能更高。而在多线程环境下进行字符串操作时,为了保证线程安全性,应该使用StringBuffer

32.关于resultType与parameterType 的基本使用的区别 :

1、使用resultType :主要针对于从数据库中提取相应的数据出来(出参)

2、使用parameterType :主要针对于将信息存入到数据库中 如:insert 增加数据到数据库(入参)

33.clickhouse使用函数时,索引失效的问题

1、使用Date()去转换一个代表时候的字符串,会造成索引的失效
2、我们可以使用toStartOfMinute() 精确到分钟的一个函数
3、我们还可以在需要使用函数的列上,加上一个函数索引,这样也可以保障索引不会失效

你可能感兴趣的:(java)